参考文章
文件上传漏洞是web安全中经常用到的一种漏洞形式。是对数据与代码分离原则的一种攻击。上传漏洞顾名思义,就是攻击者上传了一个可执行文件如木马,病毒,恶意脚本,WebShell等到服务器执行,并最终获得网站控制权限的高危漏洞。
程序员在开发任意文件上传功能时,并未考虑文件格式后缀的合法性校验或者是否只在前端通过js进行后缀检验。这时攻击者可以上传一个与网站脚本语言相对应的恶意代码动态脚本,例如(jsp、asp、php、aspx文件后缀)到服务器上,从而访问这些恶意脚本中包含的恶意代码,进行动态解析最终达到执行恶意代码的效果,进一步影响服务器安全。
一般来说文件上传过程中检测部分由客户端javascript检测、服务端Content-Type类型检测、服务端path参数检测、服务端文件扩展名检测、服务端内容检测组成。但这些检测并不完善,且都有绕过方法。
多见于头像上传处
使用mentra的firebug查找元素,或F12
绕过方法:
禁用javasrcipt即可
检测原理:
后端获取http请求包的Content-Type参数,判断上传文件类型
绕过方法:
抓包将content-type改为允许上传类型格式,即可成功上传
检测原理:
使用getimagesize()函数来获取文件的MIME类型,此时检测的不是数据包中的content-type,而是图片的文件头,常见的图片文件头如下:
gif(GIF89a) : 47 49 46 38 39 61
jpg、jpeg : FF D8 FF
png : 89 50 4E 47 0D 0A
绕过方法:
当上传php文件时,可以使用winhex、010editor等十六进制处理工具,在数据最前面添加图片的文件头,从而绕过检测
检测原理:
使用扩展名黑名单来限制上传文件类型
绕过方法:
1)使用一些特殊扩展名来绕过
php可以用php3、php4、php5代替
2)大小写混淆绕过
3)在文件名加.
(空格,点,空格),利用windows特性绕过
4)在文件名加::$data
绕过
检测原理:
要求只能是特定扩展名的文件才能上传
绕过方法:
使用%00截断文件名来上传,(注意:GET型可以对%00自动解码,但POST型不能,需要在二进制中修改)
如果目标还存在文件包含漏洞,那么就可以上传图片马再文件包含来拿shell
检测原理:
在后端处理上传的文件时,会将将文件中的敏感字符替换掉。
参考代码
$path = "./uploads";
$content = file_get_contents($_FILES['myfile']['tmp_name']);
$content = str_replace('?', '!', $content);
$file = $path . '/' . $_FILES['myfile']['name'];
if (move_uploaded_file($_FILES['myfile']['tmp_name'], $file)) {
file_put_contents($file, $content);
echo 'Success!
';
} else {
echo 'Error!
';
}
?>
绕过方法:
根据实际过滤的字符来判断,(一般不会限制所有敏感字符,因为还要兼顾图片上传)
检测原理:
后端调用了php的GD库,提取了文件中的图片数据,然后再重新渲染,这样图片中插入的恶意代码就会被过滤掉了
绕过方法:
比较过滤前后文件内容,一般不会全部过滤。
比较使用php-gd转换之前和之后的gif图像,并搜索它们之间的任何相似性,因此,如果我在原始文件中找到相似的部分,则在使用php-gd转换后也保留了该部分然后我可以在那部分注入我的PHP代码并获得RCE
该漏洞形成逻辑:
网站允许上传文件,然后检查上传文件是否包含webshell、是否是指定的文件类型。如果不是,那么删除该文件。在删除之前访问上传的php文件,从而执行上传文件中的php代码。
绕过方法:
先进行文件上传,后进行判断与删除。利用时间差进行webshell上传。
竞争条件代码举例:
fputs(fopen('shell.php','w'),'');
?>
判断是否删除
import requests
while true:
requests.get(”路径“)