什么是文件的上传漏洞?如何预防?

前言:对于服务器的文件上传、修改及生成等功能的设计,应当特别谨慎。如果攻击者能将任意文件上传到服务器,那么对于服务器来说,无疑将是灭顶之灾。

文件上传漏洞概述

任意文件上传漏洞往往需要服务器提供一定的上传接口,如上传头像、上传附件、上传模板等。虽然大部分服务器都限制了上传文件的类型,但是,由于限制逻辑不严格,被绕过的情况时有发生。

什么是文件的上传漏洞?如何预防?_第1张图片

某网站采用PHP语言开发,攻击者在上传接口上传一个命名为“1.php”的文件,文件内容为“”。此时,网站返回文件存放的路径,例如http://aaa.com/upload/20211209.php。于是攻击者可以直接向该路径传递post参数,参数名为‘a’,参数内容可以是任意的php代码。服务器会接收并执行攻击者提交的php代码,于是攻击者可以通过执行系统命令完全控制这台服务器,也就实现了入侵。这也就是任意文件上传漏洞带来的最直接的危害。

那么,假设服务器限制了上传文件的类型,只允许上传“.jpg”“.png"“.zip" 等扩展名的文件,还可以造成危害吗?

攻击者可以尝试构造一个超大的文件上传,可能会占满服务器存储空间,导致其他用户无法正常上传文件。更有甚者,服务器无法正常写入Log 文件或其他数据库文件,导致网站无法工作,这种情况实际上是由上传漏洞导致了拒绝服务漏洞

另外,在一些无法上传脚本资源的场景下,假设网站允许上传“.html"或“.htm"扩展名的文件,攻击者还可以上传含有恶意JavaScript 代码的HTML文件,恶意的JavaScript 代码可能会盗取用户的Cookie信息。这种思路类似于存储型XSS漏洞。这种场景下,任意文件上传漏洞就引发了XSS漏洞。

由此可见,并不是服务器过滤了可解析的脚本资源就能万无一 失了,对上传文件的过滤始终是一个需要深入讨论的研究课题。接下来介绍几种经典的上传绕过场景。

常见的绕过场景

以头像上传为例,理论上应当只允许上传图片类型的文件。如果攻击者将服务器本身可执行的文件上传进来,就直接获取到了WebShell, 这个操作是十分危险的,这也是任意文件上传漏洞的致命之处。对于PHP 架构的服务器,攻击者往往想方设法上传以“.php"扩展名为结尾的文件,而对于ASP架构的服务器,攻击者往往会想办法上传以“.asp"扩展名为结尾的文件。过滤这种恶意的文件,核心点在于如何只允许图片上传,而拒绝其他类型的文件上传。这里有两个问题:这个“图片”怎样定义?服务器又怎么知道文件是不是图片?这两个问题的答案就是围绕任意文件上传漏洞攻防的全部历程。

1、文件头过滤绕过

针对计算机如何识别个文件是不是图片的问题,熟悉计算机的朋友此刻应当都会想到文件头这个概念。的确,一部分操作系统,尤其是Linux操作系统,是以文件头来判断文件类型的。那么如果以文件头来校验文件是不是图片可行吗?
理论上讲,服务器代码是支持校验文件头类型的。下面列出了几种常用图片类型的文件头,如下表所示。

常用图片的文件后缀与文件头
文件类型 文件扩展名 文件头十六进制

文件头实际内容

(.表示不可见字符)

PNG .png 89504E47 .PNG
GIF .gif 474946383961 GIF89a
JPEG .jpg FFD8FF ...

按照文件头防御的思路,只需要将这些文件的文件头加入白名单,不符合的一律禁止上传就可以了。实际上这种做法是有问题的,攻击者将 WebShell 添加一个“合法”文件头即可。因为服务器在判断 WebShell 能否解析时,主要看服务器本身的配置中是否含有所支持解析的扩展名,和文件头没有太大关系,对于ASP、 PHP、JSP等文件只需要在文件任意部位引入语法解析标签,如“<%......%>”“”等,即可实现上传WebShell。于是,这种防御方法以失败而告终

2、文件扩展名过滤绕过

服务器在判断 WebShell 能否解析时,主要看服务器本身的配置中是否含有所支持解析的扩展名。

只有对症下药才能治好病,那么,就从文件扩展名入手进行校验。

虽然针对文件扩展名的过滤是有效的,但是在落实到具体做法上,就曾经出现过问题。

早期的ASP架构下的网站,不少开发人员在上传接口的防御上是采用黑名单过滤的,也就是说,只拦截以“.asp”结尾的文件。于是,安全研究人员开始寻找新的突破口,在 IIS 默认解析的列表中,一个陌生的“.asa"扩展名被关注到,它具有和“.asp"同样的解析特性,只是名称不同,这也让当时asa的WebShell 流行了一段时间。同样地,“.cer” “.cdx" 扩展名在 IIS 服务器上也能够当作ASP脚本文件解析,这两个扩展名也曾经轰动一时。再到后来ASPX的出现,不少ASP的网站都支持ASP.NET扩展,也自然支持了".aspx" 扩展名。不同种类的扩展名“百花齐放”, 鲤鱼跃龙门式地绕过黑名单策略。同一时期,在PHP架构下的网站,由于Apache的默认配置,如果开发人员以删除注释的方法启用PHP扩展,则很有可能遭受.php3”“.php4"“.phtml”"扩展名的绕过上传攻击。以黑名单方式过滤上传文件暴露出来了很多缺陷。

所以,安全设计原则中有这样一条: 使用白名单胜过黑名单,对于头像上传接口来说,完全可以使用白名单来解决,可以只允许上传“.jpg”“.png"扩展名文件。

那对于一个本身就是附件上传,需要传任意扩展名的文件,又该如何处理呢?

什么是文件的上传漏洞?如何预防?_第2张图片

这时需要针对上传的目录对服务器解析路径进行配置,所上传的附件内容一律存储在同一个文件夹下。该文件夹应当仅用于存放上传附件,而严禁存放网站应用程序的代码文件。将该文件夹下的一切文件的访问响应Content-Type统一设置成二进制数据流(application/octet-stream),避免被当作可执行的ASP或PHP文件解析。

如果网站在上传功能接口还同时允许用户控制文件的存放目录,这时应当避免用户通过目录可穿越的方法将文件上传到其他目录中。 当时安全领城修复该漏洞时流行这样一句话:“目录可写但不可解析,可解析但不可写入”,正是体现了这一原则。

3、利用条件竞争机制绕过

白名单是安全的,但是是相对的安全, 安全需要在特定场景下讨论。在一些场景下,白名单也出现过危机。白名单具体实现的做法存在缺陷,安全性也会大打折扣。一个真实的案例来自白帽子felixk3y 在2014年1月提出的挖掘开源产品PHPCMS的思路。这个思路后面被大家称为竞争性绕过。

竞争性绕过的原理是这样的:如果一个网站虽然采用了 白名单的方式过滤上传文件,但是它在程序实现上先允许任何文件上传到服务器,再去判断文件扩展名,如果该文件的扩展名不属于白名单,则立即将其删除,那么这种方案也是可导致被攻击的。

felixk3y 在漏洞发现时做了这样的一段形象生动的描述: “猛兽来了,我们应该将其“绝杀”在门外,但是有些人非得把它放进屋内,才‘杀’ 之。你们难道不知道猛兽的嘴里可能叼了一个炸药包吗?”的确,在这个问题发现以前,很多开源CMS都是这样设计的。凭借着程序执行速度快,从上传到删除的时间差可能不到1s,所以长期没有人关注到其中的安全风险。但就是这1s的时间差,允许了攻击者通过多线程的方式发送大量请求,只要能够访问到1次WebShell,恶意代码就会被执行,即使WebShell被随即删除,也为时已晚。

4、文件解压场景绕过

竞争性问题扩展和延伸带来了新的安全风险。有些网站可能并不是将恶意文件本身存储在Web目录下,而是允许将压缩包内的文件解压出来,然后再删除恶意的文件,这种场景下同样也存在竞争性问题。总之,只要给了攻击者这个时间差,哪怕只有很短的一瞬间, 攻击者仍然有办法请求成功,实现攻击。

提到压缩包解压问题,知名安全研究员,phith0n曾经提出过一种思路:可以通过修改压缩包二进制字节,让压缩包解压过程中出错,但是出错前通过解压出来的一部分文件来获取 webShell。因为在解压出错以后,网站原有的逻辑会进入捕获异常的处理分支,开发人员往往会忽视对已经解压出来的文件合法性进行校验,而攻击者恰好可以控制解压释放文件的先后顺序,让解压出来的文件就是webshell 文件。

对于一些解压场景,攻击者还可以通过构造特殊的解压路径覆盖系统文件造成攻击。如 zipslip 攻击,通过构造压缩文件的文件名,在其中添加若干“../"以实现目录穿越的效果。而对于Linux系统,如果能够覆盖/etc/crontab文件,则可以通过添加计划任务实现远程命令执行。另外,在采用tar 进行压缩文件解压的场景下,若开启“-P” 选项,则支持以“/”开头的绝对路径和含有“../”的相对路径来控制解压路径,可以通过覆盖Web文件实现GetShell,亦可覆盖“/etc/crontab” 文件造成命令执行。

除了以上介绍的这些场景,白名单在服务器自身存在缺陷的情况下,也存在被绕过的可能。

任意文件上传漏洞防御

有关任意文件上传漏洞的防御,相信大家在仔细学习本节内容后,都会或多或少地有了一个基本的防御概念:要从扩展名入手、使用白名单而不是黑名单、要避免出现条件竞争的问题

此外,还可以通过配置服务器上传目录不可解析来进一步加固, 如条件允许,还可以使用独立的一台服务器存放上传的文件资源。同时避免由于服务器自身存在解析漏洞或由于配置问题出现的多余解析扩展名给攻击者带来可乘之机。

什么是文件的上传漏洞?如何预防?_第3张图片

注:文章参考《web漏洞解析与攻防实战》----机械工业出版社

你可能感兴趣的:(学习总结,安全,web安全)