freeBuf
文件上传漏洞详解
2021-06-30 22:20:22

上传漏洞定义

文件上传漏洞是指用户上传了一个可执行的脚本文件,并通过此脚本文件获得了执行服务器端命令的能力。这种攻击方式是最为直接和有效的,“文件上传” 本身没有问题,有问题的是文件上传后,服务器怎么处理、解释文件。如果服务器的处理逻辑做的不够安全,则会导致严重的后果。

上传漏洞危害

1.上传文件是web脚本语言,服务器的web容器解释并执行了用户上传的脚本,导致代码执行。

2.上传文件是病毒或者木马时,主要用于诱骗用户或者管理员下载执行或者直接 自劢运行;

3.上传文件是Flash的策略文件 crossdomain.xml,黑客用以控制Flash在该域 下的行为(其他通过类似方式控制策略文件的情况类似);

4.上传文件是病毒、木马文件,黑客用以诱骗用户或者管理员下载执行;

5.上传文件是钓鱼图片或为包含了脚本的图片,在某些版本的浏览器中会被作为脚本执行,被用于钓鱼和欺诈。 除此之外,还有一些不常见的利用方法,比如将上传文件作为一个入口,溢 出服务器的后台处理程序,如图片解析模块;或者上传一个合法的文本文件,其内容包含了PHP脚本,再通过"本地文件包含漏洞(Local File Include)"执行此脚本。

上传漏洞满足条件

首先,上传的文件能够被web容器解释执行。所以文件上传后所在的目录要是web容器所覆盖到的路径。

其次,用户能够从web访问这个文件。如果文件上传了,但用户无法通过web访问,或者无法得到web容器解释这个脚本,那么也不能称之为漏洞。 最后,用户上传的文件若被安全检查、格式化、图片压缩等功能改变了内容,则也可能导致攻击不成功。

上传漏洞产生的原因

一些web应用程序中允许上传图片,文本或者其他资源到指定的位置,文件上传漏洞就是利用这些可以上传的地方将恶意代码植入到服务器中,再通过 url 去 访问以执行代码.

造成文件上传漏洞的原因是:

1.服务器配置不当

2.开源编辑器上传漏洞

3.本地文件上传限制被绕过

4.过滤不严格被绕过

5.文件解析漏洞导致文件执行

6.文件路径截断

上传漏洞的原理

大部分的网站和应用系统都有上传功能,一些文件上传功能实现代码没有严格限制用户上传的文件后缀以及文件类型,导致允许攻击者向某个可通过web访问的目录上传任意PHP文件,并能够将这些文件传递给PHP解释器,就可以在 进程服务器上执行任意PHP脚本。

当系统存在文件上传漏洞时攻击者可以将病毒,木马,WebShell,其他恶意脚本或者是包含了脚本的图片上传到服务器,这些文件将对攻击者后续攻击提供便利。根据具体漏洞的差异,此处上传的脚本可以是正常后缀的PHP,ASP以及JSP脚本,也可以是篡改后缀后的这几类脚本。

上传漏洞绕过

1.客服端绕过

(1)客户端校验:

一般都是在网页上写一段 javascript 脚本,校验上传文件的后缀名,有白名单形式也有黑名单形式。判断方式:在浏览加载文件,但还未点击上传按钮时便弹出对话框,内容如:只允许上传.jpg/.jpeg/.png后缀名的文件,而此时并没有发送数据包。

(2)绕过方法:

1.通过火狐插件 NOscript 插件或者禁用 IE 中 JS 脚本;

2.通过 firbug 插件元素审核修改代码(如删除 onsubmit=”return checkFile()” 事件);

3.通过 firbug 元素审核 javascirpt 脚本中添加上传文件类型;

4.通过利用 burp 抓包改包,先上传一个 gif 类型的木马,然后通过 burp 将其改为asp/php/jsp 后缀名即可 注意:这里修改文件名字后,请求头中的 Content-Length 的值也要改。

2.服务端绕过

(1)黑名单扩展名绕过

黑名单检测:一般有个专门的 blacklist 文件,里面会包含常见的危险脚本文件。绕过方法:(1)找黑名单扩展名的漏网之鱼 - 比如 iis6.0 中的 asa 和 cer (2)可能存在大小写绕过漏洞 - 比如 aSp(iis6.0 中可以)和 pHp(只能在 小于 php5.3.39 中的 linux 中)之中 (3)能被web容器解析的文件其他扩展名列表:

jsp, jspx ,jspf

asp asa cer cdx,htr,xml,html

aspx,ashx,asmx,asax,ascx


(2)黑名单特殊后缀名绕过(利用难度高)

将Burpsuite截获的数据包中backlion.php名字改为 baclion.php4(php1,php2,php3,php4,php5), 前提条件是 http.conf 中设置 AddType application/x-httpd-php .php1(php 的版本小于等于 5.3.29 以下)

(3)单双重后缀名绕过

上传时将 Burpsuite 截的数据包中文件名 backlion.php(backlion.asa)改 为 backlion.pphphph(backlion.asasaa),那么过滤了第一个"php"字符串"后, 开头的'p'和结尾的'hp'就组合又形成了 php

(4)服务端 MIME 文件类型(Content-Type)绕过

MIME 的作用:

使客户端软件,区分不同种类的数据,例如web浏览器就是通过 MIME 类 型来判断文件是GIF图片,还是可打印的 PostScript 文件。web服务器使用 MIME 来说明发送数据的种类,web客户端使用 MIME 来说明希望接收到的数据种类,它是服务器用来判断浏览器传递文件格式的重要标记项。

常用的文件上传类型的 MIME 表: text/plain(纯文本) text/html(HTML 文档) text/javascript(js 代码) application/xhtml+xml(XHTML 文档) image/gif(GIF 图像) image/jpeg(JPEG 图像) image/png(PNG 图像) video/mpeg(MPEG 劢画) application/octet-stream(二迚制数据) application/pdf(PDF 文档) application/(编程语言) 该种语言的代码 application/msword(Microsoft Word 文件) message/rfc822(RFC 822 形式) multipart/alternative(HTML 邮件的 HTML 形式和纯文本形式,相同内容使 用不同形式表示) application/x-www-form-urlencoded(POST 方法提交的表单)multipart/form-data(POST 提交时伴随文件上传的表单)

绕过方法:上传对文件类型做了限制,可通过 burpsuit 将其他类文件类型 修改为如:Content-Type:image/gif 和 image/jpeg 等运行的文件类型。

3.白名单绕过:

(1)配合web容器的解析漏洞:

IIS中的目录解析漏洞和分号解析漏洞 :

将一句话木马的文件名 backlion.php,改成 backlion.php.abc(奇怪的不被解析的后缀名都 行)。首先, 服务器验证文件扩展名的时候,验证的是.abc,只要该扩展名符合服务器端黑白名单觃则,即可上传。

nginx 空字节漏洞 xxx.jpg%00.php 这样的文件名会被解析为php代码运行。

apache 的解析漏洞,上传如 a.php.rar a.php.gif 类型的文件名,可以避免 对于php文件的过滤机制,但是由于 apache 在解析文件名的时候是从右向左读,如果遇到不能识别的扩展名则跳过,rar 等扩展名是 apache 不能识别的, 因此就会直接将类型识别为 php,从而达到了注入php代码的目的。

(2)%00 截断上传绕过

通过抓包截断将 backlion.asp.jpg 后面的一个.换成%00 在上传的时候即 backlion.asp%00.jpg,当文件系统读到%00 时,会认为文件已经结束,从而将 backlion.asp.jpg 的内容写入到 backlion.asp 中,从而达到攻击的目的。%00 不是针对所有基于白名单的后缀名检查都能绕过,代码的实现过程中必须存在截 断上传漏洞,上传格式如下:bk.asp%00.jpg

(3)文件头内容检测绕过

文件头简介

不同的图片文件都有不同文件头,如: PNG:文件头标识 (8 bytes) 89 50 4E 47 0D 0A 1A 0A JPEG: 文件头标识 (2 bytes): 0xff, 0xd8 (SOI) (JPEG 文件标识) GIF:文件头标识 (6 bytes) 47 49 46 38 39(37) 61 上传文件的时候会检查上传文件是否合法,如图片文件是否文件头含有 gif89, 这里可以通过一句话图片木马生成工具 edjpgcom 戒者通过编辑器在木马内容基础上再加了一些文件信息,有点像下面的结构:

GIF89a <?php phpinfo(); ?>

带 waf 的文件上传绕过

1.上传文件 WAF 检查的位置

文件名:解析文件名,判断是否在黑名单内。文件内容:解析文件内容,判断是否为 webshell 文件目录权限 请求的 url Boundary 边界 MIME 文件类型 目前,市面上常见的是解析文件名,少数 WAF 是解析文件内容,比如长亭。

2.文件上传存在的上传特征

http 请求 Header 头部中的 Content-Type 存在以下特征:

multipart/form-data:表示该请求是一个文件上传请求 存在 boundary 字符串:作用为分隔符,以区分 POST 数据 POST 的内容存在以下特征: Content-Disposition name filename POST 中的 boundary 的值就是 Content-Type 的值在最前面加了两个--,除了 最后 标识结束的 boundary 最后标识结束的 boundary 最后默认会多出两个--(测试时,最后一行的 boundary 删掉也能成功上传)。

3.绕过 WAF 文件上传的方法

(1)填充垃圾数据绕过

有些主机 WAF 软件为了不影响web服务器的性能,会对校验的用户数据设置 大小上限,比如 1M。此种情况可以构造一个大文件,前面 1M 的内容为垃圾内 容,后面才是真正的木马内容,便可以绕过 WAF 对文件内容的校验;' Content-Type 类型数据后添加垃圾数据:

Content-Type: image/jpeg

a=11111111111111111111111111111111111111111111111111111111

GIF89a

<?php phpinfo(); ?>

当然也可以将垃圾数据放在数据包最开头,这样便可以绕过对文件名的校验。

------WebKitFormBoundaryYijPw9QB0WlswSL2

a=111111111111111111111111111111111111111111111111111111111111111111111               

Content-Disposition: form-data; name="file_x"; filename="bk.jpg"

Content-Type: image/jpeg

1625060824_60dc75d82271466d0d09b.png!small?1625060824089

(2)文件扩展名出回车绕过(只支持 php)

Content-Disposition: form-data; nAme="upfile"; filename="bk.ph

p" Content-Type: image/jpeg

或者

Content-Disposition: form-data; nAme="upfile"; file

name="bk.php"

Content-Type: image/jpeg

又或者

Content-Disposition: form-data; nAme="upfile"; fi

lename="bk.php" Content-Type: image/jpeg

1625060847_60dc75ef50cfd408fdb26.png!small?1625060847363

(3)filename 绕过

添加一个 finame 参数:

针对早期版本安全狗,可以多加一个 filename 在一个 Content-Disposition 中,存在多个 filename ,协议解析应该使用最 后的filename 值作为文件名。如果 WAF 解析到 filename="bk.jpg"认为解析 到文件名,结束解析,将导致被绕过。因为后端容器解析到的文件名是 bk.asp。

Content-Disposition: form-data; name="file1";

filename="bk.jpg";filename="bk.asp"

1625060799_60dc75bf1f531714f7b0c.png!small?1625060799102

(4)修改 Content-Disposition 字段值的大小写绕过

对这三个固定的字换:Content-Disposition,name,filename 比如 name 转换成 Name,Content-Disposition 转换成 content-disposition。 两年前,拿它绕过安全狗的上传,不知道现在如何。

Content-Disposition: form-data; name="upfile"; filename="bk.php"

改成

Content-Disposition: form-data; nAme="upfile"; filename="bk.php"

1625061353_60dc77e9d566463a9d323.png!small?1625061353834


(5)文件重命名绕过

如果 web 程序会将 filename 除了扩展名的那段重命名的话,那么还可以构造更多的点、符号等等。                 Content-Disposition: form-data;  name="  file1";

filename="bk....................................................................................................................

............................................................................................................asp"大概几百个点。

1625061516_60dc788c4539433f130a3.png!small?1625061516168

(6)删除 Content-Disposition 值的 form-data 绕过

有的 WAF 在解析的时候,认为 Content-Disposition 值一定是 form-data,造成绕过。两年前,拿它绕过安全狗的上传,不知道现在如何。

Content-Disposition: form-data; name="file1"; filename= "bk.php"

改为:

Content-Disposition: name="file1"; filename= "bk.php"

漏洞修复

1.服务器配置不当:

重新配置好服务器。服务器PUT方法配置不当。

2. 开源编辑器上传漏洞:

若新版编辑器已修复漏洞,请更新编辑器版本。

3.本地文件上传限制被绕过:

在服务器后端对上传的文件迚行过滤。

4.设置文件上传的目录设置为不可执行 

只要web容器无法解析该目录下面的文件,卲使攻击者上传了脚本文件,服务器本身也不会受到影响,因此这一点至关重要。

5.判断文件类型

在判断文件类型时,可以结合使用MIME Type、后缀检查等方式。在文件类型检查中,强烈推荐白名单方式,黑名单的方式已经无数次被证明是不可靠的。此外,对于图片的处理,可以使用压缩函数或者 resize 函数,在处理图片的同时破坏图片中可能包含的HTML代码。

6.使用随机数改写文件名和文件路径 

文件上传如果要执行代码,则需要用户能够访问到这个文件。在某些环境中,用户能上传,但不能访问。如果应用了随机数改写了文件名和路径,将极大地增加攻击的成本。再来就是像 shell.php.rar.rar 和 crossdomain.xml 这种文件,都将因为重命名而无法攻击。

7.单独设置文件服务器的域名

由于浏览器同源策略的关系,一系列客户端攻击将失效,比如上传 crossdomain.xml、上传包含 Javascript 的 XSS 利用等问题将得到解决。

本文为 独立观点,未经允许不得转载,授权请联系FreeBuf客服小蜜蜂,微信:freebee2022
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
文章目录