Skip to content

Overlapping chunk

复制本地路径 | 在线编辑

很建议先花上几分钟看一下 house of einherjar,有如下的相似点:

  1. 都是通过溢出修改 size 或者 prev_size 来进行攻击
  2. 溢出之后都是利用 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 已经做了一些检查,这种攻击已经失效了。

Comments