文件上传就是通过流的方式将文件写到服务器上。
文件上传必须以POST提交表单。
表单中需要
文件上传漏洞是指用户上传了一个可执行的脚本文件,并通过此脚本文件获得了执行服务器端命令的能力。这种攻击方式是最为直接和有效的,“文件上传” 本身没有问题,有问题的是文件上传后,服务器怎么处理、解释文件。如果服务器的处理逻辑做的不够安全,则会导致严重的后果。
文件上传漏洞是指用户上传了一个可执行的脚本文件(php、jsp、xml、cer等文件),而WEB系统没有进行检测或逻辑做的不够安全。
文件上传功能本身没有问题,问题在于上传后如何处理及解释文件。
一般情况下,Web应用都会允许用户上传一些文件,如头像、附件等信息,如果Web应用没有对用户上传的文件进行有效的检查过滤,那么恶意用户就会上传一句话木马等Webshell,从而达到控制Web网站的目的。
存在文件上传功能的地方都有可能存在文件上传漏洞,比如相册、头像上传,视频、照片分享。论坛发帖和邮箱等可以上传附件的地方也是上传漏阔的高危地带,另外像文件管理器这样的功能也有可能被攻击者所利用。
这里上传的文件可以是木马,病毒,恶意脚本或者WebShell等。
首先,上传的文件能够被web容器解释执行。所以文件上传后所在的目录要是web容器所覆盖到的路径。
其次,用户能够从web访问这个文件。如果文件上传了,但用户无法通过web访问,或者无法得到web容器解释这个脚本,那么也不能称之为漏洞。 最后,用户上传的文件若被安全检查、格式化、图片压缩等功能改变了内容,则也可能导致攻击不成功。
一些web应用程序中允许上传图片,文本或者其他资源到指定的位置,文件上传漏洞就是利用这些可以上传的地方将恶意代码植入到服务器中,再通过 url 去 访问以执行代码.
造成文件上传漏洞的原因是:
1.服务器配置不当
2.开源编辑器上传漏洞
3.本地文件上传限制被绕过
4.过滤不严格被绕过
5.文件解析漏洞导致文件执行
6.文件路径截断
(1)客户端校验:
一般都是在网页上写一段 javascript 脚本,校验上传文件的后缀名,有白名单形式也有黑名单形式。判断方式:在浏览加载文件,但还未点击上传按钮时便弹出对话框,内容如:只允许上传.jpg/.jpeg/.png后缀名的文件,而此时并没有发送数据包。
(2)绕过方法:
1.通过火狐插件 NOscript 插件或者禁用 IE 中 JS 脚本;
2.通过 firbug 插件元素审核修改代码(如删除 οnsubmit=”return checkFile()” 事件);
3.通过 firbug 元素审核 javascirpt 脚本中添加上传文件类型;
4.通过利用 burp 抓包改包,先上传一个 gif 类型的木马,然后通过 burp 将其改为asp/php/jsp 后缀名即可 注意:这里修改文件名字后,请求头中的 Content-Length 的值也要改。
(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 等运行的文件类型。
(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
文件名:解析文件名,判断是否在黑名单内。文件内容:解析文件内容,判断是否为 webshell 文件目录权限 请求的 url Boundary 边界 MIME 文件类型 目前,市面上常见的是解析文件名,少数 WAF 是解析文件内容,比如长亭。
http 请求 Header 头部中的 Content-Type 存在以下特征:
multipart/form-data:表示该请求是一个文件上传请求
存在 boundary 字符串:作用为分隔符,以区分 POST 数据
POST 的内容存在以下特征: Content-Disposition name filename
POST 中的 boundary 的值就是 Content-Type 的值在最前面加了两个–,除了 最后 标识结束的 boundary 最后标识结束的 boundary 最后默认会多出两个–(测试时,最后一行的 boundary 删掉也能成功上传)。
(1)填充垃圾数据绕过
有些主机 WAF 软件为了不影响web服务器的性能,会对校验的用户数据设置 大小上限,比如 1M。此种情况可以构造一个大文件,前面 1M 的内容为垃圾内 容,后面才是真正的木马内容,便可以绕过 WAF 对文件内容的校验;’ Content-Type 类型数据后添加垃圾数据:
Content-Type: image/jpeg
a=11111111111111111111111111111111111111111111111111111111
GIF89a
当然也可以将垃圾数据放在数据包最开头,这样便可以绕过对文件名的校验。
------WebKitFormBoundaryYijPw9QB0WlswSL2
a=111111111111111111111111111111111111111111111111111111111111111111111
Content-Disposition: form-data; name="file_x"; filename="bk.jpg"
Content-Type: image/jpeg
(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
(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”
(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”
(5)文件重命名绕过
如果 web 程序会将 filename 除了扩展名的那段重命名的话,那么还可以构造更多的点、符号等等。 Content-Disposition: form-data; name=" file1";
filename="bk…
…asp"大概几百个点。
(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”
后端验证:采用服务端验证模式
后缀检测:基于黑名单,白名单过滤
MIME 检测:基于上传自带类型检测
内容检测:文件头,完整性检测
自带函数过滤:参考 uploadlabs 函数
自定义函数过滤:function check_file(){}
WAF 防护产品:宝塔,云盾,安全公司产品等