文件上传漏洞简介
什么是文件上传漏洞?
Web应用程序通常都会带有文件上传的功能,如在BBS中上传图片、视频,在OA系统或者ERP系统中发布Word文档等,只要 Web应用程序允许用户上传文件,就可能存在文件上传漏洞的威胁。
文件上传漏洞一般是由于开发者对用户文件上传逻辑的控制不足或者处理缺陷,从而导致的用户可以越过其本身权限向服务器上上传可执行的动态脚本文件。这里上传的文件可以是木马、病毒、恶意脚本或者WebShell等。这种攻击方式是最为直接和有效的,“文件上传”本身没有问题,有问题的是文件上传后,服务器怎么处理、解释上传的文件。如果服务器的处理逻辑做的不够安全,则会导致严重的后果。
文件上传漏洞本身就是一个危害巨大的攻击手段,WebShell属于文件上传漏洞中的一种攻击手段。大多数的上传漏洞被利用后攻击者都会留下WebShell以方便后续进入系统。攻击者在受影响系统中放置或者插入WebShell后,可通过该WebShell更轻松,更隐蔽的在服务中为所欲为。
WebShell就是以asp、php、jsp或者cgi等网页文件形式存在的一种命令执行环境,也可以将其称之为一种网页后门。攻击者在入侵了一个网站后,通常会将这些asp或php后门文件与网站服务器web目录下正常的网页文件混在一起,然后使用浏览器来访问这些后门,得到一个命令执行环境,以达到控制网站服务器的目的(可以上传下载或者修改文件,操作数据库,执行任意命令等)。
WebShell后门隐蔽较性高,可以轻松穿越防火墙,访问WebShell时不会留下系统日志,只会在网站的web日志中留下一些数据提交记录,没有经验的管理员不容易发现入侵痕迹。攻击者可以将WebShell隐藏在正常文件中并修改文件时间增强隐蔽性,也可以采用一些函数对WebShell进行编码或者拼接以规避检测。除此之外,通过木马的小马(一行代码)来提交功能更强大的大马可以更容易通过应用本身的检测。
<?php eval($_POST['code']); ?>
就是一个最常见最原始的小马。文件上传漏洞攻击原理
在 WEB应用中进行文件上传的方法是通过将form表单的类型设为 multipart/form-data,同时加入文件域,而后通过 HTTP 协议将文件内容发送到服务器,服务器端读取这个分段 (multipart) 的数据信息,并将其中的文件内容提取出来并保存的。通常,在进行文件保存的时候,服务器端处理程序会读取文件的原始文件名,并从这个原始文件名中得出文件的扩展名,而后随机为文件起一个新的文件名 ( 为了防止命名重复 ),并且加上原始文件的扩展名来保存到服务器上。大部分文件上传漏洞的产生是因为Web应用程序没有对上传文件的格式进行严格过滤,还有一部分是攻击者通过 Web服务器的解析漏洞来突破Web应用程序的防护,总结如下:
- 对于上传文件的后缀名(扩展名)没有做较为严格的限制,比如:一些应用在文件上传时根本没有进行文件格式检查,导致攻击者可以直接上传恶意文件。一些应用仅仅在客户端进行了检查,而在专业的攻击者眼里几乎所有的客户端检查都等于没有检查,攻击者可以通过NC,Fiddler等断点上传工具轻松绕过客户端的检查。一些应用虽然在服务器端进行了黑名单检查,但是却可能忽略了大小写,如将.php改为.Php即可绕过检查
- 对于上传文件的MIMETYPE(用于描述文件的类型的一种表述方法) 没有做检查
- 权限上没有对于上传的文件目录设置不可执行权限
- 对于Web Server 上传文件或者指定目录的行为没有做限制
文件上传漏洞攻击可以做什么?
- 上传文件可以是Web脚本语言(WebShell),服务器的Web容器一旦解释并执行了用户上传的脚本,会导致其中的代码执行,这些代码可以是当前语言环境支持的任何逻辑,危险性非常大,攻击者可通过这些网页后门(WebShell)执行命令并控制服务器
- 上传文件可以是Flash的策略文件 crossdomain.xml,黑客用以控制Flash在该域下的行为(其他通过类似方式控制策略文件的情况类似)
- 上传文件可以是病毒文件、木马文件,黑客用以诱骗用户或者管理员下载执行
- 上传文件可以是钓鱼图片或者包含了脚本的图片,在某些版本的浏览器中会被作为脚本执行,被用于钓鱼和欺诈
除此之外,还有一些不常见的利用方法,比如将上传文件作为一个入口,溢出服务器的后台处理程序,如图片解析模块;或者上传一个合法的文本文件,其内容包含了PHP脚本,再通过“本地文件包含漏洞(Local File Include)”执行此脚本,比如将 hack.php文件 改名为 hack.doc上传到服务器,再通过 PHP的include、include_once、require、require_once等函数包含执行等等。
文件上传漏洞攻击实操
利用“%00”或“0x00”截断符实现WebShell网页后门
一些Web应用虽然在服务器端对文件上传进行了白名单检查,却忽略了“%00”截断符,比如:应用本来只允许上传jpg图片,那么可以构造文件名为xxx.php%00.jpg,其中%00为十六进制的0x00字符,.jpg 骗过了应用的上传文件类型检测,但对于服务器来说,因为%00字符截断的关系(在上传的时候,当文件系统读到【0x00】时,会认为文件已经结束),最终上传的文件变成了xxx.php。利用00截断就是利用程序员在写程序时对文件的上传路径过滤不严格,产生0x00上传截断漏洞。
利用后缀名大小写
用于只将小写的脚本后缀名(如php)过滤掉的场合;例如:将调试工具截获的数据包中的文件名【hack.php】改为【hack.Php】。
使用双写后缀名
用于只将文件后缀名过滤掉的场合,例如“php”字符串过滤的;例如:上传时将截获的数据包中文件名【hack.php】改为【hack.pphphp】,那么过滤了第一个“php”字符串"后,开头的“p”和结尾的“hp”就组合又形成了【php】。
使用特殊后缀名
用于检测文件合法性的脚本有问题的场合;例如:将截获的数据包中【hack.php】名字改为【hack.php6】,或加个空格改为【evil.php 】等。
利用WebServer(应用服务器)自身的漏洞进行攻击
在一些常用的 Web server中,存在一些攻击者可以利用的解析漏洞如下列表:
- 老版本的IIS6中的目录解析漏洞,如果网站目录中有一个 /.asp/目录,那么此目录下面的一切内容都会被当作asp脚本来解析
- 老板本的IIS6中的分号漏洞:IIS在解析文件名的时候可能将分号后面的内容丢弃,那么我们可以在上传的时候给后面加入分号内容来避免黑名单过滤,如 a.asp;jpg
- 旧版Windows Server中存在空格和dot漏洞类似于 a.php. 和 a.php[空格] 这样的文件名存储后会被windows去掉点和空格,从而使得加上这两个东西可以突破过滤,成功上传,并且被当作php代码来执行
- nginx(0.5.x, 0.6.x, 0.7 <= 0.7.65, 0.8 <= 0.8.37)空字节漏洞 xxx.jpg%00.php 这样的文件名会被解析为php代码运行(fastcgi会把这个文件当php看,不受空字节影响,但是检查文件后缀的那个功能会把空字节后面的东西抛弃,所以识别为jpg)
- apache1.x,2.x的解析漏洞,上传如a.php.rar a.php.gif 类型的文件名,可以避免对于php文件的过滤机制,但是由于apache在解析文件名的时候是从右向左读,如果遇到不能识别的扩展名则跳过,rar等扩展名是apache不能识别的,因此就会直接将类型识别为php,从而达到了注入php代码的目的
文件上传漏洞攻击防御方法
收到如何防御文件上传漏洞,首先要考虑的是上传的文件能够被Web容器解释执行。所以文件上传后所在的目录要是Web容器所覆盖到的路径。其次用户能够从Web上访问这个文件。如果文件上传了,但用户无法通过Web访问,或者无法得到Web容器解释这个脚本,那么也不能称之为漏洞。最后用户上传的文件若被安全检查、格式化、图片压缩等功能改变了内容,则也可能导致攻击不成功。综上所述总结了防范文件上传漏洞常见的几种方法如下:
- 文件上传的目录设置为不可执行:只要Web容器无法解析该目录下面的文件,即使攻击者上传了脚本文件,服务器本身也不会受到影响,因此这一点至关重要。
- 判断文件类型:在判断文件类型时,可以结合使用 MIME Type、后缀检查等方式。在文件类型检查中,强烈推荐白名单方式,黑名单的方式已经无数次被证明是不可靠的。此外,对于图片的处理,可以使用给图片增加水印、使用压缩函数或者resize函数,在处理图片的同时破坏图片中可能包含的HTML代码。
- 使用随机数改写文件名和文件路径:文件上传如果要执行代码,则需要用户能够访问到这个文件。在某些环境中,用户能上传,但不能访问。如果应用了随机数改写了文件名和路径,将极大地增加攻击的成本。再来就是像shell.php.rar.rar和crossdomain.xml这种文件,都将因为重命名而无法攻击。
- 单独设置文件服务器的域名:由于浏览器同源策略的关系,一系列客户端攻击将失效,比如上传crossdomain.xml、上传包含Javascript的XSS利用等问题将得到解决。
- 系统开发阶段的防御:系统开发人员应有较强的安全意识,尤其是采用PHP语言开发系统。在系统开发阶段应充分考虑系统的安全性。对文件上传漏洞来说,最好能在客户端和服务器端对用户上传的文件名和文件路径等项目分别进行严格的检查。客户端的检查虽然对技术较好的攻击者来说可以借助工具绕过,但是这也可以阻挡一些基本的试探。服务器端的检查最好使用白名单过滤的方法,这样能防止大小写等方式的绕过,同时还需对%00截断符进行检测,对HTTP包头的content-type也和上传文件的大小也需要进行检查。
- 系统运行阶段的防御:系统上线后运维人员应有较强的安全意思,积极使用多个安全检测工具对系统进行安全扫描,及时发现潜在漏洞并修复。定时查看系统日志,web服务器日志以发现入侵痕迹。定时关注系统所使用到的第三方插件的更新情况,如有新版本发布建议及时更新,如果第三方插件被爆有安全漏洞更应立即进行修补。对于整个网站都是使用的开源代码或者使用网上的框架搭建的网站来说,尤其要注意漏洞的自查和软件版本及补丁的更新,上传功能非必选可以直接删除。除对系统自生的维护外,服务器应进行合理配置,非必选一般的目录都应去掉执行权限,上传目录可配置为只读。