解析漏洞
常见的web容器有iis、Nginx、Apache、Tomcat等,下面以IIS、Apache容器为例讲解。
IIS解析漏洞
当建立.asa、.asp格式的文件夹时,其目录下的任意文件都被IIS当做asp文件来解析。
例如:建立文件夹abc.asp,在abc.asp文件内新建一个文本文档test.txt,其内容<%=NOW()%>,然后再浏览器内访问。

IIS还有个经典漏洞,名为WebDav。
WebDav扩展了HTTP协议,在get、post等几个http标准方法以外填了一些新方法。在开启WebDav后,如果支持put、move、copy、delete等方法,可能会存在一些安全隐患。


Apache解析漏洞
在apache 1.x和2.x存在解析漏洞。

如图,访问的是1.php.rar,正常性况下应该会弹出下载框,但是却把1.php.rar当做php来解析。Apache在解析文件时,碰到不认识的扩展名会从后向前解析,直到碰到认识的扩展名为止。
在Apache安装目录下/conf/mime.types文件中有详细的扩展名列表。
有些开发人员在上传文件时,判断文件名是否是php、asp、aspx、asa、cer、aspx等脚本扩展名,如果是,则不允许上传,这时攻击者就可能上传1.php.rar、1.php.aaa等扩展名来绕过程序检测,并配合解析漏洞,获取到Webshell。?
PHP CGI解析漏洞
Nginx也曾被曝光过两个解析漏洞,比如,访问www.abc.com/1.jpg/1.php,此时的1.jpg会被当做PHP脚本来解析。如图所示。

此时的1.php是不存在的,却可以看到1.jpg已经按照PHP脚本来解析了。问题就出现在这个"1.php"上。这就意味着攻击者可以上传合法的“图片”(图片木马),然后再URL后面加上"/xxx.php",就可以获得网站的Webshell。
绕过上传漏洞
文件上传的基本流程相同,客户端使用JavaScript验证,服务器端采用随机数来重命名文件,以防止文件重复。
程序员在防止上传漏洞时可以分为以下两种。
- 客户端检测:客户端使用JavaScript检测,在文件未上传时,及对文件进行验证。
- 服务器端验证:服务器端脚本一般会检测文件的MIME类型,检测文件扩展名是否合法,有些甚至会检测文件中是否嵌入恶意代码。
在研究上传漏洞之前,首先来看两个小工具:中国菜刀和一句话图片木马。
“中国菜刀”这款软件是用来管理网站文件的,
客户端检测
很多程序员仅仅通过使用JavaScript来拒绝非法文件上传。这只能防止普通用户上传错误,很容易被攻击者突破客户端验证。下面是个实例。


?
针对客户端验证有非常多的绕过方法,下面说两种。
1.使用FireBug(或浏览器的开发人员工具,FireBug太老了)
?FireBug是一款开源的浏览器插件,它支持Firefox、Chrome等浏览器,可以调试HTML、JavaScript、Ajax、CSS等前端代码。
看看Firebug如何绕过客户端检测。
当单击“提交”按钮后,Form表单会触发onsubmit事件,onsubmit事件将会调用checkFile函数。checkFile函数将会检测文件扩展名是否合法,并返回一个布尔值。如果checkFile返回true,则表单提交。反之会提示“文件不合法”。知道这一点后,可以使用FireBug将onsubmit事件删除,这样就可以绕过JavaScript函数验证。

在本地构造可以突破JS的验证,但是不如FireBug方便。

这部分内容,我在XCTF的upload1中试了,在chrome的F12,事件响应中,将事件响应删除了。
然后上传.php文件,通过system()函数获得查看了网站目录,找到了flag.php。
2.中间人攻击
用FireBug是删除客户端的JS验证,而使用BurpSuite是按照正常的流程通过JS验证,然后对数据包做手脚。
首先把木马文件扩展名改为一张正常图片的扩展名,比如jpg,上传时使用BurpSuite拦截上传数据,再将扩展名jpg修改为php,就可以绕过客户端验证。
这里需要注意一点,请求头中Content-Length代表实体正文长度,如果修改filename可能代表长度也变了。如文件流中的filename=“xxser.jpg"修改为1.php,更好后正文实体少了4个字符,需要把content-length的长度减4,如不修改可能会导致上传失败。
强调:任何客户端验证都是不安全的,只能用来防止用户输入错误,减少服务器开销,只有服务器端验证才能真正防御攻击者。
服务器端检测
服务器验证分为很多种,主要包含以下几点。白名单与黑名单扩展名过滤、文件类型检测、文件重命名等操作,这样看起来无懈可击,不过还有一点就是解析漏洞。上传漏洞配合解析漏洞可以绕过大多数上传验证。
1.白名单与黑名单验证
1)黑名单过滤方式
这是种不安全的方式,通过上传文件后缀与黑名单进行匹配。攻击者可以使用很多方法来绕过黑名单检测。
- 攻击者可以从黑名单中找到开发人员忽略的扩展名,如cer
- 如果没有对扩展名进行大小写转换操作,那就意味着可以上传aSp、pHp这样的扩展名,而此类扩展名在windows平台依然会被Web容器解析。
- 在Windows系统下,如果文件名以”."或空格作为结尾,系统会自动除去”."或空格,用此特性也可以绕过黑名单验证,如上传“asp.”或者"asp "。
可见黑名单是非常不安全的,未知风险太多。
2)白名单过滤方式
白名单定义了允许上传的扩展名,有比黑名单更好的防御机制。虽然采用白名单的过滤方式可以防御未知风险,但是依然不能完全防御上传漏洞。以IIS 6.0为例,攻击者把pentest.asp;1.jpg上传,此时的文件名是jpg格式,酒而已通过验证,但那是iis 6.0会把该文件当做asp脚本执行,所以依然会被绕过。
白名单机制仅仅是防御上传漏洞的第一步。
2.MIME验证
MIME类型用来设定某种扩展名文件的打开方式,当具有该扩展名的文件被访问时,浏览器会自动使用指定的应用程序来打开。如GIF图片MIME为image/gif,CSS文件MIME类型为text/css。
上传时开发人员会对文件MIME类型做验证,php代码如下。

?上传PHP文件时,并使用BurpSuite拦截查看MIME类型,可以发现PHP文件的MIME类型为application/php,而在upload.php中会判断文件类型是否是image/jpg,显然无法通过验证。
在HTTP请求中的content-type更改为image/jpeg类型,这样可以通过程序验证,
3.目录验证
在文件上传时,程序通常允许用户将文件放到指定的目录中,然而有些开发人员为了让代码更“健壮”,通常会做一个操作,如果指定的目录存在,就将文件写入目录中,不存在则先建立目录,然后写入。代码如下:


这段代码是引发漏洞的关键点,因为HTML代码中有个隐藏标签<input type="hidden" name="Extension" value="up"/>,这是文件上传时默认的文件夹,而我们对此参数是可控的,比如将value改为pentest.asp,并提交上传一句话图片木马,如图所示

如果Web容器为IIS6.0,那么网页木马会被解析。
4.截断上传攻击
?截断上传攻击在ASP程序中最常见,下面看一段简单的ASP代码。

这两句代码非常简单,接受username值,并输出。?
?
 
?

修复上传漏洞
上传漏洞的形成原因主要有以下两点:
- ?目录过滤不严,攻击者可能建立畸形目录
- 文件未重命名,攻击者可能利用Web容器解析漏洞
如果把握好这两点,上传漏洞的风险就大大减少了。
?
这段代码对应以下三个步骤。
- 接收文件及其文件临时路径?
- 获取扩展名与白名单作对比,如果没有命令,程序退出。
- 对文件进行重命名。
以上步骤基本可以解决上传漏洞,但不是完全防御,还需要主义服务器配置、Web容器配置,安全是一个整体。
小结
我们可以知道,上传漏洞是完全可以避免的,需要做的是对路径进行验证、对文件进行随机重命名。
|