Nginx文件类型错误解析漏洞
漏洞介绍
该漏洞与nginx、php版本无关,是用户配置不当导致的漏洞
漏洞原理
本质是nginx和php对PATH_INFO处理的差异
Fastcgi、Nginx和PHP解析器的关系
先了解Fastcgi、Nginx和PHP解析器都是什么
Fastcgi是一种协议,全称 快速通用网关接口,是升级版的CGI
CGI是外部应用程序与WEB服务器之间的接口标准。CGI规范允许Web服务器执行外部程序,并将它们的输出发送给Web浏览器,CGI将Web的一组简单的静态超媒体文档变成一个完整的新的交互式媒体
Nginx是一款开源的、高性能的HTTP和反向代理服务器。
php解析器(也称为PHP解释器或PHP引擎)是负责读取、解析和执行PHP代码的软件组件。当服务器接收到一个请求,该请求指定要运行一个PHP脚本时,PHP解析器就会被调用。
这三者的运作流程:
首先web服务器(nginx)收到客户端请求后,比如请求的是/index.php,会开始查找文件,发现这是一个php文件后,会找php解析器来处理,但是在交由php解析器处理之前,是需要fastcgi规定传什么数据或什么格式给php解析器,之后php解析器会解析php的配置文件php.ini,处理请求,最后把处理结果返回给浏览器。
PATH_INFO和SCRIPT_FILENAME
什么是PATH_INFO?
PATH_INFO是CGI接口CGI_RFC中定义的一个数据,是指PATH出去SCRIPT_NAME后剩余的部分。例如请求/index.php/for/example,/index.php就是SCRIPT_NAME,而/for/example就是PATH_INFO。
什么是SCRIPT_FILENAME?
在fastcgi中的一个参数。当你访问网址/hello.php/id/123的时候,/hello.php便是你的SCRIPT_FILENAME,即执行脚本的绝对路径。
漏洞成因
在nginx/default.conf的配置文件中.php后缀名的路径会交由fastcgi协议的php解析器处理。
下面是nginx的配置文件
server {
listen 80 default_server;
listen [::]:80 default_server;
root /usr/share/nginx/html;
index index.html index.php;
server_name _;
location / {
try_files $uri $uri/ =404;
}
location ~ \.php$ {
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param REDIRECT_STATUS 200;
fastcgi_param SCRIPT_FILENAME /var/www/html$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT /var/www/html;
fastcgi_pass php:9000;
}
}
这里fastcgi环境变量SCRIPT_FILENAME的由$documen_root,$fastcgi_script_name 二者拼接而成,$documen_root 是web的根路径也就是/var/www/html, $fastcgi_script_name 是http请求的uri。
当访问/uploadfiles/nginx.png/a.php时,nginx不会对a.php是否存在进行检查,而是直接将路径交给fastcgi,并将fastcgi的SCRIPT_FILENAME的$fastcgi_script_name设为/uploadfiles/nginx.png/a.php
然后,fastcgi将参数SCRIPT_FILENAME 传给php-fpm(php解析器)
php-fpm收到后发现a.php不存在,它会去掉最后一个“/”以及后边的所有内容,再次判断文件是否存在,依次循环,直到文件存在。
php-fpm会这样做的原因是php.ini内置了一个选项fix_pathinfo,并且默认是开启的
这样由于nginx和php对路径判断的差异导致了nginx解析漏洞,也就是传入一个/uploadfiles/nginx.png/a.php路径会被错误的解析为/uploadfiles/nginx.png
这样就可以构造一个恶意的png文件,实现getshell
漏洞复现
首先使用docker配置一个实验环境

构造一个恶意png文件在png尾部加入phpinfo,上传后访问/uploadfiles/nginx.png/.php后显示phpinfo界面,漏洞利用成功


浙公网安备 33010602011771号