对 how2heap 中的部分程序进行分析。
实验环境
操作系统:WSL2 Ubuntu 22.04
glibc版本:2.31
实验程序:fastbin_dup fastbin_dup_into_stack unsorted_bin_attack tcache_dup tcache_poisoning
实验目标:基础结构理解 + 简单利用
fastbin_dup
源码解析
1 |
|
首先申请8个容纳8字节的chunk(大小为0x20),然后释放了7个,刚好填满0x20这条tcache bin。
然后申请3个0x20的chunk,在 glibc2.31 版本的
__libc_calloc()中,不会尝试从 tcache 中分配 chunk。所以还是从top chunk中分配。然后进行三次free,分别是a,b,a。之所以将两次free(a)间隔开来,是因为_int_free() 会检查前后两个chunk是否相同。此时fastbin结构是
fastbinsY[0x20] -> a -> b -> afastbin采用FIFO策略。第一次calloc分配到是a,第二次分配到是b,第三次分配到是a。所以在程序中a和c存储的地址是相同的,修改a地址的内容,也会影响c,从而实现利用。
调试过程与原理解析
序号对应上面的分析步骤。
查看 tcache bin
可以看到tcache被填了7个。

注意链表是通过fd区域链接在一起。
查看堆结构。

可以看到top chunk地址为
0x555555559390,可以与下面的地址进行比较。同时可以看到每个chunk大小为0x20大小。查看top chunk地址
可以看到又分配了三个

注意在tcache中,prev_inuse标记位不会被清除和fastbin一样。注意Top chunk地址从 0x555555559390增长到了 0x5555555593f0,刚好增长了0x60.
fastbin结构变化
第一次free(a)之前。

第一次free(a)之后。由于tcachebin[0x20]的已经满了,只能放在fastbin中。

free(b) 之后。继续存入fastbin的栈顶。同时可以发现fastbin中的fd指向的是下一个chunk的prev_size的位置。

第二次free(a)。

可以看到
fastbin[0x20]->a->b->a重新分配,得到两个相同地址。

执行过程
tcache_house_of_spirit
源码解析
解析在注释中
1 |
|
调试过程与原理解析
填满tcache

在栈上做一个fake chunk
设置第一个chunk的size字段为0x40,下图红框是fake_chunks的存储的位置(设置了0x10对齐)。

设置第二个chunk的size字段。

伪造chunk。
回收到fastbin中。注意要使用
fake_chunks[2]的地址,因为free接收用户数据的地址。
然后再使用calloc分配。可以在该地址中写入我们的数据,这个地址可以根据攻击位置设置。

执行过程

可以看到malloc得到地址被设置成我们想要的。
overlapping_chunks
源码分析
1 | /* |
调试过程
查看三个chunk在堆中的分布
第一个0x80 ,赋值为0x31;第二个0x500,赋值为0x32;第三个为0x80,赋值为0x33。

伪造chunk。
覆盖size区域。

free之前的top chunk。

先free,这里不会放到bin中,因为它和top chunk相邻,会被top chunk合并。

通过malloc获得与其他块重叠的块。top chunk变回来,和free之前一样。

重叠的块
这里刚好是全覆盖(我将代码中80改为了0x80)。

执行过程

p3和p4结尾地址相同。

可以通过修改p4来修改p3。