wdb_2018_1st_babyheap
前言
Glibc2.24 UAF Unlink
参考:这篇文章
Unlink可以看我写的这个文章: http://downbeat.top/2024/09/25/zctf2016-note2-unlink/
checksec+ida
1 | pwn@ctfpwn:~/Desktop/buuctf/wdb_2018_1st_babyheap$ checksec pwn |
NO PIE第一想法就是
Unlink下面查看ida的结果(查看关键模块)
add
- 限制了每次malloc的size为0x20
1 | unsigned __int64 sub_4009A0() |
edit
- 只有三次修改的机会,并且只能修改0x20
1 | unsigned __int64 sub_400A79() |
show
- 可用来leak libc
1 | unsigned __int64 sub_400C01() |
free
- 很明显的UAF
1 | unsigned __int64 sub_400B54() |
思路分析
- 由于限制了每次只能malloc(0x20)而且只能修改0x20的字节数,可以有
off_by_null,但是这里给了UAF,并且在glibc2.24中double free的利用姿势十分简单,我们可以利用fastbin链表泄露chunk的地址,利用double free去构造一个fake_chunk,这个fake_chunk的user_data包含某个chunk的prev_size和size那么就可以实现leak libc和unlink了 - 同时这里限制了chunk的数量,相对于Aribitraty alloc很明显是不够的
- 这题目坑其实挺多的,在下面调试的时候慢慢说吧
题解&gdb
leak heap_addr
1 | payload = p64(0)+p64(0x31)+p64(0)+p32(0x31) |
- 注意这个payload
1 | payload = p64(0)+p64(0x31)+p64(0)+p32(0x31) |
最后不能是p64,因为是sendline发送的,自带\n,影响下一次的choice

- 但其实后面无所谓是什么,即使不修改0x20的地方都没事
构造fake_chunk
1 | add(5,p64(heapptr+0x10)) # 1 |
- 修改chunk1的fd指向chun0下方构造的fake_chunk

- 下次malloc那么便会将这处
fake_chunk给malloc走,那我们修改0x20正好可以修改chunk1的prev_size和size,同时我们也可以顺手布置unlink所需的条件,如下的payload
1 | ptr = 0x602060 |
- 对于target,由于0,1号chunk通过uaf连接的比较杂,所以我们可以选chunk3为目的chunk,unlink是修改某个heap为
target-0x18,此时target-0x18是chunk3的地址,故…..
leak libc+unlink
1 | edit(0,p64(0)+b"\x21") |
- 为了Unlink我们还要修改fake_chunk的size=0x21(下图是修改之前的)

- 为什么不在一开始就修改为0x20?
因为在fastbin中会对处于同一个bin的size进行检查,之前是将fake_chunk链在size=0x31的fastbin上,所以要将size设置为0x31,此时要unlink,所以设置为0x21
ezUnlink运用
1 | edit(6,p64(libc.sym['__free_hook'])) |
- 实现unlink之后的布局

完整EXP
1 | from pwn import * |
- 标题: wdb_2018_1st_babyheap
- 作者: D0wnBe@t
- 创建于 : 2024-11-08 16:25:09
- 更新于 : 2024-11-08 17:52:14
- 链接: http://downbeat.top/2024/11/08/wdb-2018-1st-babyheap/
- 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
评论