多手法联合IO利用之House of pig 学习利用
字数 1991 2025-08-23 18:31:08

House of Pig 利用技术详解

1. 简介

House of pig 是一种在 libc 2.31 环境下结合多种堆利用技术的攻击方法,主要适用于程序中仅有 calloc 函数而没有 malloc 函数的情况。它通过以下技术组合实现利用:

  1. large bin attack
  2. IO_FILE 结构体利用
  3. tcache stashing unlink attack

2. 前置知识

2.1 Large Bin Attack

2.1.1 攻击效果

  • libc 2.23:可以向任意两个地址分别写入一个堆地址
  • libc 2.31:只能向一个任意地址写入堆地址(由于新增安全检查)

2.1.2 利用原理

在 libc 2.31 中,当较大的 chunk 进入 large bin 时会有额外的检查:

if (__glibc_unlikely(fwd->bk_nextsize->fd_nextsize != fwd))
    malloc_printerr("malloc(): largebin double linked list corrupted (nextsize)");
if (bck->fd != fwd)
    malloc_printerr("malloc(): largebin double linked list corrupted (bk)");

因此只能通过向 large bin 中链入较小的 chunk,同时修改原有的 size 比较大的 chunk 的 bk_nextsize 指针来实现攻击。

2.1.3 利用步骤

  1. 准备两个大小不同的 large bin chunk
  2. 将 size 较小的 chunk 放入 large bin 中
  3. 将 size 较大的 chunk 放在 unsorted bin 中
  4. 修改 size 较小的 chunk 的 bk_nextsize 指针为目标地址-0x20
  5. 将 size 较大的 chunk 链入 large bin 中

2.2 Tcache Stashing Unlink Attack

2.2.1 漏洞来源

small bin 处理代码中的检查不充分:

bck = victim->bk;
if (__glibc_unlikely(bck->fd != victim))
    malloc_printerr("malloc(): smallbin double linked list corrupted");

2.2.2 利用条件

  1. 能控制 Small Bin Chunk 的 bk 指针
  2. 程序可以越过 Tcache 取 Chunk(使用 calloc 即可)
  3. 程序至少可以分配两种不同大小且大小为 unsorted bin 的 Chunk

2.2.3 利用步骤

  1. 在 tcache 中放入 5 个 chunk(预留两个空位)
  2. 在 small bin 中放入两个大小相同的 chunk
  3. 修改 small bin 中 chunk 的 bk 指针为 fake chunk 地址
  4. 使用 calloc 触发攻击,将 fake chunk 链入 tcache

2.3 calloc 函数特性

calloc 函数不会从 Tcache 拿 Chunk,因此可以绕过"不能越过 Tcache 从 SmallBin 中取出 Chunk"的限制。

3. House of Pig 利用流程

3.1 整体思路

  1. 利用 UAF 等漏洞泄露 libc 和 heap 基地址
  2. 进行 tcache bin 布置,在 tcache 中放入 5 个 chunk
  3. 在 small bin 中放入两个大小相同的 chunk
  4. 进行第一次 large bin attack,将堆地址写入 __free_hook-0x8
  5. 利用 tcache stashing unlink attack,构造 fake chunk 链入 tcache
  6. 进行第二次 large bin attack,将堆地址写入 _IO_list_all
  7. 劫持 IO_FILE 结构体,将 vtable 由 _IO_file_jumps 修改为 _IO_str_jumps

3.2 IO_FILE 结构体劫持

3.2.1 关键函数分析

将 vtable 改为 _IO_str_jumps 后,程序会调用 _IO_str_overflow 而非 _IO_file_overflow

_IO_str_overflow 函数会:

  1. 计算缓冲区长度 len = _IO_buf_end - _IO_buf_base
  2. 使用 malloc 申请 len*2 + 100 大小的空间
  3. 调用 memcpy 将 old_buf 内容复制到 new_buf
  4. 调用 free(old_buf)

3.2.2 构造思路

  1. 计算好 len 使 malloc 分配到 tcache 中伪造的 fake chunk
  2. 让 old_buf 指向写有 system 函数地址的空间
  3. 通过 memcpy 将 system 地址复制到 __free_hook
  4. 让 old_buf 开头写有 "/bin/sh"

3.3 伪造 IO_FILE 结构体模板

fake_IO_FILE = 2 * p64(0)
fake_IO_FILE += p64(1)                    # _IO_write_base = 1
fake_IO_FILE += p64(0xffffffffffff)       # _IO_write_ptr = 0xffffffffffff
fake_IO_FILE += p64(0)
fake_IO_FILE += p64(heap_base + 0x148a0)  # v4
fake_IO_FILE += p64(heap_base + 0x148b8)  # v5
fake_IO_FILE = fake_IO_FILE.ljust(0xb0, '\x00')
fake_IO_FILE += p64(0)                    # _mode = 0
fake_IO_FILE = fake_IO_FILE.ljust(0xc8, '\x00')
fake_IO_FILE += p64(IO_str_vtable)        # vtable
payload = fake_IO_FILE + '/bin/sh\x00' + 2 * p64(system_addr)

4. 防御措施

  1. 及时更新 glibc 版本
  2. 检查堆操作中的边界和指针有效性
  3. 对用户输入进行严格验证
  4. 使用安全的内存分配器

5. 总结

House of pig 技术展示了如何在高版本 glibc 下通过组合多种利用技术绕过安全机制。它代表了现代堆利用的发展方向 - 不再是单一技术的应用,而是多种技术的组合利用。理解这些技术需要扎实的堆管理知识和丰富的调试经验。

House of Pig 利用技术详解 1. 简介 House of pig 是一种在 libc 2.31 环境下结合多种堆利用技术的攻击方法,主要适用于程序中仅有 calloc 函数而没有 malloc 函数的情况。它通过以下技术组合实现利用: large bin attack IO_ FILE 结构体利用 tcache stashing unlink attack 2. 前置知识 2.1 Large Bin Attack 2.1.1 攻击效果 libc 2.23:可以向任意两个地址分别写入一个堆地址 libc 2.31:只能向一个任意地址写入堆地址(由于新增安全检查) 2.1.2 利用原理 在 libc 2.31 中,当较大的 chunk 进入 large bin 时会有额外的检查: 因此只能通过向 large bin 中链入较小的 chunk,同时修改原有的 size 比较大的 chunk 的 bk_ nextsize 指针来实现攻击。 2.1.3 利用步骤 准备两个大小不同的 large bin chunk 将 size 较小的 chunk 放入 large bin 中 将 size 较大的 chunk 放在 unsorted bin 中 修改 size 较小的 chunk 的 bk_ nextsize 指针为目标地址-0x20 将 size 较大的 chunk 链入 large bin 中 2.2 Tcache Stashing Unlink Attack 2.2.1 漏洞来源 small bin 处理代码中的检查不充分: 2.2.2 利用条件 能控制 Small Bin Chunk 的 bk 指针 程序可以越过 Tcache 取 Chunk(使用 calloc 即可) 程序至少可以分配两种不同大小且大小为 unsorted bin 的 Chunk 2.2.3 利用步骤 在 tcache 中放入 5 个 chunk(预留两个空位) 在 small bin 中放入两个大小相同的 chunk 修改 small bin 中 chunk 的 bk 指针为 fake chunk 地址 使用 calloc 触发攻击,将 fake chunk 链入 tcache 2.3 calloc 函数特性 calloc 函数不会从 Tcache 拿 Chunk,因此可以绕过"不能越过 Tcache 从 SmallBin 中取出 Chunk"的限制。 3. House of Pig 利用流程 3.1 整体思路 利用 UAF 等漏洞泄露 libc 和 heap 基地址 进行 tcache bin 布置,在 tcache 中放入 5 个 chunk 在 small bin 中放入两个大小相同的 chunk 进行第一次 large bin attack,将堆地址写入 __free_hook-0x8 利用 tcache stashing unlink attack,构造 fake chunk 链入 tcache 进行第二次 large bin attack,将堆地址写入 _IO_list_all 劫持 IO_ FILE 结构体,将 vtable 由 _IO_file_jumps 修改为 _IO_str_jumps 3.2 IO_ FILE 结构体劫持 3.2.1 关键函数分析 将 vtable 改为 _IO_str_jumps 后,程序会调用 _IO_str_overflow 而非 _IO_file_overflow 。 _IO_str_overflow 函数会: 计算缓冲区长度 len = _IO_buf_end - _IO_buf_base 使用 malloc 申请 len*2 + 100 大小的空间 调用 memcpy 将 old_ buf 内容复制到 new_ buf 调用 free(old_ buf) 3.2.2 构造思路 计算好 len 使 malloc 分配到 tcache 中伪造的 fake chunk 让 old_ buf 指向写有 system 函数地址的空间 通过 memcpy 将 system 地址复制到 __free_hook 让 old_ buf 开头写有 "/bin/sh" 3.3 伪造 IO_ FILE 结构体模板 4. 防御措施 及时更新 glibc 版本 检查堆操作中的边界和指针有效性 对用户输入进行严格验证 使用安全的内存分配器 5. 总结 House of pig 技术展示了如何在高版本 glibc 下通过组合多种利用技术绕过安全机制。它代表了现代堆利用的发展方向 - 不再是单一技术的应用,而是多种技术的组合利用。理解这些技术需要扎实的堆管理知识和丰富的调试经验。