0%

House Of Corrosion-原理

House Of Corrosion

House Of Corrosion 很早以前就出现了

其根本的思想就是通过往 global_max_fast 写入一个很大的值,来造成 main_arena->fastbinsY 数组溢出


House Of Corrosion 原理

fastbinsY 是在 GLIBC 上储存 fastbin 不同大小链表头指针的一段空间,为大小从 0x20 开始的 fastbin 链表预留了十个指针

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
pwndbg> p main_arena
$1 = {
mutex = 0,
flags = 0,
fastbinsY = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
top = 0x557c160ef860,
last_remainder = 0x0,
bins = {......},
binmap = {0, 0, 65536, 0},
next = 0x7f3a14524b20 <main_arena>,
next_free = 0x0,
attached_threads = 1,
system_mem = 135168,
max_system_mem = 135168
}
  • 这意味着,如果有 SIZE 超过 0xb0 的堆块,那么这个堆块计算得到的索引值就会超出 fastbinsY 的最大范围,造成数组越界

用于决定 fastbin 大小的是 global_max_fast,我们只需要覆盖这个值,然后就可以溢出 main_arena

应用场景是:

  • 能够任意写一个大数据
  • 能够泄露堆地址和 libc 基址
  • 能够触发 IO 流(FSOP 或触发 __malloc_assert),执行 IO 相关函数

House Of Corrosion 利用姿势

劫持 global_max_fast 为一个大数据,就可以从 main_arena 向下溢出,我们要覆盖的目标就是 _IO_list_all

计算偏移:

1
2
3
4
5
6
pwndbg> p &main_arena 
$1 = (malloc_state *) 0x7f85c2d99b20 <main_arena>
pwndbg> p &_IO_list_all
$2 = (_IO_FILE_plus **) 0x7f85c2d9a520 <_IO_list_all>
pwndbg> distance 0x7f85c2d99b20 0x7f85c2d9a520
0x7f85c2d99b20->0x7f85c2d9a520 is 0xa00 bytes (0x140 words)
  • 先计算 main_arena_IO_list_all 之间的偏移
  • 把这个数值乘2就可以得到目标 size

伪造 FILE 结构体,最后申请一个 chunk 用于触发 FSOP,调用链为:

1
malloc_printerr -> _IO_flush_all_lockp -> _IO_overflow

也可以触发 __malloc_assert,调用链为:

1
__malloc_assert -> __fxprintf -> __vfxprintf -> locked_vfxprintf -> __vfprintf_internal

版本对 House Of Corrosion 的影响

  • libc 2.23 :对 vtable 的位置没有检测,可以直接在任意可控位置伪造一个 vtable,直接写 one_gadget 就可以了
  • libc 2.24 及其以后:对 vtable 的范围添加了限制,需要利用偏移来调用具体的 vtable 函数