1. Unsortedbin Attack概述
Unsortedbin attack是一种针对glibc堆管理器中unsorted bin机制的漏洞利用技术。这种攻击方式主要出现在ptmalloc2的内存管理实现中,允许攻击者通过精心构造的内存操作实现任意地址写。我在实际漏洞挖掘中发现,这种技术常与use-after-free漏洞配合使用,能够绕过ASLR等现代防护机制。
unsorted bin是glibc堆管理器中的一种特殊空闲链表,用于存放刚被释放的中等大小chunk(默认情况下大于global_max_fast的chunk)。当程序再次申请内存时,堆管理器会优先从unsorted bin中寻找合适大小的chunk进行分配。正是这种特殊的管理机制,为攻击者提供了可乘之机。
2. 技术原理深度解析
2.1 Unsorted Bin工作机制
在glibc的堆管理实现中,unsorted bin采用双向链表结构管理空闲chunk。每个chunk的fd(forward pointer)和bk(backward pointer)指针构成了这个链表的基础。关键点在于,当从unsorted bin中取出chunk时,glibc会执行以下关键操作:
// 简化版的unlink操作 victim = unsorted_chunks(av)->bk; bck = victim->bk; unsorted_chunks(av)->bk = bck; bck->fd = unsorted_chunks(av);这段代码存在一个关键特性:它会将victim的bk指针所指向的chunk的fd字段写入main_arena的地址。如果我们能控制victim的bk指针,就能实现向任意地址写入main_arena地址的效果。
2.2 攻击条件与利用路径
要实现成功的unsortedbin attack,需要满足以下几个必要条件:
- 能够控制一个将被放入unsorted bin的chunk的bk指针
- 能够触发从unsorted bin中分配内存的操作
- 目标写入地址需要满足特定对齐要求(通常需要可写)
典型的利用路径如下:
- 通过堆溢出或UAF漏洞修改某个chunk的bk指针
- 释放该chunk使其进入unsorted bin
- 再次申请内存触发unlink操作
- 目标地址被写入main_arena的地址
3. 实战操作演示
3.1 环境准备与POC构造
下面是一个典型的利用场景POC代码:
#include <stdio.h> #include <stdlib.h> int main() { unsigned long stack_var = 0; printf("目标变量原始值: %p\n", (void *)stack_var); unsigned long *p = malloc(0x420); // 分配大于fastbin的chunk malloc(0x20); // 防止合并 free(p); // 此时p进入unsorted bin // 假设存在漏洞可以修改p的bk指针 p[1] = (unsigned long)(&stack_var - 2); // 伪造bk // 触发unlink操作 malloc(0x420); printf("攻击后目标变量值: %p\n", (void *)stack_var); return 0; }这段代码演示了最基本的unsortedbin attack。在实际漏洞利用中,我们通常需要结合其他技术来绕过防护措施。
3.2 高级利用技巧
在实际漏洞利用中,我们经常需要解决以下问题:
- 绕过ASLR:虽然unsortedbin attack本身不能直接泄露地址,但可以通过多次写入来推断关键地址
- 控制写入值:main_arena的地址通常包含NULL字节,这限制了它在字符串操作中的使用
- 组合利用:常与fastbin attack或house of系列技术配合使用
一个进阶技巧是通过部分覆盖指针来精确控制写入位置。例如,在64位系统中,我们可以只覆盖指针的低4字节,这样可以绕过完整的ASLR防护。
4. 防御措施与绕过方法
4.1 现代防护机制
glibc在后续版本中引入了一些防护措施:
- 对unlink操作增加了完整性检查(fd->bk == victim && bk->fd == victim)
- 引入了tcache机制改变了内存分配优先级
- 增加了更多随机化因素
4.2 仍然可利用的场景
即使在较新的glibc版本中,unsortedbin attack仍然在以下情况有效:
- 当tcache被填满时
- 处理large bin chunk时
- 在某些特殊的堆布局情况下
特别是在处理large bin时,glibc会执行类似的unlink操作,这为攻击者提供了替代的利用路径。
5. 实际漏洞案例分析
5.1 CVE-2017-15804分析
这是一个典型的unsortedbin attack实际案例。在特定条件下,通过精心构造的ELF文件可以触发该漏洞。攻击者可以利用这个漏洞修改全局变量,进而控制程序流。
关键利用步骤:
- 通过文件解析漏洞构造特殊的chunk布局
- 触发释放操作使特定chunk进入unsorted bin
- 修改chunk的bk指针指向目标地址
- 触发内存分配完成攻击
5.2 结合其他技术的复合利用
在实际漏洞利用中,我经常将unsortedbin attack与其他技术组合使用。例如:
- 先使用unsortedbin attack修改global_max_fast值
- 然后进行fastbin attack实现更灵活的写操作
- 最后通过修改hook函数或got表实现代码执行
这种组合技术可以绕过大多数现代防护机制,实现可靠的漏洞利用。
6. 检测与防护建议
6.1 开发者防护措施
作为开发者,可以采取以下措施防范此类攻击:
- 及时更新glibc到最新版本
- 对所有堆操作进行严格的边界检查
- 使用现代防护技术如FORTIFY_SOURCE
- 考虑使用替代的内存分配器如jemalloc
6.2 漏洞检测方法
在代码审计时,应特别注意以下危险模式:
- 对堆指针的算术运算未检查边界
- 释放后仍然使用指针(UAF)
- 对堆块内容的非受控写入
可以使用如AddressSanitizer等工具来自动检测这类问题。在我的实践中,结合静态分析和动态检测能发现大多数潜在的漏洞。
7. 延伸技术与研究
7.1 与House of技术的关联
Unsortedbin attack是很多高级堆利用技术的基础,例如:
- House of Orange:利用unsortedbin attack修改IO_FILE结构
- House of Einherjar:通过off-by-one触发unsortedbin操作
- House of Force:有时需要unsortedbin attack作为前置条件
理解这些技术的关联性对于掌握现代堆利用至关重要。
7.2 最新研究进展
近年来,随着防护措施的加强,纯粹的unsortedbin attack已经较少见。但研究人员发现了以下变种:
- 针对large bin的类似攻击
- 结合tache的特定条件利用
- 在多线程环境下的特殊利用方式
这些新技术表明,堆利用领域仍在不断发展,需要持续关注最新的研究成果。