前言
偶然在推特看到的这个比赛, 搜了下似乎国内没什么人参加, 但是往年题目质量还不错(?), 摸鱼打了打, 4道pwn只做了2个, 剩下一个是Windows Pwn一个是GameBoy, 都不太熟= =.
onetestament
glibc 2.23的heap菜单题, some old tricks 😀
限制因素:
- 能申请的
mem size只有四种:0x18 0x30 0x60 0x7c - 只有在
add的时候可以leak信息,show函数是没用的 - 用的是
calloc, 会把申请到的chunk清零 - 最多只允许调用11次
calloc(0-10) delete里用了一个标志变量判断是否有double-free
漏洞点:
edit有off-by-one, 在可以改下一个chunk header的size- 读入菜单选项的函数存在一个字节的溢出, 可以把第4块chunk(编号从0开始)是否被free过的标志变量覆写, 从而达到
double free
这里有一个小知识点, 在glibc-2.23/malloc/malloc.c的__libc_calloc函数中(3259行):
/* Two optional cases in which clearing not necessary */
if (chunk_is_mmapped (p))
{
if (__builtin_expect (perturb_byte, 0))
return memset (mem, 0, sz);
return mem;
}
可以看到calloc 函数不会把 mmap 系统调用拿到的内存清零, 这是因为mmap系统调用拿到的内存本身就是清零的, 为了节省性能开销这里就不再调用memset清了.
因此如果能覆写chunk的IS_MMAPED位, 就可以绕过calloc的清零操作. 参考chunk结构图可以发现当一个chunk的data部分大小为0x18时, 其利用edit中的off-by-one就正好可以覆盖下一个chunk的IS_MMAPED位:

那么现在思路其实很明确了, 主要步骤:
- 用0x18的chunk作为辅助编辑块, 负责修改其下一个chunk的
IS_MMAPED绕过calloc的清零 - 用
0x7c大小的unsorted bin chunk泄露libc基址 - 用
0x60大小的chunk做fastbin attack, 拿到一块指向__malloc_hook的fake chunk - 覆写
__malloc_hook为one gadget, 调用一次add拿到shell
继续阅读“Insomni’hack teaser 2022 Pwn writeup”
