深入理解unsorted bin attack
字数 2001 2025-08-24 16:48:07
深入理解Unsorted Bin Attack技术详解
一、Unsorted Bin基础概念
1.1 Unsorted Bin简介
Unsorted Bin是glibc堆管理器中用于缓存最近释放的chunk的一种机制,特点如下:
- 采用双向链表结构组织
- 分配方式是FIFO(先进先出)
- 遍历时使用bk指针(从尾部开始)
- 用于缓存大小不属于fast bin范围的chunk
1.2 Unsorted Bin与其他bins的区别
| 特性 | Unsorted Bin | Fast Bin | Small Bin | Large Bin |
|---|---|---|---|---|
| 组织方式 | 双向链表 | 单链表 | 双向链表 | 双向链表+排序 |
| 分配顺序 | FIFO | LIFO | FIFO | 最佳适配 |
| 遍历方向 | 从bk开始 | 从fd开始 | 从fd开始 | 多方向 |
二、Unsorted Bin Attack原理分析
2.1 关键代码分析
while ((victim = unsorted_chunks(av)->bk) != unsorted_chunks(av)) {
bck = victim->bk;
// size检查
if (__builtin_expect(victim->size <= 2*SIZE_SZ, 0)
|| __builtin_expect(victim->size > av->system_mem, 0))
malloc_printerr(check_action, "malloc(): memory corruption", chunk2mem(victim), av);
// ...省略其他检查...
/* remove from unsorted list */
unsorted_chunks(av)->bk = bck;
bck->fd = unsorted_chunks(av); // 漏洞触发点
2.2 攻击原理
当从unsorted bin中取出chunk时,会执行以下操作:
- 获取victim(链表尾部chunk)和bck(victim->bk)
- 将unsorted bin的bk指针指向bck
- 将bck->fd设置为unsorted_chunks(av)(即main_arena+88)
攻击条件:
- 能够控制victim->bk(即bck)
- 能够绕过size检查(2*SIZE_SZ < size ≤ system_mem)
攻击效果:
可以向任意地址(bck+0x10)写入main_arena+88的值
三、经典利用场景
3.1 修改global_max_fast
# 将global_max_fast改为很大的值,使几乎所有chunk都用fastbin管理
unsorted_bin_attack(global_max_fast-0x10)
3.2 伪造IO_FILE结构
# 修改_IO_list_all为伪造的IO_FILE结构
unsorted_bin_attack(_IO_list_all-0x10)
# 然后通过FSOP触发
3.3 House of Roman利用
# 结合unsorted bin attack和fastbin attack
1. 释放unsorted bin chunk并修改size为0x71
2. 释放两个0x70 chunk,部分写fd指向unsorted bin
3. UAF修改unsorted bin的fd为__malloc_hook-0x23
4. 分配三个0x70 chunk得到__malloc_hook-0x23
5. unsorted bin attack修改__malloc_hook为main_arena+88
6. 部分写__malloc_hook为one_gadget
四、高级利用技巧
4.1 多轮unsorted bin遍历利用
当第一轮victim不满足条件时,会继续遍历:
- 将第一个unsorted bin的bk改为
__malloc_hook-0x10 - 在
__malloc_hook-8处布置合适的size - 第一轮触发unsorted bin attack写
*(__malloc_hook-0x10+0x10) - 第二轮返回伪造的chunk给用户,获得
__malloc_hook控制权
4.2 劫持top chunk
1. 通过unsorted bin attack将main_arena+88写入heap_list
2. 使得top chunk被劫持到目标地址(如GOT表)
3. 通过分配控制目标区域
五、实战案例分析
5.1 pwnhub 2019 classic_revenge
保护机制:全保护开启(ASLR, NX, Canary等)
利用步骤:
- 通过Show功能泄露程序基址(XXTEA加密漏洞)
- 构造overlapping chunk修改size为0x141
- 释放并修改unsorted bin chunk的size为0x71
- 通过fastbin attack修改unsorted bin的bk
- 触发unsorted bin attack获得
__malloc_hook写权限 - 部分写
__malloc_hook为one_gadget
关键代码:
# 修改unsorted bin的bk
Add(0x68, p64(0x21)*2 + p64(0) + p64(0x91) + p64(0) + '\x00')
# 布置__malloc_hook-8的size和可写地址
Add(0x68, '\x00'*(0x13-8) + p64(0xa1) + p64(0) + p64(code_base + 0x202000))
# 触发unsorted bin attack
Add(0x98, '\xa4\xd2\xaf')
5.2 2019武汉"黄鹤杯" note_three
保护机制:Partial RELRO,无PIE
利用步骤:
- 通过堆溢出修改top chunk size
- 分配大chunk使top chunk进入unsorted bin
- 堆溢出修改unsorted bin的bk为heap_list-0x10
- 触发unsorted bin attack将main_arena+88写入heap_list
- 劫持top chunk到GOT表
- 修改atoi为system获取shell
关键代码:
# 修改unsorted bin的bk
Edit(0, "a"*0x10 + p64(0) + p64(0x71) + p64(0) + p64(heap_lis - 0x10))
# 劫持top chunk
Edit(0, p64(0x602048) + p64(0) + p64(0x6020c0 + 0x70)*2)
六、防御与绕过
6.1 常见防御措施
- glibc 2.29+ 引入对unsorted bin的额外检查
- 增加对bk指针的完整性验证
- 对写入地址的合法性检查
6.2 绕过思路
- 寻找合法的中间地址进行间接写入
- 结合其他漏洞(如堆溢出)构造合法chunk结构
- 利用程序已有的数据段构造fake chunk
七、总结与思考
Unsorted Bin Attack作为一种经典的堆利用技术,虽然在新版glibc中受到限制,但在特定环境下仍然强大。其核心价值在于:
- 能够向任意地址写入libc地址(main_arena+88)
- 常作为其他攻击手段的辅助方法
- 在缺乏信息泄露的情况下仍可能实现利用
学习建议:
- 深入理解glibc源码中unsorted bin的处理逻辑
- 掌握多种利用场景的组合应用
- 通过实际题目练习构造精确的内存布局