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;
}

安全问题:

  1. 取出chunk时仅清空key字段,next指针未被清空
  2. 无size检查
  3. glibc 2.28及之前版本无double free检查

1.3 tcache利用技术

1.3.1 堆地址泄漏(无UAF)

利用步骤:

  1. 释放一个chunk到tcache
  2. 该chunk的next字段会被写入堆地址
  3. 申请该chunk后,next字段未被清空,可读取堆地址

1.3.2 任意地址分配

利用原理:

  • 修改tcache链表中chunk的next指针为目标地址
  • 申请时无检查,可分配到任意地址

限制条件:

  • glibc 2.29+需要地址按0x10对齐

1.3.3 其他利用方式

  1. 修改mp_.tcache_bins扩大tcache管理范围
  2. 覆盖size字段造成堆块重叠(overlapping)
  3. 结合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

利用步骤:

  1. 修改global_max_fast为较大值(如0xffff)
  2. 释放大chunk到fastbin
  3. 申请时通过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分配流程

关键行为:

  1. 精确匹配申请大小
  2. 将剩余chunk转移到tcache
  3. 转移过程无双向链表检查

3.3 tcache stashing unlink attack

利用条件:

  1. 能修改smallbin中第二个chunk的bk指针
  2. 伪造chunk的bk字段指向可写地址

利用步骤:

  1. 准备smallbin链(至少2个chunk)
  2. 修改第二个chunk的bk指向目标地址-0x10
  3. 使用calloc申请或清空tcache对应entry
  4. smallbin处理时会将伪造chunk链入tcache

关键点:

  • 不能破坏第二个chunk的fd字段
  • 伪造chunk的bk字段必须指向可写地址
  • 目标地址+0x10处会被写入main_arena地址

4. malloc_consolidate机制

4.1 触发条件

  1. 申请大小超过smallbin范围
  2. fastbin中的chunk需要合并时

4.2 主要功能

  1. 遍历fastbin中所有chunk
  2. 合并相邻空闲chunk
  3. 将合并后的chunk放入unsortedbin

4.3 利用技术

4.3.1 fastbin+unlink实现overlapping

利用步骤:

  1. 准备两个相邻chunk(chunk1和chunk2)
  2. 伪造chunk1的fd和bk指针
  3. 释放chunk2到fastbin
  4. 设置chunk2的prev_size和prev_inuse位
  5. 申请大chunk触发malloc_consolidate
  6. 合并后造成堆块重叠

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 关键检查项

  1. size字段检查(fastbin)
  2. 双向链表检查(smallbin/unlink)
  3. 对齐检查(glibc 2.29+)
  4. key字段检查(tcache double free)

5.2 绕过技巧

  1. 精确控制伪造的size字段
  2. 维护伪造chunk的fd/bk指针一致性
  3. 使用calloc绕过tcache
  4. 利用合法写入覆盖关键变量(如global_max_fast)

6. 版本差异

  1. glibc 2.28-:无tcache double free检查
  2. glibc 2.29+:增加tcache对齐检查
  3. glibc 2.30+:calloc也检查tcache
  4. glibc 2.32+:增加更多安全检查

7. 综合利用思路

  1. 信息泄露优先:通过残留指针泄漏堆/库地址
  2. 控制关键变量:如global_max_fast、tcache_bins等
  3. 构造伪造结构:精心设计fake chunk
  4. 触发特殊路径:如malloc_consolidate、largebin等
  5. 组合多种技术:如tcache+fastbin+smallbin组合利用

以上内容涵盖了malloc源码中的主要分配机制、安全检查和利用技术,重点分析了各bin的特性和相互转换关系,以及如何利用这些特性实现内存泄漏、任意地址分配和堆块重叠等效果。在实际漏洞利用中,需要根据具体环境和版本选择合适的利用链。

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函数分析 关键代码行为: 安全问题: 取出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分配流程 关键检查: 分配后行为: 将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的特性和相互转换关系,以及如何利用这些特性实现内存泄漏、任意地址分配和堆块重叠等效果。在实际漏洞利用中,需要根据具体环境和版本选择合适的利用链。