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 标记机制
- 写入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- 当前线程已初始化TCachecounts[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:初始堆布局
释放顺序: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
- 申请一个足够大的堆块,能够覆写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攻击方式
// 传统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版本的更新,相关的防护机制也在不断加强,但基本的利用思想仍然具有参考价值。