通过 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 字段来造成堆块重叠。

利用步骤

  1. 初始布局

    • 分配四个 chunk:a (0x100)、b (0x200)、c (0x100) 和 barrier (0x100)
    • barrier 用于防止 free(c) 时被合并到 top chunk
  2. 关键操作

    • 通过 chunk a 的单字节溢出修改 chunk b 的 size
    • 伪造 chunk c 的 prev_size 以绕过 unlink 检查
    • 计算公式:c.prev_size = b_size & 0xff00
  3. 释放与重新分配

    • 释放 chunk b,此时 chunk 布局发生变化
    • 分配 b1,系统会从 free 掉的 chunk b 中取出合适大小
    • 分配 b2,此时 b1 和 c 之间有一个 chunk b
  4. 利用过程

    • 先后 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 指针

利用步骤

  1. 创建 small bin chunk

    • 分配并释放一个 chunk,使其进入 small bin
  2. 伪造 chunk

    • 在栈上伪造两个 chunk
    • chunk1 的 fd 指向 victim chunk,bk 指向 chunk2
    • chunk2 的 fd 指向 chunk1
  3. 修改指针

    • 修改 victim chunk 的 bk 指针指向伪造的 chunk1
  4. 分配利用

    • 分配与 victim chunk 大小相同的 chunk
    • 再次分配时,系统会返回栈上的伪造 chunk

关键点

  • 必须绕过 small bin 的双向链表检查:bck->fd == victim
  • 伪造的 chunk 需要形成完整的链表结构
  • 可以用于绕过栈保护(如 canary)

0x09 overlapping_chunks

技术概述

通过修改 size 值造成堆块重叠,使两个指针可以操作同一块内存。

利用步骤

  1. 初始分配

    • 分配三个 chunk:p1 (0x100-8)、p2 (0x100-8)、p3 (0x80-8)
  2. 释放操作

    • 释放 p2,使其进入 unsorted bin
  3. 修改 size

    • 通过 p1 的溢出修改 p2 的 size,使其包含 p3
    • 例如:evil_chunk_size = 0x181
  4. 分配利用

    • 分配一个大 chunk (0x180-8),会包含原来的 p2 和 p3
    • 现在可以通过 p4 和 p3 操作同一块内存

关键点

  • 通过修改 size 值吞并邻块
  • 造成两个指针指向同一内存区域
  • 可用于类型混淆等攻击

0x10 overlapping_chunks_2

技术概述

与 overlapping_chunks 类似,但在 free 之前修改 size 值,导致错误的合并。

利用步骤

  1. 初始分配

    • 分配五个 chunk,第五个防止合并到 top chunk
  2. 释放操作

    • 释放 p4,观察 p5 的 prev_size 变化
  3. 修改 size

    • 通过 p1 的溢出修改 p2 的 size,使其包含 p3
    • 例如:real_size_p2 + real_size_p3 + prev_in_use + sizeof(size_t)*2
  4. 释放与分配

    • 释放 p2,错误地修改 p5 的 prev_size
    • 分配 p6,会与 p3 重叠

关键点

  • 在 free 前修改 size 值
  • 导致系统错误计算合并区域
  • 可用于构造 UAF 等漏洞

0x11 house_of_force

技术概述

通过改写 top chunk 的 size 字段来欺骗 malloc 返回任意地址。

利用步骤

  1. 初始分配

    • 分配一个 chunk,观察 top chunk 的位置和大小
  2. 修改 top chunk size

    • 通过溢出漏洞将 top chunk 的 size 改为极大值(如 -1)
  3. 计算分配大小

    • 计算目标地址与 top chunk 的偏移
    • evil_size = target_addr - top_chunk_addr - chunk_header_size
  4. 分配利用

    • 分配 evil_size 大小的 chunk
    • 下次分配将返回目标地址

关键点

  • 需要知道堆地址(受 ASLR 影响)
  • 可以分配任意地址的内存
  • 常用于修改全局变量或重要数据结构

总结

这些堆利用技术展示了如何通过精心构造的内存操作来利用堆管理器的行为,实现任意地址读写或代码执行。理解这些技术对于二进制安全研究和漏洞利用开发至关重要。

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 影响) 可以分配任意地址的内存 常用于修改全局变量或重要数据结构 总结 这些堆利用技术展示了如何通过精心构造的内存操作来利用堆管理器的行为,实现任意地址读写或代码执行。理解这些技术对于二进制安全研究和漏洞利用开发至关重要。