houseofcat 复现
1 | GNU C Library (Ubuntu GLIBC 2.35-0ubuntu3) stable release version 2.35 |
1 | pwn: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=3aaf66e8616ac46ea3a3708792d4361a6c5b94c6, for GNU/Linux 3.2.0, not stripped |
- 64位,dynamically,全开
1 | ➜ houseofcat patchelf ./house_of_cat --set-interpreter ./ld-linux-x86-64.so.2 --replace-needed libc.so.6 ./libc.so.6 --output house_of_cat1 |
1 | pwndbg> set debug-file-directory /home/yhellow/tools/debuglibc/2.35-0ubuntu3_amd64/usr/lib/debug/ |
有沙盒:
1 | ➜ houseofcat seccomp-tools dump ./house_of_cat1 |
- 白名单:getrandom,open,close,mmap,brk,exit_group
- read 使用的 FD 只能为 “0”
漏洞分析
1 | ssize_t show() |
- 有 UAF
1 | output("Welcome to CatF1y's shop!!\n"); |
1 | 00:0000│ 0x558f614e7160 —▸ 0x7f04f249e3c8 (mp_+104) ◂— 0x40 /* '@' */ |
1 | __int64 init_k() |
- 可以修改
mp_
为 0x40
入侵思路
在 libc-2.34 中删除了:
- __free_hook
- __malloc_hook
- __realloc_hook
- __memalign_hook
- __after_morecore_hook
在 libc-2.34 的早期版本中(glibc-2.34-0ubuntu3_amd64 以及之前),vtable 可写,但在 glibc-2.34-0ubuntu3.2_amd64 中 vtable 不可写
1 | pwndbg> p /x &_IO_2_1_stdout_ |
因为题目限制了 edit 的次数,导致 House Of Emma 不起作用
- House Of Emma 需要3次 edit:
- 构造 largebin attack 攻击
stderr
中的 FILE 结构体 - 构造 largebin attack 攻击
__pointer_chk_guard_local
- 修改 top chunk->size 以触发
sysmalloc
中的__malloc_assert
- 构造 largebin attack 攻击
这时就需要 House Of Emma 中 vtable 偏移的思想,通过修改虚表指针的偏移,转而调用 _IO_wfile_jumps
中的 _IO_wfile_seekoff
函数,然后进入到 _IO_switch_to_wget_mode
函数中来攻击
进行 largebin attack,把 stderr
中的 _IO_2_1_stderr_
覆盖为可控制的 heap 地址
然后注入一些的 fake_IO_FILE:
1 | next_chain = 0 |
因为沙盒中限制了 read 的 FD,所以在调用 ORW 前需要先 close(0)
,使 open("./flag")
的文件描述符生成在 “0”
处
完整 exp:
1 | from pwn import * |
小结:
打比赛的时候没有做出来,在学习了 House Of Kiwi,House Of Emma 后,感觉理解这种调用方式了,最核心的技术还是那一点:通过伪造 vtable 的偏移来进行 vtable 函数任意执行
House Of Cat 只需要两次 edit,比 House Of Emma 还少一次,我感觉基于这个思路应该有很多种调用链,但它们大多数都可以被 House Of Cat 替代
如果本题目的漏洞点不是 UAF,而是 off-by-one 的话,可能会更复杂点,但理论上还是可以通过 unsortedbin 遗留的 FD BK 指针来绕过检查,完成 leak 并且进行一次 largebin attack