House Of Kiwi
House Of Kiwi 使用了一条新的调用链,适用于高版本的 libc 版本
使用条件:
- 能够触发
__malloc_assert
(通常是堆溢出导致) - 能够任意写 WAA(修改
_IO_file_sync
和IO_helper_jumps + 0xA0 and 0xA8
)
House Of Kiwi 原理
House Of Kiwi 需要 __malloc_assert
进行触发,代码如下:
1 | static void |
- 函数
fflush(stderr)
会调用_IO_file_jumps
中的 sync 指针 - 注意这里是
stderr
的_IO_file_jumps
(在 GDB 上看到的第一个_IO_file_jumps
),stdin
和stdout
也有_IO_file_jumps
1 |
|
- 我们可以提前修改
_IO_file_jumps->_IO_file_sync
,进行后续利用
那么 __malloc_assert
怎么触发呢?
_int_malloc
中存在以下的 assert:
1 |
|
- 判断 bck->bk 是不是在 main_arena 中(bck->bk 存储着相应 largebin 中最小的 chunk)
- 破坏 chunk->A 就可以触发
__malloc_assert
sysmalloc
中存在以下的 assert:
1 | assert ((old_top == initial_top (av) && old_size == 0) || |
- 会进行以下判断:
- old_size >= 0x20
- old_top.prev_inuse = 0
- old_top 页对齐
我们故意破坏 chunk 结构,然后进行调试:(sysmalloc 处的 assert)
1 | ► 0x7ffff7e8c4ba <sysmalloc+1850> call __malloc_assert <__malloc_assert> |
- 继续跟进
__malloc_assert
:
1 | ► 0x7ffff7e89cb0 <__malloc_assert+80> call fflush <fflush> |
- 进行跟进
fflush
:
1 | ► 0x7ffff7e78523 <fflush+131> call qword ptr [rbp + 0x60] <setcontext+61> |
- 发现其
rdx
是个定值,而setcontext+61
就是根据rdx
进行操作:
1 | pwndbg> telescope setcontext+61 |
- 所以我们可以提前修改
IO_helper_jumps + 0xA0 and 0xA8
来配合setcontext+61
进行操作
House Of Kiwi 利用姿势
利用模板如下:
1 |
|
结果:
1 | ➜ exp gcc test.c -o test -z noexecstack -fstack-protector-all -pie -z now -masm=intel -g |
利用条件:
- 三次 WAA,分别进行如下的修改:
_IO_file_sync -> setcontext + 61
IO_helper_jumps + 0xA0 -> ORW_ROP_addr
IO_helper_jumps + 0xA0 -> ret
- 能够触发
__malloc_assert
,有如下两种方式:- 修改相应 largebin 中最小 chunk 的 flag->A 为“1”
- 使 top chunk 不足以申请从而调用
sysmalloc
,将 flag->P 写 “0”
版本对 House Of Kiwi 的影响
libc-2.34
在 libc-2.34 的早期版本中(glibc-2.34-0ubuntu3_amd64 以及之前),vtable 可写,但在 glibc-2.34-0ubuntu3.2_amd64 中 vtable 不可写
所以在 glibc-2.34-0ubuntu3_amd64 以及之前,House Of Kiwi 都是可以正常使用的,再次之后就无法使用了