var
flag =
false
;
var
str = document.getElementById(
"
file
"
).value;
str
= str.substring(str.lastIndexOf(
'
.
'
) +
1
);
var
arr =
new
Array(
'
png
'
,
'
bmp
'
,
'
gif
'
,
'
jpg
'
);
for
(
var
i=
0
;i<arr.length;i++
)
if
(str==
arr[i])
flag
=
true
;
if
(!
flag)
alert(
'
文件不合法!
'
);
return
flag;
</script>
</head>
<form action=
"
upload.php
"
method=
"
post
"
onsubmit=
"
checkFile()
"
enctype=
"
multipart/form-data
"
>
<input type=
"
file
"
name=
"
file
"
id=
"
file
"
/><br/>
<input type=
"
submit
"
value=
"
提交
"
name=
"
submit
"
/>
</form>
</body>
</html>
接收文件的脚本upload.php代码如下:
<?php
if(isset($_POST["submit"]))
$name = $_FILES['file']['name'];
$name = md5(date('Y-m-d h:m:s')).strrchr($name,".");
$size = $_FILES['file']['size'];
$tmp = $_FILES['file']['tem_name'];
move_uploaded_file($tmp,$name);
echo "文件上传成功!path:".$name;
1、可以用firebug将form表单中的onsubmit事件删除,这样就可以绕过验证。
2、使用Burp Suite:
1)先将木马文件的扩展名改为一张正常图片的扩展名,如1.php/asp ---> 1.jpg
2)上传时使用Burp Suite拦截数据包,将木马文件扩展名改为php就可绕过客户端验证。
注意:这里修改文件名字后,请求头中的Content-Length的值也要改
服务端检测
服务端分为6项:
黑名单与白名单验证
MIME验证
截断上传攻击
.htaccess文件攻击
检测文件内容
黑名单与白名单验证
黑名单过滤方式
<?php
$Blacklist = array('asp','php','jsp','php5','asa','aspx'); //黑名单
if(isset($_POST["submit"]))
$name = $FILES['file']['name']; //接收文件名
$extension = substr(strrchr($name, ".") , 1); //得到扩展名
$boo = false;
foreach($Blaklist as $key => $value)
if($value==$extension)
//迭代判断是否命中
$boo = true;
break; //命中后直接退出循环
if(!$boo)
//若没有被命中,则进行上传操作
$size = $_FILES['file']['size']; //接收文件大小
$tmp = $FILES['file']['temp_name']; //临时路径
move_uploaded_file($tmp, $name); //移动临时文件到当前文件目录
echo "文件不合法!!";
对于上面的过滤可以通过如下方法绕过:
从黑名单中找到web开发者忽略的扩展名,如:cer
没有对扩展名进行大小写转换,在window平台依然可以大小写绕过
在window下,若文件名以"."或者空格作为结尾,系统会自动去除"."与空格,
所以可以上传以“asp.”和“asp_”为扩展名的文件
0x00截断绕过
<?php
$WhiteList = array('rar','jpg','png','bmp','gif','jpg','doc');
if(isset($_POST["submit"]))
$name = $_FILES['file']['name'];
$extension = substr(strrchr($name,"."),1);
$boo = false;
foreach($WhiteList as $key => $value)
if($value==$extension)
$boo = true;
if($boo)
$size = $_FILES['file']['size'];
$tmp = $_FILES['file']['tmp_name'];
move_uploaded_file($tmp,$name);
echo "文件上传成功!<br/>path:".$name;
echo "文件不合法!";
绕过方法:
0x00截断绕过
此时若在iis6.0,则可以将木马名改为test.asp;1.jpg来上传,从而通过验证
配合解析漏洞
MIME验证
对文件MIME类型做验证的PHP代码如下:
<?php
if($_FILES['file']['type']==" image/jpeg")
$imageTempName = $_FILES['file']['tmp_name'];
$imageName = $_FILES['file']['name'];
$last = substr($imageName,strrpos($imageName,"."));
if(!is_dir("uploadFile"))
mkdir("uploadFile");
$imageName = md5($imageName).$last;
move_upload_file($imageTempName,"./uploadFile/".$imageName);
echo("文件上传成功! path = /uploadFile/$imageName");
echo("文件上传类型错误,请重新上传...");
exit();
未修改MIME类型,上传失败:
修改MIME类型,上传成功:
<form action="upload.php" method="post" enctype="multipart/form-data">
<input type="file" name="file" /><br/>
<input type="hidden" name="Extension" value="up" />
<input type="submit" value="提交" name="submit" />
</form>
</body>
</html>
服务端PHP接收文件的代码如下:
<?php
if($_FILES['file']['type']=="image/jpeg")
$imageTempName=$_FILES['file']['tmp_name'];
$imageName=$_FILES['file']['name'];
$last=substr($imageName,strrpos($imageName,"."));
if($last!=".jpg")
echo("mime error!<br/>");
$Extension=$_POST['Extension'];
if(!is_dir($Extension))
mkdir("./$Extension");
echo "mkidr $Extension succesfully"."<br/>";
$imageName=md5($imageName).$last;
move_uploaded_file($imageTempName,"./$Extension/".$imageName);
echo("upload ok! path = /$Extension/$imageName");
echo("type error...");
exit();
查看上传到了那个文件:
将文件改名:
.htaccess文件攻击
通过.htaccess文件调用php解析器去解析一个文件名中只要包含"haha"这个字符串的任意文件,论扩展名是什么(没有也行),都以php的方式来解析,.haccess文件代码如下
<FilesMatch "haha">
SetHandler application/x-httpd-php
</FilesMatch>
或者如下,上传一个文件名为evil.gif的图片马:
<FilesMatch "evil.gif">
SetHandler application/x-httpd-php
</FilesMatch>
除了上述的.htaccess文件攻击,还可以用.user.ini进行文件攻击
当中间键是以fastcgi运行的php都可以用这个方法,.user.ini能被动态加载,它也有两个配置项:
auto_append_file和auto_prepend_file,只要在.user.ini中添加auto_prepend_file=aa.jpg
这句话,就可以让其他php文件执行前自动包含aa.jpg,和require()类似。
1 使用大小写绕过(针对对大小写不敏感的系统如windows),如:PhP
2 使用黑名单外的脚本类型,如:php5
3 借助文件解析漏洞突破扩展名验证,如:test.jpg.xxx(apache解析漏洞)
4 借助系统特性突破扩展名验证,如:test.php_(在windows下下划线是空格,保存文件时下划线被吃掉剩下test.php)
5 双扩展名之间使用00截断,绕过验证上传恶意代码如:test.php%00.jpg
6 借助.htaccess文件上传恶意代码并解析。如:上传一个.htaccess文件,内容为AddTypeapplication/x-httpd-php .jpg,上传的jpg文件就可以当作php来解析
7 使用00截断,绕过后缀验证获取webshell(php<5.3.4+关闭GPC)
8 超长文件名截断上传(windows 258byte | linux 4096byte)
1 使用白名单限制可以上传的文件扩展
2 验证文件内容,使用正则匹配恶意代码限制上传
3 对上传后的文件统一随机命名,不允许用户控制扩展名
4 修复服务器可能存在的解析漏洞
5 严格限制可以修改服务器配置的文件上传如:.htaccess