house of botcake详细源码解析
字数 2604 2025-12-16 12:36:41

House of Botcake 漏洞利用技术详解

1. TCache 核心机制分析

1.1 TCache 关键结构体

tcache_perthread_struct

// TCache 主结构体
typedef struct tcache_perthread_struct {
    char counts[TCACHE_MAX_BINS];  // 每个bin的计数器
    tcache_entry *entries[TCACHE_MAX_BINS];  // 每个bin的链表头
} tcache_perthread_struct;

tcache_entry

// TCache 条目结构体
typedef struct tcache_entry {
    struct tcache_entry *next;  // 指向下一个chunk
    uintptr_t key;             // 安全标记,防double free
} tcache_entry;

1.2 TCache 安全机制

Key 标记机制

  • 写入keye->key = tcache_key - 标记chunk已在TCache中,防止double free
  • 清除keye->key = 0 - 表示chunk已分配出去,不再属于TCache

核心安全函数

tcache_next(e)

  • 安全获取TCache链表中下一个节点
  • 自动对e->next进行指针解密(REVEAL_PTR)
  • 支持glibc ≥ 2.32的safe-linking安全特性

tcache_available(tc_idx)

  • 快速判断指定大小类(tc_idx)的TCache bin是否有可用chunk
  • 检查条件:
    1. tc_idx < mp_.tcache_bins - 索引合法(默认64个bins,对应24~512字节)
    2. tcache != NULL - 当前线程已初始化TCache
    3. counts[tc_idx] > 0 - 该bin中有空闲chunk

tcache_double_free_verify(e, tc_idx)

  • TCache报错的主要原因
  • 双重检查机制:
    • 第一层(快速检查):在_int_free中检查e->key == tcache_key
    • 第二层(可靠检查):即使key被篡改也能发现double free

1.3 全局管理结构体

mp(malloc parameters)

  • 全局的、进程级别的堆配置参数
  • 所有arena共享同一份mp_
  • 可通过环境变量调整(如MALLOC_ARENA_MAX=1TCACHE_COUNT=10

av(arena)

  • 每个线程最多有一个arena(优先使用自己的thread arena,否则共享main_arena)
  • main_arena:主线程的arena,也作为fallback
  • 多个arena可以同时存在(用于多线程并发malloc/free,避免锁竞争)

1.4 TCache 核心操作函数

tcache_free(p, size)

  • 高层封装函数,尝试将chunk放入当前线程的TCache
  • 检查流程:
    1. 检查e->key == tcache_key → 可能double free
    2. 若命中,调用tcache_double_free_verify做O(n)遍历确认

tcache_init()

  • 第一次调用malloc/free时懒初始化TCache
  • 从某个arena(通常是main_arena)分配内存作为tcache_perthread_struct

MAYBE_INIT_TCACHE()宏

  • 用在malloc和free路径中
  • 避免每次检查,只在首次使用时初始化
  • 防止重复初始化

tcache_try_malloc(bytes, memptr)

  • malloc的fast path:先查TCache
  • 若可用,调用tcache_get(内部会清key=0)
  • 若不可用,返回NULL,后续走_int_malloc正常流程

tcache_thread_shutdown()

  • 线程退出时,TCache中的chunk必须归还给主堆
  • 调用__libc_free(e) → 进入_int_free → 可能合并、进unsorted bin
  • 唯一将TCache chunk批量"降级"到主堆的路径

2. House of Botcake 漏洞原理

2.1 漏洞本质

House of Botcake是一种基于TCache的UAF(Use-After-Free)利用技术,通过精心构造的堆布局实现任意地址写。

2.2 利用条件

  1. 存在UAF漏洞,能够对已释放的chunk进行写操作
  2. 能够控制chunk的释放顺序
  3. 能够申请特定大小的chunk

2.3 攻击步骤详解

步骤1:初始堆布局

释放顺序:A → B
堆布局:A在下,B在上

步骤2:触发合并机制

  • A和B合并,B的fd指针转移到A的fd
  • 此时B既在unsorted bin中又在TCache中

步骤3:再次释放B

// 关键操作:对B进行double free
free(B);  // 此时B已经在TCache中,但通过特定条件绕过检查

步骤4:申请大堆块并伪造fd

  1. 申请一个足够大的堆块,能够覆写B的fd指针
  2. 在申请后完成fd指针的伪造
  3. TCache成功将fake chunk拉入链表

2.4 关键绕过技术

标志位修改

  • 通过修改B的标志位绕过TCache的double free检查
  • 核心是控制chunk的metadata,使其在特定时刻不被识别为double free

延迟加入key机制

  • House of Botcake虽然加入了key,但是延迟加入的
  • 在glibc 2.34之后,由于链长度限制,此技术效果受限

3. 实际利用示例

3.1 与传统技术的对比

Fastbin攻击方式

// 传统fastbin攻击
free(A); free(A);  // double free
malloc(size);      // 申请出来编辑
// 产生额外chunk,用于后续利用

House of Botcake优势

  • 简化利用流程,减少操作步骤
  • 避免频繁的double free检测
  • 更稳定的利用成功率

3.2 实际代码实现要点

Arena管理示例

// 示例1:创建新arena时用mp_.arena_test
// 示例2:决定是否走mmap
// 示例3:TCache是否启用
// 示例4:free时检查TCache是否满

信息泄露利用

  • 泄露av地址:可计算heap基址(main_arena在libc data段附近)
  • 泄露mp地址:较少见,可通过/proc/self/maps或infoleak获取libc基址后计算
  • 修改mp字段:如tcache_count,可扩大TCache容量辅助攻击(但通常不可写)

4. 防护与检测

4.1 安全增强特性

  • Safe-linking:glibc ≥ 2.32引入的指针加密机制
  • Double-free检测:多层次的验证机制
  • Key标记系统:防止简单的UAF利用

4.2 检测方法

  • 监控异常的chunk释放模式
  • 检测TCache链表的异常长度
  • 分析key标记的异常变化

5. 总结

House of Botcake代表了现代堆利用技术的发展方向,它充分利用了TCache机制的特性,通过精妙的堆布局和时序控制实现漏洞利用。理解这一技术需要深入掌握glibc的内存管理机制,特别是TCache的安全实现细节。随着glibc版本的更新,相关的防护机制也在不断加强,但基本的利用思想仍然具有参考价值。

House of Botcake 漏洞利用技术详解 1. TCache 核心机制分析 1.1 TCache 关键结构体 tcache_ perthread_ struct tcache_ entry 1.2 TCache 安全机制 Key 标记机制 写入key : e->key = tcache_key - 标记chunk已在TCache中,防止double free 清除key : e->key = 0 - 表示chunk已分配出去,不再属于TCache 核心安全函数 tcache_ next(e) 安全获取TCache链表中下一个节点 自动对 e->next 进行指针解密(REVEAL_ PTR) 支持glibc ≥ 2.32的safe-linking安全特性 tcache_ available(tc_ idx) 快速判断指定大小类(tc_ idx)的TCache bin是否有可用chunk 检查条件: tc_idx < mp_.tcache_bins - 索引合法(默认64个bins,对应24~512字节) tcache != NULL - 当前线程已初始化TCache counts[tc_idx] > 0 - 该bin中有空闲chunk tcache_ double_ free_ verify(e, tc_ idx) TCache报错的主要原因 双重检查机制: 第一层(快速检查):在 _int_free 中检查 e->key == tcache_key 第二层(可靠检查):即使key被篡改也能发现double free 1.3 全局管理结构体 mp(malloc parameters) 全局的、进程级别的堆配置参数 所有arena共享同一份 mp_ 可通过环境变量调整(如 MALLOC_ARENA_MAX=1 、 TCACHE_COUNT=10 ) av(arena) 每个线程最多有一个arena(优先使用自己的thread arena,否则共享main_ arena) main_arena :主线程的arena,也作为fallback 多个arena可以同时存在(用于多线程并发malloc/free,避免锁竞争) 1.4 TCache 核心操作函数 tcache_ free(p, size) 高层封装函数,尝试将chunk放入当前线程的TCache 检查流程: 检查 e->key == tcache_key → 可能double free 若命中,调用 tcache_double_free_verify 做O(n)遍历确认 tcache_ init() 第一次调用malloc/free时懒初始化TCache 从某个arena(通常是main_ arena)分配内存作为 tcache_perthread_struct MAYBE_ INIT_ TCACHE()宏 用在malloc和free路径中 避免每次检查,只在首次使用时初始化 防止重复初始化 tcache_ try_ malloc(bytes, memptr) malloc的fast path:先查TCache 若可用,调用 tcache_get (内部会清key=0) 若不可用,返回NULL,后续走 _int_malloc 正常流程 tcache_ thread_ shutdown() 线程退出时,TCache中的chunk必须归还给主堆 调用 __libc_free(e) → 进入 _int_free → 可能合并、进unsorted bin 唯一将TCache chunk批量"降级"到主堆的路径 2. House of Botcake 漏洞原理 2.1 漏洞本质 House of Botcake是一种基于TCache的UAF(Use-After-Free)利用技术,通过精心构造的堆布局实现任意地址写。 2.2 利用条件 存在UAF漏洞,能够对已释放的chunk进行写操作 能够控制chunk的释放顺序 能够申请特定大小的chunk 2.3 攻击步骤详解 步骤1:初始堆布局 步骤2:触发合并机制 A和B合并,B的fd指针转移到A的fd 此时B既在unsorted bin中又在TCache中 步骤3:再次释放B 步骤4:申请大堆块并伪造fd 申请一个足够大的堆块,能够覆写B的fd指针 在申请后完成fd指针的伪造 TCache成功将fake chunk拉入链表 2.4 关键绕过技术 标志位修改 通过修改B的标志位绕过TCache的double free检查 核心是控制chunk的metadata,使其在特定时刻不被识别为double free 延迟加入key机制 House of Botcake虽然加入了key,但是延迟加入的 在glibc 2.34之后,由于链长度限制,此技术效果受限 3. 实际利用示例 3.1 与传统技术的对比 Fastbin攻击方式 House of Botcake优势 简化利用流程,减少操作步骤 避免频繁的double free检测 更稳定的利用成功率 3.2 实际代码实现要点 Arena管理示例 信息泄露利用 泄露av地址 :可计算heap基址(main_ arena在libc data段附近) 泄露mp地址 :较少见,可通过/proc/self/maps或infoleak获取libc基址后计算 修改mp字段 :如tcache_ count,可扩大TCache容量辅助攻击(但通常不可写) 4. 防护与检测 4.1 安全增强特性 Safe-linking :glibc ≥ 2.32引入的指针加密机制 Double-free检测 :多层次的验证机制 Key标记系统 :防止简单的UAF利用 4.2 检测方法 监控异常的chunk释放模式 检测TCache链表的异常长度 分析key标记的异常变化 5. 总结 House of Botcake代表了现代堆利用技术的发展方向,它充分利用了TCache机制的特性,通过精妙的堆布局和时序控制实现漏洞利用。理解这一技术需要深入掌握glibc的内存管理机制,特别是TCache的安全实现细节。随着glibc版本的更新,相关的防护机制也在不断加强,但基本的利用思想仍然具有参考价值。