题记:
去年80sec爆出了一个“nginx的文件名解析漏洞”,当时虽觉得很重要,但并未深入了解(当时还是太浮)。今天验证Dicuz!1.5和nginx二次文件名解析漏洞时候才有机会详细了解。
正文:
1)搭建环境
因为自己对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",爆出了绝对路径:
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文件名解析漏洞。到这里,针对二次解析的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文件类型错误解析漏洞。
后记:
对于一个很有影响的漏洞,自己居然时隔一年多才花时间学习,可见自己的问题多严重,以后要改正。