堆中global_max_fast相关利用
字数 2238 2025-08-05 08:16:32
堆利用技术:global_max_fast 相关攻击详解
前言
在堆利用技术中,global_max_fast 是一个重要的全局变量,它可以被利用来实现高级的堆攻击。本文将从原理分析到实际案例,详细讲解如何利用 global_max_fast 进行堆攻击。
global_max_fast 基础
定义与作用
global_max_fast 是 glibc 中的一个全局变量,用于定义 fastbin 的大小阈值。小于这个值的堆块会被认为是 fastbin,使用 fastbin 的相应机制进行管理。
#define set_max_fast(s) \
global_max_fast = (((s) == 0) \
? SMALLBIN_WIDTH : ((s + SIZE_SZ) & ~MALLOC_ALIGN_MASK))
#define get_max_fast() global_max_fast
默认情况下,global_max_fast 被初始化为 0x80。
fastbin 管理机制
fastbin 是单链表结构,管理方式简单:
-
malloc 中的 fastbin 处理:
- 找到对应的 fastbin 单链表
- 从中取出堆块
- 检查 size 后返回堆块
-
free 中的 fastbin 处理:
- 检查释放堆块的 size
- 检查下一个堆块的 size
- 获取 fastbin 索引
- 检查 double free
- 将堆块释放到单链表中
关键宏定义
#define fastbin_index(sz) \
((((unsigned int) (sz)) >> (SIZE_SZ == 8 ? 4 : 3)) - 2)
#define fastbin(ar_ptr, idx) ((ar_ptr)->fastbinsY[idx])
这两个宏用于定位 fastbin 数组中的指针。fastbin_index 计算 size 对应的索引,fastbin 获取对应索引的指针。
攻击原理
漏洞利用思路
如果可以改写 global_max_fast 为一个较大的值,然后释放一个较大的堆块时:
- fastbins 数组空间是有限的
- 相对偏移会往后覆盖
- 如果释放堆块的 size 可控,就可以实现往 fastbins 数组(main_arena)后的任意地址写入堆块地址
攻击条件
- 能够覆盖
global_max_fast(通常通过 unsorted bin attack) - 能够控制 free 堆块的 size
- 能够泄露 libc 地址(非必须但通常需要)
计算偏移
计算目标地址对应的 size:
fastbin_ptr = libc_base + libc.symbols['main_arena'] + 8
idx = (target_addr - fastbin_ptr) / 8
size = idx * 0x10 + 0x20
常见攻击目标
_IO_list_all:用于 IO_FILE 攻击stdout/stdin/stderr:用于泄露地址或控制流__free_hook:用于执行任意代码
实际案例分析
案例1: baby_arena (BCTF 2018)
漏洞分析
- Create Order 中存在信息泄露漏洞
- login 中存在栈溢出,可覆盖 user 指针实现任意地址写
利用步骤
- 利用信息泄露获取 libc 地址
- 计算
global_max_fast和_IO_list_all地址 - 利用任意地址写将
global_max_fast覆盖为 0x6E696D6461 ("admin") - 释放堆块至
_IO_list_all - 伪造 IO_FILE 结构
- 触发 FSOP 获取 shell
案例2: zerostorage (0CTF 2016)
漏洞分析
- merge 时 from id 和 to id 可相同,导致 UAF
- 可泄露 libc 地址和堆地址
- 可进行 unsorted bin attack
利用步骤
- 利用 UAF 泄露地址
- 使用 unsorted bin attack 覆盖
global_max_fast - 利用 merge 功能创建大 size 堆块 (0x2000)
- 释放堆块至
_IO_list_all - 伪造 IO_FILE 结构
- 触发 FSOP 获取 shell
案例3: heap_master (*CTF 2019)
漏洞分析
- 可在 mmap 内存中伪造堆块并释放
- 可编辑已释放的堆块(变相 UAF)
利用步骤
- 伪造堆块释放到 unsorted bin
- 编辑堆块 bk 进行 unsorted bin attack,覆盖
global_max_fast - 修改 stdout 结构实现地址泄露:
_IO_write_base指向泄露地址_IO_write_ptr指向结束地址_IO_read_end等于_IO_write_base
- 泄露 libc 地址后,攻击
__free_hook:- 释放堆块到
__free_hook - 编辑堆块 fd 为 system 地址
- 申请堆块将 system 写入
__free_hook - 释放 "/bin/sh" 获取 shell
- 释放堆块到
攻击技术总结
适用场景
- 能够获取 libc 地址
- 能够控制 free 堆块的 size
- 能够往任意地址写但无法控制写的内容(如 unsorted bin attack)
关键技术
- unsorted bin attack:覆盖
global_max_fast - fastbin 任意地址写:通过控制 size 实现
- IO_FILE 攻击:针对
_IO_list_all等目标 - hook 攻击:针对
__free_hook等目标
防御措施
- 更新 glibc 版本(加入更多检查)
- 使用 tcache 机制(改变堆管理方式)
- 加强堆块释放时的检查
附录:相关工具
推荐使用 pwn_debug 框架进行调试:
- 支持带符号调试 glibc
- 支持不同版本 glibc 调试
- 下断点方便,兼容 pwntools
通过深入理解 global_max_fast 相关利用技术,可以解决许多复杂的堆利用场景,特别是在有限条件下实现任意地址写的挑战。