malloc源码调试(一)
字数 2608 2025-08-30 06:50:11
malloc源码分析与利用技术详解
1. tcache机制分析
1.1 tcache基本特性
tcache (thread local caching)是glibc 2.26引入的线程本地缓存机制,主要特点:
- 每个线程独立维护tcache,减少锁竞争
- 单链表结构,LIFO(后进先出)管理
- 默认每个线程有64个bins,每个bin最多存放7个chunk
- chunk大小范围:0x20-0x410(64位系统)
1.2 tcache_get函数分析
关键代码行为:
tcache_get (size_t tc_idx)
{
tcache_entry *e = tcache->entries[tc_idx];
tcache->entries[tc_idx] = e->next;
--(tcache->counts[tc_idx]);
e->key = NULL; // 仅清空key字段
return (void *) e;
}
安全问题:
- 取出chunk时仅清空key字段,next指针未被清空
- 无size检查
- glibc 2.28及之前版本无double free检查
1.3 tcache利用技术
1.3.1 堆地址泄漏(无UAF)
利用步骤:
- 释放一个chunk到tcache
- 该chunk的next字段会被写入堆地址
- 申请该chunk后,next字段未被清空,可读取堆地址
1.3.2 任意地址分配
利用原理:
- 修改tcache链表中chunk的next指针为目标地址
- 申请时无检查,可分配到任意地址
限制条件:
- glibc 2.29+需要地址按0x10对齐
1.3.3 其他利用方式
- 修改
mp_.tcache_bins扩大tcache管理范围 - 覆盖size字段造成堆块重叠(overlapping)
- 结合free函数实现更复杂的利用
2. fastbin机制分析
2.1 fastbin基本特性
- 单链表结构,LIFO管理
- chunk大小范围:0x20-0x80(64位系统)
- 默认最大fastbin大小由
global_max_fast控制
2.2 fastbin分配流程
关键检查:
if (__builtin_expect (fastbin_index (chunksize (victim)) != idx, 0))
{
errstr = "malloc(): memory corruption (fast)";
goto errout;
}
分配后行为:
- 将fastbin链上剩余chunk转移到tcache中
- 转移过程无size检查
2.3 fastbin利用技术
2.3.1 double free
利用原理:
- free时仅检查链首chunk
- 可通过
free(A)->free(B)->free(A)实现double free
2.3.2 修改global_max_fast
利用步骤:
- 修改
global_max_fast为较大值(如0xffff) - 释放大chunk到fastbin
- 申请时通过size与
global_max_fast比较
效果:
- 将大chunk纳入fastbin管理
- 可用于后续攻击
2.3.3 堆地址泄漏
类似tcache:
- 释放两个chunk到fastbin
- 第一个chunk的fd字段会写入堆地址
- 申请时不修改fd字段,可泄漏堆地址
3. smallbin机制分析
3.1 smallbin基本特性
- 双向循环链表结构
- chunk大小范围:0x20-0x3f0(64位系统)
- FIFO(先进先出)管理
3.2 smallbin分配流程
关键行为:
- 精确匹配申请大小
- 将剩余chunk转移到tcache
- 转移过程无双向链表检查
3.3 tcache stashing unlink attack
利用条件:
- 能修改smallbin中第二个chunk的bk指针
- 伪造chunk的bk字段指向可写地址
利用步骤:
- 准备smallbin链(至少2个chunk)
- 修改第二个chunk的bk指向目标地址-0x10
- 使用calloc申请或清空tcache对应entry
- smallbin处理时会将伪造chunk链入tcache
关键点:
- 不能破坏第二个chunk的fd字段
- 伪造chunk的bk字段必须指向可写地址
- 目标地址+0x10处会被写入main_arena地址
4. malloc_consolidate机制
4.1 触发条件
- 申请大小超过smallbin范围
- fastbin中的chunk需要合并时
4.2 主要功能
- 遍历fastbin中所有chunk
- 合并相邻空闲chunk
- 将合并后的chunk放入unsortedbin
4.3 利用技术
4.3.1 fastbin+unlink实现overlapping
利用步骤:
- 准备两个相邻chunk(chunk1和chunk2)
- 伪造chunk1的fd和bk指针
- 释放chunk2到fastbin
- 设置chunk2的prev_size和prev_inuse位
- 申请大chunk触发malloc_consolidate
- 合并后造成堆块重叠
4.3.2 不修改prev_inuse位的overlapping
利用特点:
- 利用smallbin chunk天然的prev_size=0
- 仅需伪造fastbin chunk的prev_size
- 直到glibc 2.40仍可用
关键点:
- 使用smallbin chunk避免unsortedbin检查
- 伪造的prev_size必须与fake_chunk的size匹配
5. 防御机制与绕过
5.1 关键检查项
- size字段检查(fastbin)
- 双向链表检查(smallbin/unlink)
- 对齐检查(glibc 2.29+)
- key字段检查(tcache double free)
5.2 绕过技巧
- 精确控制伪造的size字段
- 维护伪造chunk的fd/bk指针一致性
- 使用calloc绕过tcache
- 利用合法写入覆盖关键变量(如global_max_fast)
6. 版本差异
- glibc 2.28-:无tcache double free检查
- glibc 2.29+:增加tcache对齐检查
- glibc 2.30+:calloc也检查tcache
- glibc 2.32+:增加更多安全检查
7. 综合利用思路
- 信息泄露优先:通过残留指针泄漏堆/库地址
- 控制关键变量:如global_max_fast、tcache_bins等
- 构造伪造结构:精心设计fake chunk
- 触发特殊路径:如malloc_consolidate、largebin等
- 组合多种技术:如tcache+fastbin+smallbin组合利用
以上内容涵盖了malloc源码中的主要分配机制、安全检查和利用技术,重点分析了各bin的特性和相互转换关系,以及如何利用这些特性实现内存泄漏、任意地址分配和堆块重叠等效果。在实际漏洞利用中,需要根据具体环境和版本选择合适的利用链。