文件上传漏洞
文件上传漏洞是指用户上传了一个可执行的脚本文件,并通过此脚本文件获得了执行服务器端命令的能力。常见场景是web服务器允许用户上传图片或者普通文本文件保存,而用户绕过上传机制上传恶意代码并执行从而控制服务器。显然这种漏洞是getshell最快最直接的方法之一,需要说明的是上传文件操作本身是没有问题的,问题在于文件上传到服务器后,服务器怎么处理和解释文件。
如果WEB应用在文件上传过程中没有对文件的安全性进行有效的校验,攻击者可以通过上传WEBshell等恶意文件对服务器进行攻击,这种情况下认为系统存在文件上传漏洞。
WebShell
最常见利用文件上传漏洞的方法就是上传网站木马(webshell)文件,
WEBSHELL又称网页木马文件,根据开发语言的不同又分为ASP木马、PHP木马、JSP木马等,该类木马利用了脚本语言中的系统命令执行、文件读写等函数的功能,一旦上传到服务器被脚本引擎解析,攻击者就可以实现对服务器的控制
上传检测流程
通常一个文件以HTTP协议进行上传时,将以POST请求发送至Web服务器,Web服务器接收到请求并同意后,用户与Web服务器将建立连接,并传输数据。客户端javascript校验(一般只校验文件的扩展名)服务端校验文件头content-type字段校验(image/gif)文件内容头校验(GIF89a)(前两种都属于MIME类型检验)目录路经检测(检测跟Path参数相关的内容)文件扩展名检测 (检测跟文件 extension 相关的内容)后缀名黑名单校验后缀名白名单校验自定义正则校验WAF设备校验(根据不同的WAF产品而定)
1 客户端校验
这一类的检测通常是在上传页面的含有专门检测文件的javascript代码,最常用的就是检测扩展名是否合法,有白名单校验也有黑名单形式的校验。由于JavaScript是在客户端执行的,那么这种校验是可以通过先上传文件,然后再通过burp抓包就修改来绕过的。
if(extension=="jpg"||extension=="JPG")//可以另行添加扩展名{objButton.disabled=false;//启用上传按钮objMSG.innerHTML="文件检测通过";}else{objButton.disabled=true;//禁用上传按钮objMSG.innerHTML="请选择正确的文件上传";}}
1.1 客户端校验的判断方式
如果在浏览文件页面,还未点击上传按钮就弹出来弹框(例如:只能上传.jpg/.png后缀名的文件),而此时我们还未和服务器进行交互,那么这样一般就是在客户端进行了校验
1.2 客户端校验的绕过方法
1 在上传的页面进行F12大法,修改js检测函数
2 将木马的后缀改为允许的类型,后再抓包进行修改
3 上传webshell.jpg.php 有的前端程序检查后缀的时候,前面符合就会通过
2 服务端检测
2.1 MIME类型检测
服务器端检测文件MIME类型可能的代码如下
<?phpif($_FILES['file']['type'] != "image/gif"){echo "Sorry, we only allow uploading GIF images";exit;}$uploaddir = './';$uploadfile = $uploaddir . basename($_FILES['file']['name']);if (move_uploaded_file($_FILES['file']['tmp_name'], $uploadfile)){echo "File is valid, and was successfully uploaded.\n";} else {echo "File uploading failed.\n";}?>
2.1.1MIME类型检测绕过方法:
配置Burp Suite代理进行抓包,将Content-Type修改为image/gif,或者其他允许的类型
然后在对应目录生成shell.jpg
2.2目录路径检测
上传的数据包中,如果存在path(或者其他名称)等能够操作上传路径的参数,修改该参数配合解析漏洞Get Webshell,该方法一般asp系统用比较多。
例如path参数为如下“upfile/”
,可以尝试修改为“upfile.asp/”
或者“upfile/1.asp/”
或者“upfile/1.asp;”
,注意观察返回的文件名。返回的文件名可能为:upfile/1.asp;.04117886.jpg
,满足IIS6.0解析漏洞。
2.3 文件扩展名检测
2.3.1 黑名单检测
黑名单的安全性比白名单低很多,服务器端,一般会有个专门的blacklist文件,里面会包含常见的危险脚本文件类型,例如:html | htm | php | php2 | hph3 | php4 | php5 | asp | aspx | ascx | jsp | cfm | cfcbat | exe | com | dll | vbs | js | reg | cgi | htaccess | asis | sh等等。黑名单则可以通过对关键函数的各类混淆变化来绕过。
<?phpfunction getExt($filename){//sunstr - 返回字符串的子串//strripos — 计算指定字符串在目标字符串中最后一次出现的位置(不区分大小写)return substr($filename,strripos($filename,'.')+1);}if($_FILES["file"]["error"] > 0){echo "Error: " . $_FILES["file"]["error"] . "<br />";}else{$black_file = explode("|","php|jsp|asp");//不允许上传的文件类型组$new_upload_file_ext = strtolower(getExt($_FILES["file"]["name"])); //取得被.隔开的最后字符串if(in_array($new_upload_file_ext,$black_file)){echo "文件不合法";die();}else{$filename = time().".".$new_upload_file_ext;if(move_uploaded_file($_FILES['file']['tmp_name'],"upload/".$filename)){echo "Upload Success";}}}?>
2.3.2白名单检测
仅允许指定的文件类型上传,比如仅允许上传jpg | gif | doc | pdf等类型的文件,其他文件全部禁止。
针对白名单检测,可以在满足要求的文件后插入木马脚本语句来绕过。
3 绕过方法
3.1 文件名大小写绕过
3.2 文件名双写绕过
3.3 名单列表绕过
3.4 不常见的扩展名
例如: PHP3、PHP4、PHP5
3.5 特殊文件名绕过
比如在发送的HTTP包中,将文件名改为”dama.asp.”
或者”dama.asp_”
(下划线为空格),这种命名方式在window系统里是不被允许的,所以需要在Burp Suite中抓包修改,上传之后,文件名会被window自动去掉后面的点或者空格,需要注意此种方法仅对window有效,Unix/Linux系统没有这个特性。
上传不符合windows文件命名规则的文件名
test.asp.test.asp(空格)test.php:1.jpgtest.php::$DATAshell.php::$DATA…….
3.60x00截断:
在许多语言的函数中,比如在C、PHP等语言的常用字符串处理函数中,0x00被认为是终止符。攻击者通常会利用该字符构造特殊的后缀名或目录来绕过白名单的限制。比如应用原本只允许JPG上传,攻击者修改POST包,构造文件名为xx.php[/0]JPG
,/0]
为16进制的0x00字符,.JPG绕过了应用的上传文件类型判断﹔但是对于服务端来说,由于有0x00字符,认为中止了,最终会认为读取的是xx.php文件。
操作方法:
上传dama.jpg,Burp抓包,将文件名改为dama.php%00.jpg,选中%00,进行url-decode。
3.7 冒号截断
冒号截断:冒号(“:”)是一个在系统中不能作为文件名的符号,在文件保存时会自动截断冒号后面的内容,住是某些文件保存函数中没有对其处理,可以尝试构造类似于1.php:1.jpg的文件绕过白名单检测。
3.8 .上传.htaccess文件绕过
--------------------------------------------------------------------------------
参考资料-奇安信社区Zxl2605