通过 how2heap 复习堆利用 (二)
字数 2322 2025-08-20 18:18:16
How2Heap 堆利用技术详解(二)
本文是 how2heap 堆利用技术系列的第二部分,详细讲解了几种经典的堆利用技术,包括 poison_null_byte、house_of_lore、overlapping_chunks 和 house_of_force 等。
0x07 poison_null_byte
技术概述
poison_null_byte 是一种利用单字节溢出(off-by-one)的技术,通过修改 chunk 的 size 字段来造成堆块重叠。
利用步骤
-
初始布局:
- 分配四个 chunk:a (0x100)、b (0x200)、c (0x100) 和 barrier (0x100)
- barrier 用于防止 free(c) 时被合并到 top chunk
-
关键操作:
- 通过 chunk a 的单字节溢出修改 chunk b 的 size
- 伪造 chunk c 的 prev_size 以绕过 unlink 检查
- 计算公式:
c.prev_size = b_size & 0xff00
-
释放与重新分配:
- 释放 chunk b,此时 chunk 布局发生变化
- 分配 b1,系统会从 free 掉的 chunk b 中取出合适大小
- 分配 b2,此时 b1 和 c 之间有一个 chunk b
-
利用过程:
- 先后 free b1 和 c,导致 chunk 合并
- 分配 chunk d,与 b2 重叠,获得对 b2 内容的任意读写能力
关键点
- 必须伪造 prev_size 以绕过 unlink 检查
- 通过单字节溢出修改 size 字段
- 利用堆块合并机制造成重叠
0x08 house_of_lore
技术概述
house_of_lore 通过伪造 small bin 链来分配任意指定位置的 chunk,从而修改任意地址的内存。
利用条件
- 控制 Small Bin Chunk 的 bk 指针
- 控制指定位置 chunk 的 fd 指针
利用步骤
-
创建 small bin chunk:
- 分配并释放一个 chunk,使其进入 small bin
-
伪造 chunk:
- 在栈上伪造两个 chunk
- chunk1 的 fd 指向 victim chunk,bk 指向 chunk2
- chunk2 的 fd 指向 chunk1
-
修改指针:
- 修改 victim chunk 的 bk 指针指向伪造的 chunk1
-
分配利用:
- 分配与 victim chunk 大小相同的 chunk
- 再次分配时,系统会返回栈上的伪造 chunk
关键点
- 必须绕过 small bin 的双向链表检查:
bck->fd == victim - 伪造的 chunk 需要形成完整的链表结构
- 可以用于绕过栈保护(如 canary)
0x09 overlapping_chunks
技术概述
通过修改 size 值造成堆块重叠,使两个指针可以操作同一块内存。
利用步骤
-
初始分配:
- 分配三个 chunk:p1 (0x100-8)、p2 (0x100-8)、p3 (0x80-8)
-
释放操作:
- 释放 p2,使其进入 unsorted bin
-
修改 size:
- 通过 p1 的溢出修改 p2 的 size,使其包含 p3
- 例如:
evil_chunk_size = 0x181
-
分配利用:
- 分配一个大 chunk (0x180-8),会包含原来的 p2 和 p3
- 现在可以通过 p4 和 p3 操作同一块内存
关键点
- 通过修改 size 值吞并邻块
- 造成两个指针指向同一内存区域
- 可用于类型混淆等攻击
0x10 overlapping_chunks_2
技术概述
与 overlapping_chunks 类似,但在 free 之前修改 size 值,导致错误的合并。
利用步骤
-
初始分配:
- 分配五个 chunk,第五个防止合并到 top chunk
-
释放操作:
- 释放 p4,观察 p5 的 prev_size 变化
-
修改 size:
- 通过 p1 的溢出修改 p2 的 size,使其包含 p3
- 例如:
real_size_p2 + real_size_p3 + prev_in_use + sizeof(size_t)*2
-
释放与分配:
- 释放 p2,错误地修改 p5 的 prev_size
- 分配 p6,会与 p3 重叠
关键点
- 在 free 前修改 size 值
- 导致系统错误计算合并区域
- 可用于构造 UAF 等漏洞
0x11 house_of_force
技术概述
通过改写 top chunk 的 size 字段来欺骗 malloc 返回任意地址。
利用步骤
-
初始分配:
- 分配一个 chunk,观察 top chunk 的位置和大小
-
修改 top chunk size:
- 通过溢出漏洞将 top chunk 的 size 改为极大值(如 -1)
-
计算分配大小:
- 计算目标地址与 top chunk 的偏移
evil_size = target_addr - top_chunk_addr - chunk_header_size
-
分配利用:
- 分配 evil_size 大小的 chunk
- 下次分配将返回目标地址
关键点
- 需要知道堆地址(受 ASLR 影响)
- 可以分配任意地址的内存
- 常用于修改全局变量或重要数据结构
总结
这些堆利用技术展示了如何通过精心构造的内存操作来利用堆管理器的行为,实现任意地址读写或代码执行。理解这些技术对于二进制安全研究和漏洞利用开发至关重要。