0ctf_2017_babyheap--fastbin_attack
0ctf_2017_babyheap
知识点:
- glibc2.24 fastbin_attack, unsortedbin泄露main_arena ,Arbitrary Alloc
- Fastbin Attack - CTF Wiki (ctf-wiki.org)
题目速览:





思路分析:
- 漏洞点在edit函数,未对size检查,可以实现任意地址写
- 题目开启了PIE,unlink直接out,由got表不可改,所以想到改__malloc_hook为onegadget
- 先通过unsortedbin泄露main_arena,即可以得到malloc_hook(相差0x10), arbitrary_alloc错位构造fake_chunk,就可以修改malloc_hook为one_gadget
- 但是运用arbitrary_alloc需要uaf修改fastbin中chunk的fd指针,因此需要我们两个地址控制同一个chunk,看下面调试吧。
gdb调试:
1.
1 | # glibc2.24,泄漏libc,修改__malloc_hook为onegadget |
- 构造五个chunk,chunk0用来溢出chunk1,chunk1,2用于uaf,chunk4用来泄露libc,chunk3溢出修改chunk4
- 查看堆布局,看看如何使得两个地址共同控制一个chunk:

- 由于内存的分页管理机制以及PIE,我们第一次分配堆地址的最后三位十六进制数肯定为000
- 此时我们溢出chunk0修改chunk1的fd指针,也就相当于修改chunk2的地址,此时我们需要利用chunk4,如果将1->fd所指向的chunk2的地址最后一字节修改为0x80,也就是1->fd = chunk4。
- 同时由于add中会循环检查哪个指针=0就将malloc的地址给到该指针,而chunk2的指针在free的时候被清零了,第二次malloc将chunk4给到了chunk2,因此chunk2会和chunk4联系起来,即修改chunk2也会修改chunk4,也就做到了uaf的利用
1 | payload = cyclic(0x10) + p64(0) + p64(0x21) + p8(0x80) |
2.
- 虽然已经将1->fd -> 4 ,4和2联系起来了,但是此时的chunk4放在fastbin中肯定是不合适的,因为size不同,在分配chunk的时候size不同是会报错的,所以我们要修改chunk4的size,和chunk1保持一致(在同一个bin中)
- 然后将1,2都回收回来,注意虽然1->fd修改为了chunk4,但是add的函数中for循环从小到大,只要满足”标志位”是0就分配,而chunk2的标志位free之后始终为0。
- 然后将chunk4的size修改回来,free(4),4的fd和bk指针将指向main_arena+0x58,show(2)就将输出这个特殊地址,因为chunk2和chunk4都是指向chunk4的。
1 | payload = cyclic(0x10) + p64(0) + p64(0x21) |

3.
- Arbitrary Alloc 构造fake_chunk
技巧可以看开头的文章,这里直接演示。
- 为了修改malloc_hook为one_gadget,我们要往malloc_hook上面构造fake_chunk,然后直接修改堆中内容即可,来看看malloc_hook上面又没有地方构造吧:

- 我们发现这个地方可以错位出一个size出来,对应于fastbin[5](不是很懂可以看开头文章),这个错位出来的chunk的size是0x60(fastbin[5]对应的size就是0x60),为了使fastbin中已经存在的chunk->fd链接上fake_chunk,其size也应该是0x60
- 该chunk的地址可以从图上看出:malloc_hook-0x13-0x8(size)-0x8(prev_size)
1 | libc = ELF("/mnt/hgfs/ctfpwn/exp/libc/libc6_2.23-0ubuntu11.2_amd64.so") |
- 下图可以发现修改chunk2其实也修改了chunk4

4.
- 然后就很简单了,修改malloc_hook->one_gadget,再次malloc即可。
1 | payload = cyclic(0x13) + p64(onegadget) # 从上图看偏移即可 |
- 补充:要是用的buuctf给的libc-2.23.so的话,即使试便所有的onegadget也是不可以打通的,因为栈上的数据不满足,但是我们可以改__realloc_hook为onegadget,然后修改malloc_hook为realloc+n(n要自己试)
- 因为这个realloc附近存在大量的gadget可以调整栈结构,下面是脚本(与上面不同,这是后面重新写的):
1 | from pwn import * |
注意:
之前有几次出现了“timeout: the monitored command dumped core”
可以看看这篇文章
其实还有一种情况(我也不知道算不算),我修改了libc.so文件就过了
- 标题: 0ctf_2017_babyheap--fastbin_attack
- 作者: D0wnBe@t
- 创建于 : 2024-09-03 13:42:37
- 更新于 : 2024-11-07 22:42:21
- 链接: http://downbeat.top/2024/09/03/0ctf-2017-babyheap-fastbin-attack/
- 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
评论