题记:

去年80sec爆出了一个“nginx的文件名解析漏洞”,当时虽觉得很重要,但并未深入了解(当时还是太浮)。今天验证Dicuz!1.5和nginx二次文件名解析漏洞时候才有机会详细了解。

正文:

一、验证Dicuz!1.5和nginx二次文件名解析漏洞


1)搭建环境

因为自己对nginx不了解,因此首先是搭建nginx和php的测试环境。经过搜索,在网上找到了配置指南(转载到本博客了),依照其操作,成功搭建完成。

nginx 解压缩命令 nginx文件解析漏洞_php

其后安装Discuz!1.5,中间出现两个小问题,后来解决了:

1、php.ini 中的 short_open_tag 需要设置为 On,否则无法继续安装;

2、打开 php.ini 把 ;extension=php_mysql.dll 前面的 ; 去掉,否则无法连接数据库;

3、提示错误,找不到“source/plugin/diy/template/forum/discuz.htm”,后来发现upload目录下文件上传不完整(太悲剧)。

2)漏洞验证

安装完成后,成功利用晴天小铸的"Discuz 1.5 配合NGINX二次解析爆路径BUG",爆出了绝对路径:

nginx 解压缩命令 nginx文件解析漏洞_文件名_02

3)漏洞分析

不过盯着相关代码看了好久也没看清原因所在(郁闷)。索性不看了,直接从漏洞名入手:dicuz!1.5的解析漏洞+nginx的解析漏洞。既然dicuz的没分析出来,那就分析nginx文件类型错误解析漏洞

首先测试搭建的环境(nginx1.0.2+php5.2.17+MySQL5.0)是否有该漏洞。我们输入http://192.168.16.116:81/Dicuz/robots.txt/1.php,可以看到:

nginx 解压缩命令 nginx文件解析漏洞_php_03

这就证明了搭建的环境确实存在Nginx文件名解析漏洞。到这里,针对二次解析的bug基本结束。

二、nginx文件类型错误解析漏分析

不过由于对nginx文件类型错误解析漏洞并不了解,因此我决定继续了解该漏洞的产生的详细原因。

经过搜索,在http://blog.sina.com.cn/s/blog_5efeeff10100l3c7.html中上看到了这段文字:

假设存在一个http://www.target.com/jpg.jpg,我们以如下的方式去访问:http://www.target.com/jpg.jpg/php.php,将会得到一个URI:/jpg.jpg/php.php,经过location指令,该请求将会交给后端的

fastcgi处理,nginx为其设置环境变量SCRIPT_FILENAME,内容为:/scripts/jpg.jpg/php.php。而在其他的webserver如lighttpd当中,我们发现其中的SCRIPT_FILENAME被正确的设置

为:/scripts/jpg.jpg,所以不存在此问题。后端的fastcgi在接受到该选项时,会根据fix_pathinfo配置决定是否对SCRIPT_FILENAME进行额外的处理,一般情况下如果不对fix_pathinfo进行

设置将影响使用PATH_INFO进行路由选择的应用,所以该选项一般配置开启。

Php通过该选项之后将查找其中真正的脚本文件名字,查找的方式也是查看文件是否存在,这个时候将分离出SCRIPT_FILENAME和PATH_INFO分别为:/scripts/jpg.jpg和php.php。最后,以

/scripts/jpg.jpg作为此次请求需要执行的脚本,攻击者就可以实现让nginx以php来解析任何类型的文件了。

结合安装nginx和php时的配置过程,我们可以看到配置中的确需要修改php.ini:

; CGI 设置
            cgi.force_redirect = 1
            cgi.fix_pathinfo = 1
            cgi.rfc2616_headers = 1

至此,终于真正认清nginx文件类型错误解析漏洞。

后记:

对于一个很有影响的漏洞,自己居然时隔一年多才花时间学习,可见自己的问题多严重,以后要改正。