house of pig

利用原理

利用链

1
2
exit->__run_exit_handlers->__IO_cleanup->__IO_flush_all_lockp->__IO_str_overflow
->malloc->__memmove_avx_unaligned_erms(memcpy)->free

通过非预期调用 malloc/memcpy/free 实现利用

适用场景

因为利用链是 FSOP 的刷新流,所以需要触发刷新流,调用 __IO_flush_all_lockp 主要有三个时机:

  1. libc 执行 abort 函数时(内存错误)
  2. 程序显式调用 exit 函数时
  3. 程序从 main 函数返回时

现在的比赛环境,有了很多新的 IO 利用链,house of pig 借非预期地调用 mallocmemcpyfree,仍然有一定的应用场景。

除了结合题目的应用场景外,House of pig 通用性上,通常用于显式 exit 的情况(或者存在于 main 函数返回的情况),可以仅用一次 largebinattack 实现攻击目标。

利用技巧

house of pig 有很大通用性优势的,有好几种分支,主要区别在于着重利用的函数。

**方案一:**重点在执行 free,触发 IO_list_all

如果是利用 fastbin reverse 方法就触发 IO_list_all + 0x70stderr 的 chain 字段)

  1. 堆块上放好 payload(我们要触发的函数地址)
  2. 可申请到的 bin 里放置或伪造 free_hook - 0x10(即要修改的位置)
  3. 伪造 IO 结构体,触发实现申请 free_hook,写入 payload
  4. 触发 free 实现利用

**方案二:**重点在执行 memcpy,构造堆用,实现 largebinattack -> 触发 IO_list_all

  1. 在堆块里放置好 payload
  2. 修改 tcache_struct 的值
  3. 以及构造 fake IO 链 (0x410 -> 0x290 -> 0x128 -> 0x108) 触发 tcache 结构体,实现申请 libc.memcpy.got,修改为 system
  4. delete 一个 0x410 的堆

方案二的延伸可以实现不用在 bin 里伪造目标地址,直接触发 tcache 结构体实现任意地址申请,且整个方案只需要进行一次 largebinattack 即可,适用于可以刷新流的任何情况。