对PHP-FPM RCE漏洞(CVE-2019-11043)的调试和分析
字数 1519 2025-08-26 22:11:28
PHP-FPM RCE漏洞(CVE-2019-11043)深入分析与调试指南
0x00 漏洞概述
CVE-2019-11043是一个影响PHP-FPM的远程代码执行漏洞,当Nginx与PHP-FPM配合使用时,通过精心构造的恶意请求可以导致远程代码执行。该漏洞的核心在于Nginx处理URL时的正则表达式匹配问题与PHP-FPM内存操作的结合利用。
0x01 漏洞成因
根本原因:Nginx处理URL的正则表达式存在缺陷,在特定情况下会将path_info置空。
关键点:
- Nginx使用
libpcre.so库处理正则表达式 - 当URL中包含换行符(
%0A)时,正则匹配行为异常 - 这种异常导致PHP-FPM接收到的
PATH_INFO环境变量为空
0x02 环境准备
编译调试版PHP-FPM
./configure --prefix=/root/php7.3.10 \
--enable-phpdbg-debug \
--enable-debug \
--enable-fpm \
CFLAGS="-g3 -gdwarf-4"
Nginx配置示例
location ~ [^/]\.php(/|$) {
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
include fastcgi_params;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_index index.php;
fastcgi_param REDIRECT_STATUS 200;
fastcgi_param SCRIPT_FILENAME /opt/nginx-src/nginx-branches-stable-1.10/html$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT /opt/nginx-src/nginx-branches-stable-1.10/html;
fastcgi_pass 127.0.0.1:9000;
}
0x03 漏洞利用原理
关键数据结构
- fcgi_hash_bucket:哈希表结构,保存请求的环境变量键值对
- fcgi_hash_seg:存储键值对的实际数据结构,包含:
pos:指向下一个要插入变量的位置end:当前数据块的终点next:指向下一个fcgi_hash_segdata:连续的键值对存储区域
漏洞触发流程
-
初始状态:
env_path_info指针为空pilen(路径信息长度)为0
-
内存操作异常:
path_info被赋值为env_path_info指针向上偏移slen的值- 通过精心构造的请求,使
path_info指针减去特定长度后,恰好指向fcgi_hash_seg的pos指针最低位
-
内存覆盖:
- 将
pos指针的最低位清零 - 通过
FCGI_PUTENV函数向被修改的pos指针位置写入恶意数据
- 将
-
哈希碰撞利用:
- 需要将
PHP_VALUE覆盖到与它哈希值相同的变量上(如HTTP_EBUT) - 通过长度控制和哈希碰撞,确保PHP-FPM会读取被覆盖的变量
- 需要将
0x04 调试过程详解
关键断点
在init_request_info函数设置断点,观察以下关键变量:
env_path_info的值和指针地址path_info的赋值过程fcgi_hash_seg结构的内存布局
内存操作观察点
-
pos指针修改前:
- 记录
pos指针的原始值 - 确认其指向的内存区域
- 记录
-
pos指针修改后:
- 观察最低位被清零的效果
- 确认指针偏移后的新位置
-
变量写入过程:
- 跟踪
FCGI_PUTENV函数的执行 - 观察
fcgi_hash_set函数如何向被修改的pos位置写入数据
- 跟踪
对齐调整
由于请求路径前有/index.php/(11字节),需要:
- 计算正确的偏移量
- 通过添加HTTP头确保
h->data->pos正确对齐
0x05 利用示例
最简单的利用方式是设置auto_prepend_file:
- 在web目录创建恶意文件
a - 构造请求使PHP-FPM加载该文件作为前置文件
0x06 防御措施
- 升级PHP版本:官方已发布修复补丁
- Nginx配置检查:确保正确处理PATH_INFO
- 输入过滤:过滤包含换行符的请求
- 权限控制:限制PHP-FPM进程权限
0x07 参考资源
0x08 总结
该漏洞利用涉及多个组件的交互异常,包括:
- Nginx的正则处理
- PHP-FPM的内存管理
- 环境变量的哈希存储机制
成功利用需要精确控制内存布局和指针操作,展示了系统组件间交互可能引入的复杂安全问题。