Nginx解析漏洞汇总

0x01 概述


Nginx的解析漏洞都是与CGI接口有关,PHP5.3.3之后就自带了PHP-FPM。

另外现在网上的资料都是说从5.3.9开始,php官方加入了一个配置”security.limit_extensions”,默认状态下只允许执行扩展名为”.php”的文件。

可以查看/etc/php-fpm.d/www.conf

; Limits the extensions of the main script FPM will allow to parse. This can

; prevent configuration mistakes on the web server side. You should only limit

; FPM to .php extensions to prevent malicious users to use other extensions to

; exectute php code.

; Note: set an empty value to allow all extensions.

; Default Value: .php

security.limit_extensions = .php .php3 .php4 .php5

可以看到默认值为.php。这样其实下面的解析漏洞是不受影响的。

不过现在CentOS6下通过yum安装的php-fpm:

[root@kafka112 ~]# yum install php-fpm -y

版本是5.3.3

[root@kafka112 ~]# rpm -qa | grep php-fpm

php-fpm-5.3.3-49.el6.x86_64

默认值为.php

[root@kafka112 php-fpm.d]# grep -B 1 'limit_extensions' www.conf

; Default Value: .php

;security.limit_extensions = .php .php3 .php4 .php5

与网上说法不太一致,测试需要注意。

 

0x02 fix_pathinfo


漏洞测试:

访问http://www.target.com/robots.txt

返回头Content-Type: text/plain

访问http://www.target.com/robots.txt/x.php

返回头Content-Type: text/html

也就是robots.txt被当做PHP解析。那么问题就来了,如果用户上传包含恶意代码的头像文件,然后利用该方法解析为PHP,那么就能轻松拿到shell。

其实该问题的根本原因在于php.ini中的cgi.fix_pathinfo配置,我们来看下cgi.fix_pathinfo配置

; cgi.fix_pathinfo provides *real* PATH_INFO/PATH_TRANSLATED support for CGI.  PHP's

; previous behaviour was to set PATH_TRANSLATED to SCRIPT_FILENAME, and to not grok

; what PATH_INFO is.  For more information on PATH_INFO, see the cgi specs.  Setting

; this to 1 will cause PHP CGI to fix it's paths to conform to the spec.  A setting

; of zero causes PHP to behave as before.  Default is 1.  You should fix your scripts

; to use SCRIPT_FILENAME rather than PATH_TRANSLATED.

cgi.fix_pathinfo=0

如果开启了这个选项, 那么就会触发在PHP中的如下逻辑:

/*

 * 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] == '/' ||

....//以下省略.

可以看到如果文件不存在,则会PATH_INFO作为PHP解析。

 

修复方案如下:

1)修改php.ini文件,将cgi.fix_pathinfo的值设置为0,完成后重启PHP-FPM。此操作可能会响应到正常功能。

2)在Nginx配置文件中添加以下代码:

  if ( $fastcgi_script_name ~ \..*\/.*php ) {

           return 403;

  }

 

0x03 空字节


漏洞描述:

在使用PHP-FastCGI执行php的时候,URL里面在遇到%00空字节时与FastCGI处理不一致,导致可在非php文件中嵌入php代码,通过访问url+%00.php来执行其中的php代码。如:http://local/robots.txt%00.php会把robots.txt文件当作php来执行。

影响版本:

nginx 0.5.*

nginx 0.6.*

nginx 0.7 <= 0.7.65

nginx 0.8 <= 0.8.37

漏洞利用:

1.上传经过处理的包含php一句话木马的图片文件.

2.访问http://target.com/pathtopic/nginx.jpg%00.php获得shell

修复方案:

升级Nginx

 

0x04 CVE-2013-4547


影响版本
nginx 0.8.41 – 1.5.6

测试版本
nginx 1.2.9

漏洞测试
1)访问到不可访问文件
nginx中添加配置

location /vinc/ {
    deny all;
}
[root@vincent nginx]# curl 172.16.100.161/vinc/1.txt -I
HTTP/1.1 403 Forbidden

创建一个包含空格的目录test

[root@vincent html]# ls -F
50x.html index.html test / vinc/

然后通过curl访问就可以

[root@vincent vinc]# curl "172.16.100.161/test /../vinc/1.txt" 
hello

2)将非PHP文件解析为PHP

Linux环境+PHP5.5.38


这里先说明下php从5.3.3版本开始引入php-fpm。
从5.3.9开始,php官方加入了一个配置”security.limit_extensions”,默认状态下只允许执行扩展名为”.php”的文件。如果发送给Fastcgi的文件非.PHP,则会报错Access denied.
所以测试前提是配置
security.limit_extensions =
然后重启php-fpm。
创建文件1.txt (需要注意末尾有空格)我们修改1.txt ,内容为PHP代码:

<?php
    phpinfo();
?>

我们构造一个伪造请求,请求的地址为”/1.txt \0.php”,注意其中的空格没有编码。然后可以看到phpinfo解析了。

所以利用前提
1)构造文件名末尾带空格的文件,所以在实际环境中基本是不可能的。
2)php-fpm配置了security.limit_extensions =

Windows环境+PHP5.6.32


这个漏洞在Windows环境下的利用价值就大大增强了
1)测试发现Windows下php-fpm默认就可以解析其他类型文件,不是默认只解析PHP文件。
2)Windows会自动忽略对应文件名后的空格,所以文件名末尾带空格的文件不再需要。
也就是说在Windows环境下,用户上传包含Webshell的头像文件,就可以直接Getshell了。

创建文件1.txt(末尾不带空格),我们修改1.txt ,内容为PHP代码:

<?php
    phpinfo();
?>

我们构造一个伪造请求,请求的地址为”/1.txt \0.php”,结果如下: