Web应用程序通常会有文件上传的功能,只要Web应用程序允许上传文件,就有可能存在文件上传漏洞。
上传漏洞与SQL注入相比,其风险更大,如果Web应用程序存在上传漏洞,攻击者甚至可以直接上传webshell到服务器上。
0x01 解析漏洞
攻击者在利用上传漏洞时,通常会与Web容器的解析漏洞配合在一起。
1. IIS 解析漏洞
IIS6.0 在解析文件的时候存在以下两个解析漏洞。
① 当建立 *.asa、*.asp格式的文件夹时,其目录下的任意文件都将被IIS当做asp文件来解析。
② 当文件为 *.asp;1.jpg 时,IIS 同样会以asp脚本来执行。
WebDav 漏洞
WebDAV (Web-based Distributed Authoring and Versioning) 一种基于 HTTP 1.1协议的通信协议。它扩展了HTTP 1.1,在GET、POST、HEAD等几个HTTP标准方法以外添加了一些新的方法,使应用程序可对Web Server直接读写,并支持写文件锁定(Locking)及解锁(Unlock),还可以支持文件的版本控制。
攻击者可以通过PUT方法向服务器上传危险脚本文件。
2. Apache 解析漏洞
在Apache 1.x 和 Apache 2.x 中存在解析漏洞。
Apache 在碰到不认识的扩展名时,将会从后向前解析,直到碰到认识的扩展名为止。
比如:1.php.rar.xs.aa
Apache 首先会解析 aa 扩展名,如果不认识,将会解析 xs 扩展名,这样一直遍历到认识的扩展名为止,然后进行解析。
3. PHP CGI 解析漏洞
例如,访问 http://www.xxx.com/1.jpg/1.php
,此时 1.php 是不存在的,却可以看到 1.jpg。
这就意味着攻击者可以上传合法的图片木马,然后在 URL 后面加上 xxx.php
,就可以获得网站的WebShell。
在 PHP 的配置文件中有一个关键的选项: cgi.fi: x_pathinfo
。这个选项在某些版本中是默认开启的,在开启时 Nginx拿到文件路径(更专业的说法是URI)/test.jpg/test.php后,一看后缀是.php,便认为该文件是php文件,转交给php去处理。php一看/test.jpg/test.php不存在,便删去最后的/test.php,又看/test.jpg存在,便把/test.jpg当成要执行的文件了。
待填坑
0x02 绕过上传漏洞
程序员在开发Web应用程序时,一般都会涉及文件上传。文件上传的基本流程相同,客户端使用 Javascript 验证,服务器采用随机数来重命名文件,以防止文件重复。
程序员在防止上传漏洞时可以分为以下两种。
- 客户端检测:客户端使用 Javascript 检测,在文件未上传时,就对文件进行验证
- 服务器端检测:服务器脚本一般会检测文件的 MIME 类型,检测文件扩展名是否合法。
上传一句话木马。
PHP: <?php @eval($_POST['123']);?>
ASP: <%eval request("123")%>
ASP.NET: <%@ Page Language="Jscript"%><%eval(Request.Item['123'],'unsafe');%>
1. 客户端检测
很多程序员仅仅使用JavaScript来拒绝非法文件上传。这样验证是很不安全的。攻击者可以通过非常多的方法突破客户端验证。
- 使用插件禁用 JavaScript 脚本
- 使用 Burp Suite 绕过 JavaScript 验证
2. 服务器端检测
服务器端的验证更加安全。而服务器验证分为很多种,主要包含以下几点:白名单与黑名单扩展名过滤、文件类型检测、文件重命名等操作。但是解析漏洞配合上传漏洞,可以绕过大多数上传验证。
a. 白名单与黑名单验证
(1) 黑名单过滤方式
黑名单过滤方式很不安全:
- 攻击者可用从黑名单中找到开发人员忽略的扩展名
- 在windows平台对于扩展名是大小写不敏感的,可以通过大小写绕过黑名单
- 在windows系统中,如果文件名以
.
或者空格作为结尾时,系统会自动去除这些
(2) 白名单过滤方式
采用白名单的过滤方式可以防御未知风险,但是不能完全依赖白名单,因为白名单并不能完全防御上传漏洞。
配合使用解析漏洞可以绕过白名单过滤。
b. MIME 验证
MIME类型用来设定某种扩展名文件的打开方式,当具有该扩展名的文件被访问时,浏览器会自动使用指定的应用程序来打开。
GIF图片的 MIME 为 image/gif
。
使用 Burp Suite 可以绕过 MIME 验证。
c. 目录验证
在文件上传时,程序通常允许用户将文件放到指定的目录中,然而有些Web开发人员为了让代码更“健壮”,通常会做一个操作,如果指定的目录存在,就将文件写入目录中,不存在则先建立目录,然后写入。
d. 截断上传攻击
截断上传攻击在ASP程序中最常见。
0x00是十六进制表示方法,是ascii码为0的字符,在有些函数处理时,会把这个字符当做结束符。这个可以用在对文件类型名的绕过上。