[Pikachu 靶场] 8-不安全文件上传
0x00 Unsafe file upload:不安全的文件上传
许多 Web 应用系统需要文件上传功能,比如注册时要求自定义头像。
如果后台未对上传文件做充分的检查,可能导致恶意文件上传,比如包含 PHP webshell 的图片马。
设计文件上传功能时,一定要考虑:
- 验证文件类型、后缀、大小;
- 验证文件上传方式;
- 对文件再次进行特殊的格式化(重命名、压缩等);
- 隐藏文件上传后存储的路径;
- ……
靶场提供了三个简单案例。
0x01 Client Check
意思是对上传文件的校验工作完全在客户端进行,服务端对任何文件照单全收。
查看源码:
前端限制。于是前端禁用脚本或者抓包改包都可以。
访问对应路径发现成功执行:
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.="文件上传成功
文件保存的路径为:{$upload['new_path']}
";
}else{
$html.="{$upload['error']}
";
}
}
然而上传 .php 文件时的 MIME 为 application/octet-stream,需要抓包改一下:
访问对应路径可得上述相同结果。
0x03 getimagesize()
getimagesize()
函数会检查文件头部的字节,因此仅仅修改 MIME Type 是行不通的了。
仍旧是抓包改包,不过文件头部放个 .gif 的特征。
不过这确实会被服务端当作一个图片文件,因此访问对应路径也不会直接执行。
可以使用之前的文件包含漏洞来执行。
成功执行。