[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 的特征。

不过这确实会被服务端当作一个图片文件,因此访问对应路径也不会直接执行。

可以使用之前的文件包含漏洞来执行。

成功执行。