Overlapping chunk
复制本地路径 | 在线编辑
很建议先花上几分钟看一下 house of einherjar,有如下的相似点:
- 都是通过溢出修改
size或者prev_size来进行攻击 - 溢出之后都是利用
free进行合并
攻击要求:可以修改某个块的 size(这个块的大小要大于 fastbin)
最终效果:实现 Chunk Overlapping
PS: chunk overlapping 是一个现象,即 A 指向的内存和 B 指向的内存有重叠。而 overlapping chunk 是一种攻击手段,即本文介绍。(所以又是一个很失败的命名,二进制安全的起名确实不咋地)
原理说明
下面结合 ChatGPT 对细节说明,这个攻击是在 glibc 2.29 做的,那个时候还没 tcache。
1️⃣ 初始分配布局
p1 = malloc(1000);
p2 = malloc(1000);
p3 = malloc(1000);
p4 = malloc(1000);
p5 = malloc(1000);
内存布局(物理相邻)
[p1][p2][p3][p4][p5][top]
2️⃣ free(p4)
free(p4);
内存布局
[p1][p2][p3][ FREE p4 ][p5][top]
3️⃣ 核心漏洞:伪造 p2.size(从 p1 越界)
修改 p2 的 size 字段,此时 malloc 认为 p2 之后紧接着 p4:
p2.size = size(p2) + size(p3) + CHUNK_HDR
伪造后的逻辑布局(allocator 视角)
[p1][ p2 + p3 ][ FREE p4 ][p5]
⚠️ p3 被“吃进了” p2
4️⃣ free(victim) —— 攻击成立点
这里的 victim 是被我们修改 size 的块,即 p2:
free(p2);
glibc 2.23 内部逻辑(关键)
nextchunk = p2 + chunksize(p2); // ← 被伪造
nextchunk == p4- p4 已 free
- 触发 forward consolidation
结果:一个巨大的 free chunk
FREE chunk = p2 + p3 + p4
真实布局却是:
[p1][ FREE (p2+p3+p4) ][p5]
↑
p3 仍在使用,但 allocator 不知道
说明
所以这里有一个要求:p2 不能是 fastbin 大小,否则 free(p2) 不会进行合并,而是直接放到 fastbin 中去了。
多说一句:如果不是 fastbin,这个块肯定是先放到 unsorted bin 中作为中转的,所以如果你把它当成 unsorted bin 的攻击,勉强也算。但我觉得还是归为 consolidate 的攻击更合理。
5️⃣ 最终结果:造成 overlapping
其实上面这个布局已经很清晰了,即 p3 指向的部分,在 malloc 眼中已经是释放的。下面直接再 malloc 一个块,结果就更清晰明了。
p6 = malloc(2000);
布局:
p6
⬇
[p1][ p6 ][剩下内容][p5]
↑
p3 仍在使用,但 allocator 不知道
最终重叠关系
p6 covers:
[ p2 ][ p3 ][ part of p4 ]
p3 still "in use" by program
很典型的 chunk overlapping
攻击已经失效
glibc 已经做了一些检查,这种攻击已经失效了。