0x00 Unsafe file upload:不安全的文件上传
许多 Web 应用系统需要文件上传功能,比如注册时要求自定义头像。
如果后台未对上传文件做充分的检查,可能导致恶意文件上传,比如包含 PHP webshell 的图片马。
设计文件上传功能时,一定要考虑:
- 验证文件类型、后缀、大小;
- 验证文件上传方式;
- 对文件再次进行特殊的格式化(重命名、压缩等);
- 隐藏文件上传后存储的路径;
- ……
靶场提供了三个简单案例。
0x01 Client Check
意思是对上传文件的校验工作完全在客户端进行,服务端对任何文件照单全收。
查看源码:
<script>
function checkFileExt(filename)
{
var flag = false; //状态
var arr = ["jpg","png","gif"];
//取出上传文件的扩展名
var index = filename.lastIndexOf(".");
var ext = filename.substr(index+1);
//比较
for(var i=0;i<arr.length;i++)
{
if(ext == arr[i])
{
flag = true; //一旦找到合适的,立即退出循环
break;
}
}
//条件判断
if(!flag)
{
alert("上传的文件不符合要求,请重新选择!");
location.reload(true);
}
}
</script>
前端限制。于是前端禁用脚本或者抓包改包都可以。

访问对应路径发现成功执行:

0x02 MIME Type
现在选择非图片(指非图片格式后缀)文件时不会拦截,但是上传时会被服务端拦截。
服务端这次检验了上传文件的后缀。
MIME(Multipurpose Internet Mail Extensions),指多用途互联网邮件扩展类型。MIME 是设定某种扩展名的文件用一种应用程序来打开的方式类型,当该扩展名文件被访问时,浏览器会自动使用指定应用程序来打开。MIME 多用于指定一些客户端自定义的文件名,以及一些媒体文件打开方式。MIME 一般分为两个部分,前半部分指大类别,后半部分指具体类型。
常见的 MIME 类型有
- 普通文本 .txt:text/plain
- RTF 文件 .rtf:application/rtf
- GIF 图片 .gif:image/gif
- JPEG 图片 .jpeg:image/jpeg
查看源码可知服务端允许的 MIME 类型。
if(isset($_POST['submit'])){
// var_dump($_FILES);
$mime=array('image/jpg','image/jpeg','image/png');//指定MIME类型,这里只是对MIME类型做了判断。
$save_path='uploads';//指定在当前目录建立一个目录
$upload=upload_sick('uploadfile',$mime,$save_path);//调用函数
if($upload['return']){
$html.="<p class='notice'>文件上传成功</p><p class='notice'>文件保存的路径为:{$upload['new_path']}</p>";
}else{
$html.="<p class=notice>{$upload['error']}</p>";
}
}
然而上传 .php 文件时的 MIME 为 application/octet-stream,需要抓包改一下:

访问对应路径可得上述相同结果。
0x03 getimagesize()
getimagesize() 函数会检查文件头部的字节,因此仅仅修改 MIME Type 是行不通的了。
仍旧是抓包改包,不过文件头部放个 .gif 的特征。

不过这确实会被服务端当作一个图片文件,因此访问对应路径也不会直接执行。
可以使用之前的文件包含漏洞来执行。

成功执行。
更多文章请关注《万象专栏》
转载请注明出处:https://www.wanxiangsucai.com/read/cv9373