文件上传漏洞

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

文件上传功能本身是一个正常业务需求,对于网站来说,很多时候也确实需要用户将文件上传到服务器。所以“文件上传”本身没有问题,但有问题的是文件上传后,服务器怎么处理、解释文件。如果服务器的处理逻辑做的不够安全,则会导致严重的后果。

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

  1. 上传文件是Web脚本语言,服务器的Web容器解释并执行了用户上传的脚本,导致代码执行
  2. 上传文件是Flash的策略文件crossdomain.xml,黑客用以控制Flash在该域下的行为(其他通过类似方式控制策略文件的情况类似)
  3. 上传文件是病毒、木马文件,黑客用以诱骗用户或管理员下载执行
  4. 上传文件是钓鱼图片或为包含了脚本的图片,在某些版本的浏览器中会被作为脚本执行,被用于钓鱼和诈骗

在大多数情况下,文件上传漏洞一般是指“上传Web脚本能够被服务器解析”的问题,也就是通常所说的webshell的问题。要完成这个攻击,要满足如下几个条件:

  1. 首先,上传的文件能够被Web容器解释执行。所以文件上传后所在的目录要是Web容器所覆盖的路径。
  2. 其次,用户能够从Web上访问这个文件。如果文件上传了,但用户无法通过Web访问,或者无法使得Web容器解释这个脚本,那么也不能称之为漏洞。
  3. 最后,用户上传的文件若被安全检查、格式化、图片压缩等功能改变了内容,则也可能导致攻击不成功。

 

绕过文件上传检查功能

在文件上传文件的检查中,很多应用都是通过判断文件名后缀的方法来验证文件的安全性的。但是在某些时候,如果攻击者手动修改了上传过程的POST包,在文件名后添加一个%00字节,则可以截断某些函数对文件名的判断。因为在许多语言的函数中,比如在C、PHP等语言的常用字符串处理中,0x00被认为是终止符。受此影响的环境有Web应用和一些服务器。比如应用原本只允许上传JPG图片,那么可以构造文件名(需要修改POST包)为xxx.php[\0].JPG, 其中[\0]为十六进制的0x00字符,.JPG绕过了应用的上传文件类型判断;但对于服务器端来说,此文件因为0字节截断的关系,最终却变成xxx.php

除了常见的检查文件名后缀的方法外,有的应用还会通过判断上传文件的文件头来验证文件的类型。在正常情况下,通过判断前10个字节,基本上就能判断出一个文件的真实类型。浏览器的MIME Sniff功能实际上也是通过读取文件的前256个字节,来判断文件的类型。因此,为了绕过应用中类似MIME Sniff的功能,常见的攻击技巧是伪造一个合法的文件头,而将真实的PHP等脚本代码附在合法的文件头后,但仍需要通过PHP来解释此图片文件才行(若上传文件的后缀是.JPG,则Web Server很可能会将此文件当做静态文件解析,而不会调用PHP解释器,攻击的条件无法满足)。

 

文件解析问题

Apache文件解析问题

Apache对于文件名的解析是从后往前解析的,直到遇见一个Apache认识的文件类型为止。比如:

phpshell.php.rar.rar.rar.rar

因为Apache不认识rar这个文件类型(在Apache的mime.types文件中定义了它所认识的文件类型),所以会一直遍历后缀到.php,然后认为这是一个PHP类型的文件。

Apache的这个特性,很多工程师在写应用的时候并不知道,导致写出的安全检查功能可能会存在缺陷。比如.rar是一个合法的上传需求,在应用里只判断文件的后缀是否是.rar,最终用户上传的文件是phpshell.php.rar.rar.rar.rar,从而导致脚本被执行。

 

IIS文件解析问题

IIS 6 在处理文件解析时,也出过一些漏洞。前面提到的0x00字符截断文件名,在IIS和Windows环境下曾经出现过非常类似的漏洞,不过截断的字符变成了分号“;”。

当文件名为abc.asp;xyz.jpg时,IIS 6 会将此文件解析为abc.asp,文件名被截断了,从而导致脚本被执行,比如:

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

会执行abc.asp,而不会管xx.jpg。

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

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

这个xyz.jpg会被当做ASP文件进行解析。

 

设计安全的文件上传功能

文件上传功能本身并没错,只是在一些条件下会被攻击者利用,从而成为漏洞。那么如何才能设计出安全的、没有缺陷的文件上传功能呢?根据攻击的原理,总结了一下几点:

1. 文件上传的目录设置为不可执行

只要Web容器无法解析目录下的文件,即使攻击者上传了脚本文件,服务器本身也不会受到影响,因此这点至关重要。很多大型的网站的上传应用,文件上传后会放到独立的存储上,做静态文件处理,一方面方便使用缓存加速,降低性能损耗;另一方面也杜绝了脚本执行的可能。

2. 判断文件类型

在判断文件类型时,可以结合使用MIME Type、后缀检查等方式。在文件类型检查中,强烈推荐白名单的方式,黑名单的方式已经无数次证明是不可靠的。此外,对于图片的处理,可以使用压缩函数或者resize函数,在处理图片的同时破坏图片中可能包含的HTML代码。

3. 使用随机数改写文件名和文件路径

文件上传如果要执行代码,则需要用户能够访问到这个文件。在某些环境中,用户能上传,但不能访问。如果应用使用随机数改写了文件名和路径,将极大地增加攻击的成本。

4. 单独设置文件服务器的域名

由于浏览器同源策略的关系,一系列客户端攻击将失效,比如上传cossdomain.xml、上传包含JavaScript的XSS利用等问题将得到解决。但能否如此设置,还需要看具体的业务环境。

 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值