【翻译】从设置字符集到RCE:利用 GLIBC 攻击 PHP 引擎(篇二)
字数 1496 2025-08-22 22:47:39

利用GLIBC缓冲区溢出漏洞攻击PHP引擎(篇二)教学文档

漏洞概述

本教学文档详细分析了一个存在于GLIBC中长达24年的缓冲区溢出漏洞(CVE-2024-2961)在PHP引擎中的利用方法。该漏洞虽然存在于多个常见库中,但在PHP环境中特别容易被利用。

漏洞背景

漏洞特性

  • 存在于GLIBC的iconv字符集转换功能中
  • 是一个缓冲区溢出漏洞
  • 需要特定字符集转换才能触发(如UTF-8到ISO-2022-CN-EXT)
  • 最多只能写入3个字节到边界外

PHP环境特殊性

  • PHP的堆设计简单,没有特别保护措施
  • 每个请求使用独立的堆(1-heap-per-request)
  • PHP-FPM和mod PHP采用主从进程架构,工作进程崩溃后会自动重启
  • 所有工作进程的内存布局相同(ASLR、PIE)

漏洞触发方式

直接调用iconv()

$input = "A"x160 . "劄劄劄劄\n劄劄劄劄\n劄劄劄劄\n劄劄\n劄劄\n劄劄\n劄劄";
$output = iconv("UTF-8", "ISO-2022-CN-EXT", $input);

通过mbstring扩展间接调用

$output = mb_convert_encoding($input, "ISO-2022-CN-EXT", "UTF-8");
// 当未安装mbstring扩展时,symfony/polyfill-mbstring会使用iconv()实现

漏洞利用原理

信息泄露阶段

  1. 目标结构:覆盖zend_string结构的len字段

    • zend_string结构包含字符串长度信息和实际数据
    • 通过增加len值可以实现内存泄露
  2. 利用步骤

    • 调整堆布局,使4个内存块(A,B,C,D)相邻且空闲
    • 在D块写入目标字符串
    • 从A块溢出,修改指向C块的指针
    • 分配新块覆盖目标字符串头部

代码执行阶段

  1. 目标结构:覆盖zend_array结构的pDestructor指针

    • 控制该指针可以在数组销毁时控制执行流程
  2. 利用方法

    • 通过信息泄露获取内存布局信息
    • 构造特定内存布局覆盖pDestructor
    • 触发数组销毁执行任意代码

Roundcube攻击实例

攻击条件

  • 控制输出字符编码(通过_charset参数)
  • 控制输入缓冲区(通过_to_cc_bcc字段)

攻击步骤

  1. 堆塑形

    • 使用HTTP参数创建特定大小的内存块
    • 示例:创建四个0x400大小的块,并控制它们的分配顺序
  2. 触发漏洞

    • 通过_to字段设置无效电子邮件地址
    • 通过_cc字段触发iconv转换漏洞
  3. 信息泄露

    • 通过_bcc字段分配内存覆盖目标字符串长度
    • 利用错误消息显示泄露内存内容
  4. 会话劫持

    • 覆盖$_SESSION['preferences']变量
    • 利用反序列化漏洞执行任意代码

具体实现

// 堆塑形示例
// 创建四个0x400大小的块:C1 C2 C3 C4
$a = str_repeat('A', 0x3e7); // 在C1和C2中分配
$b = str_repeat('B', 0x3e7); // 在C3和C4分配
$b = ''; // 释放C3和C4
$c = str_repeat('C', 0x3e7); // 重新分配C4

高级利用技术

绕过1-heap-per-request限制

  • 在单个请求中完成准备、触发和利用所有步骤
  • 利用PHP脚本执行过程中的内存分配机会

堆布局控制技巧

  • 通过HTTP参数控制键值对分配
  • 利用字符串连接和数组操作影响内存分配
  • 选择较少使用的内存块大小减少干扰

反序列化利用

  1. 覆盖$_SESSION['preferences']变量
  2. 使用Guzzle/fw1反序列化链实现任意文件写入
  3. 写入webshell获取服务器控制权

防御措施

缓解方案

  • 更新GLIBC到修复版本
  • 禁用或限制iconv的危险字符集转换
  • 对用户输入进行严格过滤

PHP配置建议

  • 限制mbstring扩展使用安全字符集
  • 监控和记录异常字符集转换请求
  • 使用最新版PHP和Roundcube

扩展影响

  • 影响所有使用iconv()或mbstring进行字符集转换的PHP应用
  • 特别是使用symfony/polyfill-mbstring的项目
  • 潜在影响范围超过8.23亿次安装

总结

本漏洞展示了如何利用GLIBC的缓冲区溢出漏洞在PHP环境中实现远程代码执行。通过精心构造的堆操作和PHP内部数据结构覆盖,攻击者可以绕过多种安全机制,最终控制服务器。防御此类攻击需要多层次的安全措施和及时的补丁更新。

利用GLIBC缓冲区溢出漏洞攻击PHP引擎(篇二)教学文档 漏洞概述 本教学文档详细分析了一个存在于GLIBC中长达24年的缓冲区溢出漏洞(CVE-2024-2961)在PHP引擎中的利用方法。该漏洞虽然存在于多个常见库中,但在PHP环境中特别容易被利用。 漏洞背景 漏洞特性 存在于GLIBC的iconv字符集转换功能中 是一个缓冲区溢出漏洞 需要特定字符集转换才能触发(如UTF-8到ISO-2022-CN-EXT) 最多只能写入3个字节到边界外 PHP环境特殊性 PHP的堆设计简单,没有特别保护措施 每个请求使用独立的堆(1-heap-per-request) PHP-FPM和mod PHP采用主从进程架构,工作进程崩溃后会自动重启 所有工作进程的内存布局相同(ASLR、PIE) 漏洞触发方式 直接调用iconv() 通过mbstring扩展间接调用 漏洞利用原理 信息泄露阶段 目标结构 :覆盖 zend_string 结构的 len 字段 zend_string 结构包含字符串长度信息和实际数据 通过增加 len 值可以实现内存泄露 利用步骤 : 调整堆布局,使4个内存块(A,B,C,D)相邻且空闲 在D块写入目标字符串 从A块溢出,修改指向C块的指针 分配新块覆盖目标字符串头部 代码执行阶段 目标结构 :覆盖 zend_array 结构的 pDestructor 指针 控制该指针可以在数组销毁时控制执行流程 利用方法 : 通过信息泄露获取内存布局信息 构造特定内存布局覆盖 pDestructor 触发数组销毁执行任意代码 Roundcube攻击实例 攻击条件 控制输出字符编码(通过 _charset 参数) 控制输入缓冲区(通过 _to 、 _cc 、 _bcc 字段) 攻击步骤 堆塑形 : 使用HTTP参数创建特定大小的内存块 示例:创建四个0x400大小的块,并控制它们的分配顺序 触发漏洞 : 通过 _to 字段设置无效电子邮件地址 通过 _cc 字段触发iconv转换漏洞 信息泄露 : 通过 _bcc 字段分配内存覆盖目标字符串长度 利用错误消息显示泄露内存内容 会话劫持 : 覆盖 $_SESSION['preferences'] 变量 利用反序列化漏洞执行任意代码 具体实现 高级利用技术 绕过1-heap-per-request限制 在单个请求中完成准备、触发和利用所有步骤 利用PHP脚本执行过程中的内存分配机会 堆布局控制技巧 通过HTTP参数控制键值对分配 利用字符串连接和数组操作影响内存分配 选择较少使用的内存块大小减少干扰 反序列化利用 覆盖 $_SESSION['preferences'] 变量 使用Guzzle/fw1反序列化链实现任意文件写入 写入webshell获取服务器控制权 防御措施 缓解方案 更新GLIBC到修复版本 禁用或限制iconv的危险字符集转换 对用户输入进行严格过滤 PHP配置建议 限制mbstring扩展使用安全字符集 监控和记录异常字符集转换请求 使用最新版PHP和Roundcube 扩展影响 影响所有使用iconv()或mbstring进行字符集转换的PHP应用 特别是使用symfony/polyfill-mbstring的项目 潜在影响范围超过8.23亿次安装 总结 本漏洞展示了如何利用GLIBC的缓冲区溢出漏洞在PHP环境中实现远程代码执行。通过精心构造的堆操作和PHP内部数据结构覆盖,攻击者可以绕过多种安全机制,最终控制服务器。防御此类攻击需要多层次的安全措施和及时的补丁更新。