Fastbin Attack
本文最后更新于 2025年12月30日 凌晨
参考
这个操作是通过伪造fastbin的单向链表来实现的
可以实现特定内存构造chunk
fastbin的管理机制
- 当chunk->size < 0x90,free(chunk)时会被回收到fastbin中
[AMD64下] - 当fastbin中为空时,free(chunk),该chunk->fd = 0
- 当fastbin中不为空时,free(chunk),该chunk->fd指向上一个被回收入fastbin中的chunk
- 申请同样大小的chunk时,返回链表的头chunk,该chunk从fastbin中脱链,chunk->fd被content覆盖
看文字总是有点不够生动,看图吧



fastbin添加chunk
这里有两种
- 手动free(fake_chunk),实现fastbin添加fake_chunk,但是在free的时候有要求
- fake chunk 的 ISMMAP 位不能为 1,因为 free 时,如果是 mmap 的 chunk,会单独处理。
- fake chunk 地址需要对齐, MALLOC_ALIGN_MASK
- fake chunk 的 size 大小需要满足对应的 fastbin 的需求,同时也得对齐。
- fake chunk 的 next chunk 的大小不能小于 2 * SIZE_SZ,同时也不能大于av->system_mem 。
- fake chunk 对应的 fastbin 链表头部不能是该 fake chunk,即不能构成 double free 的情况。
- 通过修改fastbin中的chunk->fd,实现fastbin添加fake_chunk,同样有要求
- 能够写入fastbin中的chunk的内存,一般是堆溢出
- chunk->size <= fake_chunk->size < chunk->size + size_t*2
a的理解很简单:如果不能写入chunk的内存,那么fd就无法修改,也就无法实现fastbin添加
b的理解就有丢丢复杂:要求fake_chunk->size 必须存在值,且值不能超过chunk->size + size_t2或者小于chunk->size。什么意思呢,就是说((size_t*)fake_chunk+1)必须有值;后半句是说,由于你是修改fastbin中已有的chunk->fd,那么就认为你的fake_chunk->size和chunk->size一样,但是可以不完全一样,上图来看看比较好理解

House Of Spirit
例题
ctfshowpwn144
edit:存在堆溢出

我们的目的是修改magic的值,那么我们就需要布局fake_chunk(第二种添加方法)

EXP
1 | |
代码解释

在布局fake_chunk时
stdin@@GLIBC_2_2_5,在elf文件映射内存的时一般都在高位地址上,也就是0x000070~0x00007F,那么就可以构造一个chunk->size = 0x71,实现添加fake_chunk
这里还有个问题,就是说,如果我们把fake_chunk == 0x0602090,那么fake_chunk->size ==0,就无法申请到fake_chunk的地址,那么我们就需要把[0x70~0x7f]从fake_chunk->prev_size挪到fake_chunk->size上。其在高三位上,那么stdin@@GLIBC_2_2_5-3,把它顶出去就ok



Fastbin Double Free
又称 fastbin dup
简单来说
通过对同一个堆块进行两次
free(&(chunk->fd))(不要求连续[也连续不了]),使得chunk->fd = &(last_free_thunck),这时候如果能够修改thunck->fd的内容,就可以实现任意内存申请也就是说:
当我有chunk0、chunk1
free(chunk0) –> fastbins: chunk0 <- 0
free(chunk0) –> process crash
那么我们换一个思路
free(chunk0) –> fastbins: chunk0 <- 0
free(chunk1) –> fastbins: chunk1 –> chunk0 <- 0
free(chunk0) –> fastbins: chunk0 –>chunk1 <– chunk0
第三次free会使得:chunk0->fd = chunk1
Q-A
Q:为什么无法连续free
A:跟tcache不一样,不管哪个版本glibc都有对fastbin free 的check