如何利用mitre.org给出的CWE-415双重释放漏洞示例代码?
CWE-415 双重释放漏洞示例利用原理说明
前置说明
该利用逻辑仅适用于未开启堆元数据完整性校验、使用glibc ptmalloc内存分配器的旧版本Linux发行版,通常对应glibc 2.26之前未引入tcache、或tcache未增加指针完整性校验的环境。
漏洞点定位
样例代码的核心问题是buf2R1指针被重复释放:
- 首次释放
buf1R1、buf2R1两个小堆块 - 新申请的
buf1R2大堆块会合并上述两个空闲的小堆块,此时buf2R1指向的地址已经属于buf1R2的可写用户数据区 - 再次调用
free(buf2R1)触发双重释放,且此时buf2R1对应的旧堆块元数据已经可以被用户通过argv[1]完全控制
完整利用链路
- 步骤1:初始分配释放阶段
两次malloc(BUFSIZE2)会得到两个相邻的小堆块,首次free后两个块会进入对应大小的fastbin/tcache空闲链表,处于可被合并的状态。 - 步骤2:堆块合并阶段
申请BUFSIZE1大小的堆块时,ptmalloc会判断刚释放的两个相邻小堆块的总大小刚好匹配请求的大堆块需求,因此会将两个小堆块合并后分配给buf1R2。此时buf1R2的内存范围完全覆盖两个旧小堆块的全部区域,包括buf2R1对应的旧堆块的元数据段。 - 步骤3:堆元数据篡改阶段
strncpy(buf1R2, argv[1], BUFSIZE1-1)会将用户可控的输入写入buf1R2,此时可以通过构造argv[1]的内容,精准篡改buf2R1旧堆块的fd(空闲链表forward指针)等元数据为任意值。 - 步骤4:触发任意地址分配
调用free(buf2R1)触发双重释放时,因为系统未开启堆校验,ptmalloc会把我们篡改了元数据的旧buf2R1块再次加入空闲链表。当下次申请对应大小的堆块时,分配器就会返回我们伪造的fd指向的地址,实现任意地址写,后续可以通过覆盖GOT表、返回地址等方式完成权限获取。
防护机制的影响
如果系统开启了堆块校验和功能,在双重释放、或检测到堆元数据被篡改时会直接触发进程崩溃,上述利用链路会被中断。
内容的提问来源于stack exchange,提问作者Enrico R.
相关产品推荐
相关产品推荐

