菜鸡pwn手对于exit漏洞的探索
字数 1609 2025-08-29 22:41:24

exit漏洞利用技术深入解析

一、漏洞背景与基本原理

exit函数是程序正常退出的重要函数,其内部调用链中存在可利用的漏洞点。传统认知中,exit漏洞利用通常通过exit->__run_exit_handlers->tls_call_dtors路径劫持结构体跳表,但研究发现存在更直接的利用路径。

关键调用链

exit --> __run_exit_handlers --> [取exit_funcs结构体initial数组+0x18偏移位置的加密指针] -> [用fs:[0x30]内容解密指针] --> _dl_fini

二、核心结构体分析

exit_function结构体

这是控制整个流程的核心结构体,包含以下关键成员:

  • initial:指向控制结构体的指针
  • idx:迭代变量,控制循环次数
  • flavor:分支选择器,决定执行路径

initial结构体

包含实际执行的函数指针和参数:

  • 加密的函数指针(通过PTR_DEMANGLE解密)
  • 可控制的参数(arg)
  • 其他控制流程的成员

三、利用条件

  1. 内存操作能力

    • 能够任意地址分配内存
    • 能够自由读取内存内容(show)
    • 能够任意地址写入chunk地址
  2. 信息泄露能力

    • 能够泄露libc基地址
    • 能够篡改/泄露TLS结构体内容

四、利用技术细节

1. 指针控制机制

通过控制exit_function结构体中的initial指针,可以完全控制函数行为:

  • 篡改initial指针指向可控区域
  • 控制idx实现无限循环
  • 通过flavor选择执行分支

2. 函数指针加密机制

函数指针使用TLS中的pointer_chk_guard进行加密:

#define PTR_DEMANGLE(var) \
  (var) = (__typeof (var)) ((uintptr_t) (var) >> 0x11) ^ (uintptr_t) (var)

3. 加密密钥获取方式

有两种主要方法获取/控制加密密钥:

  1. largebin attack

    • 将堆地址写到pointer_chk_guard
    • 使用堆地址计算加密密钥
  2. 内存泄露

    • 分配到initial结构体处的chunk
    • 泄露原有加密函数指针
    • 与真实函数地址计算得到pointer_chk_guard

4. 参数控制

通过伪造initial结构体可以控制:

  • 函数指针(加密后)
  • 第一个参数(arg)
  • 第二个参数(status)

五、完整利用流程(POC)

1. 初始准备

  • 准备四个chunk,形成两条largebins链
  • 释放两个chunk到unsortedbin泄露libc和堆地址

2. 计算加密指针

  • 通过堆地址计算加密密钥
  • 准备要写入的伪造initial结构体

3. largebin攻击

  • 篡改两个largebin头的bk_nextsize指针
    • 一个指向TLS->pointer_chk_guard
    • 一个指向exit_function
  • 将unsortedbin放入largebins完成指针篡改

4. 触发利用

  • 调用exit触发漏洞
  • 控制流程执行预设函数链(如puts->puts->system)

六、技术难点与限制

  1. TLS地址控制

    • largebin attack只能写堆地址到pointer_chk_guard
    • 需要额外泄露堆地址
    • TLS地址在ASLR下与ld地址偏移固定,泄露复杂
  2. initial结构体伪造

    • largebin attack写入的堆块可能包含arena指针
    • chunk头的size会影响idx导致多余循环
    • 可能造成环境不稳定
  3. ASLR影响

    • TLS地址随机化增加利用难度
    • 需要精确计算偏移

七、优化方向

  1. 更精确的initial控制

    • 寻找更精确的initial结构体写入方式
    • 减少不必要的循环
  2. 密钥获取替代方案

    • 寻找不依赖堆地址的密钥获取方式
    • 利用其他泄露方法获取TLS信息
  3. 稳定性提升

    • 优化伪造结构体内容
    • 减少对环境状态的依赖

八、防御措施

  1. 编译选项

    • 启用FORTIFY_SOURCE
    • 使用最新的glibc版本
  2. 运行时保护

    • 加强ASLR保护
    • 监控异常exit行为
  3. 代码审计

    • 检查exit相关调用链
    • 验证关键结构体完整性

本技术提供了在特定条件下的强大利用能力,但实现复杂度较高,需要结合具体环境进行调整和优化。

exit漏洞利用技术深入解析 一、漏洞背景与基本原理 exit函数是程序正常退出的重要函数,其内部调用链中存在可利用的漏洞点。传统认知中,exit漏洞利用通常通过 exit->__run_exit_handlers->tls_call_dtors 路径劫持结构体跳表,但研究发现存在更直接的利用路径。 关键调用链 二、核心结构体分析 exit_ function结构体 这是控制整个流程的核心结构体,包含以下关键成员: initial :指向控制结构体的指针 idx :迭代变量,控制循环次数 flavor :分支选择器,决定执行路径 initial结构体 包含实际执行的函数指针和参数: 加密的函数指针(通过PTR_ DEMANGLE解密) 可控制的参数(arg) 其他控制流程的成员 三、利用条件 内存操作能力 : 能够任意地址分配内存 能够自由读取内存内容(show) 能够任意地址写入chunk地址 信息泄露能力 : 能够泄露libc基地址 能够篡改/泄露TLS结构体内容 四、利用技术细节 1. 指针控制机制 通过控制 exit_function 结构体中的 initial 指针,可以完全控制函数行为: 篡改 initial 指针指向可控区域 控制 idx 实现无限循环 通过 flavor 选择执行分支 2. 函数指针加密机制 函数指针使用TLS中的 pointer_chk_guard 进行加密: 3. 加密密钥获取方式 有两种主要方法获取/控制加密密钥: largebin attack : 将堆地址写到 pointer_chk_guard 使用堆地址计算加密密钥 内存泄露 : 分配到initial结构体处的chunk 泄露原有加密函数指针 与真实函数地址计算得到 pointer_chk_guard 4. 参数控制 通过伪造initial结构体可以控制: 函数指针(加密后) 第一个参数( arg ) 第二个参数( status ) 五、完整利用流程(POC) 1. 初始准备 准备四个chunk,形成两条largebins链 释放两个chunk到unsortedbin泄露libc和堆地址 2. 计算加密指针 通过堆地址计算加密密钥 准备要写入的伪造initial结构体 3. largebin攻击 篡改两个largebin头的 bk_nextsize 指针 一个指向TLS->pointer_ chk_ guard 一个指向exit_ function 将unsortedbin放入largebins完成指针篡改 4. 触发利用 调用exit触发漏洞 控制流程执行预设函数链(如puts->puts->system) 六、技术难点与限制 TLS地址控制 : largebin attack只能写堆地址到 pointer_chk_guard 需要额外泄露堆地址 TLS地址在ASLR下与ld地址偏移固定,泄露复杂 initial结构体伪造 : largebin attack写入的堆块可能包含arena指针 chunk头的size会影响 idx 导致多余循环 可能造成环境不稳定 ASLR影响 : TLS地址随机化增加利用难度 需要精确计算偏移 七、优化方向 更精确的initial控制 : 寻找更精确的initial结构体写入方式 减少不必要的循环 密钥获取替代方案 : 寻找不依赖堆地址的密钥获取方式 利用其他泄露方法获取TLS信息 稳定性提升 : 优化伪造结构体内容 减少对环境状态的依赖 八、防御措施 编译选项 : 启用FORTIFY_ SOURCE 使用最新的glibc版本 运行时保护 : 加强ASLR保护 监控异常exit行为 代码审计 : 检查exit相关调用链 验证关键结构体完整性 本技术提供了在特定条件下的强大利用能力,但实现复杂度较高,需要结合具体环境进行调整和优化。