堆中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 是单链表结构,管理方式简单:

  1. malloc 中的 fastbin 处理

    • 找到对应的 fastbin 单链表
    • 从中取出堆块
    • 检查 size 后返回堆块
  2. 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 为一个较大的值,然后释放一个较大的堆块时:

  1. fastbins 数组空间是有限的
  2. 相对偏移会往后覆盖
  3. 如果释放堆块的 size 可控,就可以实现往 fastbins 数组(main_arena)后的任意地址写入堆块地址

攻击条件

  1. 能够覆盖 global_max_fast(通常通过 unsorted bin attack)
  2. 能够控制 free 堆块的 size
  3. 能够泄露 libc 地址(非必须但通常需要)

计算偏移

计算目标地址对应的 size:

fastbin_ptr = libc_base + libc.symbols['main_arena'] + 8
idx = (target_addr - fastbin_ptr) / 8
size = idx * 0x10 + 0x20

常见攻击目标

  1. _IO_list_all:用于 IO_FILE 攻击
  2. stdout/stdin/stderr:用于泄露地址或控制流
  3. __free_hook:用于执行任意代码

实际案例分析

案例1: baby_arena (BCTF 2018)

漏洞分析

  1. Create Order 中存在信息泄露漏洞
  2. login 中存在栈溢出,可覆盖 user 指针实现任意地址写

利用步骤

  1. 利用信息泄露获取 libc 地址
  2. 计算 global_max_fast_IO_list_all 地址
  3. 利用任意地址写将 global_max_fast 覆盖为 0x6E696D6461 ("admin")
  4. 释放堆块至 _IO_list_all
  5. 伪造 IO_FILE 结构
  6. 触发 FSOP 获取 shell

案例2: zerostorage (0CTF 2016)

漏洞分析

  1. merge 时 from id 和 to id 可相同,导致 UAF
  2. 可泄露 libc 地址和堆地址
  3. 可进行 unsorted bin attack

利用步骤

  1. 利用 UAF 泄露地址
  2. 使用 unsorted bin attack 覆盖 global_max_fast
  3. 利用 merge 功能创建大 size 堆块 (0x2000)
  4. 释放堆块至 _IO_list_all
  5. 伪造 IO_FILE 结构
  6. 触发 FSOP 获取 shell

案例3: heap_master (*CTF 2019)

漏洞分析

  1. 可在 mmap 内存中伪造堆块并释放
  2. 可编辑已释放的堆块(变相 UAF)

利用步骤

  1. 伪造堆块释放到 unsorted bin
  2. 编辑堆块 bk 进行 unsorted bin attack,覆盖 global_max_fast
  3. 修改 stdout 结构实现地址泄露:
    • _IO_write_base 指向泄露地址
    • _IO_write_ptr 指向结束地址
    • _IO_read_end 等于 _IO_write_base
  4. 泄露 libc 地址后,攻击 __free_hook
    • 释放堆块到 __free_hook
    • 编辑堆块 fd 为 system 地址
    • 申请堆块将 system 写入 __free_hook
    • 释放 "/bin/sh" 获取 shell

攻击技术总结

适用场景

  1. 能够获取 libc 地址
  2. 能够控制 free 堆块的 size
  3. 能够往任意地址写但无法控制写的内容(如 unsorted bin attack)

关键技术

  1. unsorted bin attack:覆盖 global_max_fast
  2. fastbin 任意地址写:通过控制 size 实现
  3. IO_FILE 攻击:针对 _IO_list_all 等目标
  4. hook 攻击:针对 __free_hook 等目标

防御措施

  1. 更新 glibc 版本(加入更多检查)
  2. 使用 tcache 机制(改变堆管理方式)
  3. 加强堆块释放时的检查

附录:相关工具

推荐使用 pwn_debug 框架进行调试:

  1. 支持带符号调试 glibc
  2. 支持不同版本 glibc 调试
  3. 下断点方便,兼容 pwntools

通过深入理解 global_max_fast 相关利用技术,可以解决许多复杂的堆利用场景,特别是在有限条件下实现任意地址写的挑战。

堆利用技术:global_ max_ fast 相关攻击详解 前言 在堆利用技术中, global_max_fast 是一个重要的全局变量,它可以被利用来实现高级的堆攻击。本文将从原理分析到实际案例,详细讲解如何利用 global_max_fast 进行堆攻击。 global_ max_ fast 基础 定义与作用 global_max_fast 是 glibc 中的一个全局变量,用于定义 fastbin 的大小阈值。小于这个值的堆块会被认为是 fastbin,使用 fastbin 的相应机制进行管理。 默认情况下, global_max_fast 被初始化为 0x80。 fastbin 管理机制 fastbin 是单链表结构,管理方式简单: malloc 中的 fastbin 处理 : 找到对应的 fastbin 单链表 从中取出堆块 检查 size 后返回堆块 free 中的 fastbin 处理 : 检查释放堆块的 size 检查下一个堆块的 size 获取 fastbin 索引 检查 double free 将堆块释放到单链表中 关键宏定义 这两个宏用于定位 fastbin 数组中的指针。 fastbin_index 计算 size 对应的索引, fastbin 获取对应索引的指针。 攻击原理 漏洞利用思路 如果可以改写 global_max_fast 为一个较大的值,然后释放一个较大的堆块时: fastbins 数组空间是有限的 相对偏移会往后覆盖 如果释放堆块的 size 可控,就可以实现往 fastbins 数组(main_ arena)后的任意地址写入堆块地址 攻击条件 能够覆盖 global_max_fast (通常通过 unsorted bin attack) 能够控制 free 堆块的 size 能够泄露 libc 地址(非必须但通常需要) 计算偏移 计算目标地址对应的 size: 常见攻击目标 _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 相关利用技术,可以解决许多复杂的堆利用场景,特别是在有限条件下实现任意地址写的挑战。