新冠确诊阳性后的第二篇博客,一文带你学习文件上传漏洞
- 1.什么是文件上传漏洞
- 2.不要使用黑名单规定上传文件类型
- 3.绕过文件上传检查功能
- 4.Apache文件解析问题
- 5.IIS文件解析问题
- 6.设计安全的文件上传功能
1.什么是文件上传漏洞
文件上传漏洞是指用户上传了一个可执行的脚本文件,并通过此脚本文件获得了执行服务器端命令的能力。这种攻击方式是最为直接和有效的,有时候几乎没有什么技术门槛。
在大多数情况下,文件上传漏洞一般都是指“上传Web脚本能够被服务器解析”的问题,也就是通常所说的webshell的问题
2.不要使用黑名单规定上传文件类型
FCKEditor是一款非常流行的富文本编辑器,为了方便用户,它带有一个上传文件功能,但是这个功能却出过许多次漏洞。
它是通过检查文件的后缀来确定是否安全的。代码如下:
$Config['AllowedExtensions']['File'] = array() ; //允许上传的类型
$Config['DeniedExtensions']['File'] =
array('php', 'php3', 'php5', 'phtml', 'asp', 'aspx', 'ascx', 'jsp', 'cfm', 'cfc', 'pl', 'bat', 'e
xe', 'dll', 'reg', 'cgi') ; //禁止上传的类型
以这个黑名单为例,如果我们上传后缀为php2、php4、inc、pwml、asa、cer等的文件,都可能导致发生安全问题。
这就引发了很大的安全隐患!
3.绕过文件上传检查功能
在针对上传文件的检查中,很多应用都是通过判断文件名后缀的方法来验证文件的安全性的。但是在某些时候,如果攻击者手动修改了上传过程的POST包,在文件名后添加一个%00
字节,则可以截断某些函数对文件名的判断。
在许多语言的函数中,比如在C、PHP等语言的常用字符串处理函数中,
0x00
被认为是终止符🍟
比如应用原本只允许上传JPG图片,那么可以构造文件名(需要修改POST包)为xxx.php[\0].JPG
,其中[\0]为十六进制的0x00字符,.JPG绕过了应用的上传文件类型判断;但对于服务器端来说,此文件因为0字节截断的关系,最终却会变成xxx.php
除了常见的检查文件名后缀的方法外,有的应用,还会通过判断上传文件的文件头来验证文件的类型
比如一个JPG文件,其文件头是:
常见的攻击技巧是伪造一个合法的文件头,而将真实的PHP等脚本代码附在合法的文件头之后
4.Apache文件解析问题
在Apache 1.x、2.x中,对文件名的解析就存在以下特性。
Apache对于文件名的解析是从后往前解析的,直到遇见一个Apache认识的文件类型为止。比如:
Phpshell.php.rar.rar.rar.rar.rar
因为Apache不认识.rar
这个文件类型,所以会一直遍历后缀到.php
,然后认为这是一个PHP类型的文件。
Apache的这个特性,很多工程师在写应用时并不知道,即便知道,可能有的工程师也会认为这是Web Server该负责的事情。如果不考虑这些因素,写出的安全检查功能可能就会存在缺陷。比如.rar
是一个合法的上传需求,在应用里只判断文件的后缀是否是.rar
,最终用户上传的是phpshell.php.rar.rar.rar
,从而导致脚本被执行。
5.IIS文件解析问题
前面提到的0x00字符截断文件名,在IIS和Windows环境下曾经出过非常类似的漏洞,不过截断字符变成了分号“;
”
例如:当文件名为abc.asp; xx.jpg
时,IIS 6会将此文件解析为abc.asp
,文件名被截断了,从而导致脚本被执行
除此漏洞外,在IIS 6中还曾经出过一个漏洞,因为处理文件夹扩展名出错,导致将/*.asp/
目录下的所有文件都作为ASP文件进行解析。比如:
http://www.target.com/path/xyz.asp/abc.jpg
这个abc.jpg
,会被当做ASP文件进行解析,这很危险!
谈到IIS,就不得不谈在IIS中,支持PUT功能所导致的若干上传脚本问题
在IIS中,如果目录支持写权限,同时开启了WebDav,则会支持PUT方法,再结合MOVE方法,就能够将原本只允许上传文本文件改写为脚本文件,从而执行webshell。MOVE能否执行成功,取决于IIS服务器是否勾选了“脚本资源访问”复选框
一般要实施此攻击过程,攻击者应先通过OPTIONS方法探测服务器支持的HTTP方法类型,如果支持PUT,则使用PUT上传一个指定的文本文件,最后再通过MOVE改写为脚本文件。
- 第一步:通过OPTIONS探测服务器信息。
返回:
- 第二步:上传文本文件。
返回:
- 第三步:通过MOVE改名。
返回:
修改成功!
6.设计安全的文件上传功能
文件上传的目录设置为不可执行:🍟
只要Web容器无法解析该目录下的文件,即使攻击者上传了脚本文件,服务器本身也不会受到影响,因此此点至关重要。在实际应用中,很多大型网站的上传应用,文件上传后会放到独立的存储上,做静态文件处理,一方面方便使用缓存加速,降低性能损耗;另一方面也杜绝了脚本执行的可能。但是对于一些边边角角的小应用,如果存在文件上传功能,则仍需要多加关注。
判断文件类型:🙌
在判断文件类型时,可以结合使用MIME Type、后缀检查等方式。在文件类型检查中,强烈推荐白名单的方式。此外,对于图片的处理,可以使用压缩函数或者resize函数,在处理图片的同时破坏图片中可能包含的HTML代码。
使用随机数改写文件名和文件路径:🥯
文件上传如果要执行代码,则需要用户能够访问到这个文件。在某些环境中,用户能上传,但不能访问。如果应用使用随机数改写了文件名和路径,将极大地增加攻击的成本。与此同时,像shell.php.rar.rar这种文件,或者是crossdomain.xml这种文件,都将因为文件名被改写而无法成功实施攻击。
单独设置文件服务器的域名:👌
由于浏览器同源策略的关系,一系列客户端攻击将失效,比如上传crossdomain.xml、上传包含JavaScript的XSS利用等问题将得到解决。但能否如此设置,还需要看具体的业务环境。