文件上传漏洞——文件上传检测汇总

文件上传检测分类

  • 任意上传
  • 前端JS检测
  • 文件扩展名检测
  • MIME-type检测
  • 文件头检测
  • 文件加载检测

1、任意上传概念:

  • 服务端脚本语言未对上传的文件进行任何限制和过滤,导致恶意用户上传任意文件。

2、前端JS检测。

  • js验证-源代码
  •     function checkFileExt()
  • {
  •  var filename = document.getElementById("file0").value;
  •  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("文件名合法");
  •  }else{
  •   alert("文件名不合法"); }
  •  return flag;
  • };
  • 绕过js校验上传
  • Web应用系统虽然对用户上传的文件进行了校验,但是校验是通过前端javascript代码完成的。由于恶意用户可以对前端javascript进行修改或者是通过抓包软件篡改上传的文件,就会导致基于js的校验很容易被绕过。
  • 绕过方法
  • 1、删除或者禁用js。
  • 2、使用代理上传文件,比如Burp Suite。

3、文件上传漏洞-后端上传代码校验绕过。

  • 常规检测方法
  • MIME文件类型校验
  • 扩展名验证
  • 文件头校验

4、文件扩展名检测。

  • 截断上传
  • 基于一个组合逻辑漏洞造成的。在某些时候,攻击者手动修改了上传过程中的POST包,在文件名后添加一个%00字节额,则可以截断某些函数对文件名的判断。因为在许多语言的函数中,比如在C、PHP等语言的常用字符串处理函数中,0x00被认为是终止符。受此影响的环境有Web应用和一些服务器。比如应用原本只允许上传JPG图片,那么可以构造文件名为xxx.php[\0].JPG,其中[\0]为十六进制的0x00字符,.JPG绕过了应用的上传文件类型判断;但对于服务器来说,此文件因为0x00字符截断的关系,最终却变成了xxx.php。
  • 检测方法
  • 1、黑名单
  • 黑名单检测:一般有个专门的 blacklist 文件,里面会包含常见的危险脚本文件。
  • 2、白名单
  • 白名单检测:一般有个专门的 whitelist 文件,里面会包含的正常文件。
  • 绕过黑名单
  • 绕过方法:
  • 1、解析漏洞
  • 2、截断上传
  • 3、可能存在大小写绕过漏洞 - 比如 aSp 和 pHp 之类
  • 4、找黑名单扩展名的漏网之鱼 - 比如 asa 和 cer 之类
  •       jsp jspx jspf     asp asa cer aspx     php php php3 php4 php5     exe exee
  • 5、利用Windows的命名机制:shell.php.  shell.php空格  shell.php:1.jpg shell.php:: $DATA
  • 绕过白名单
  • 解析漏洞
  • 截断上传
  • 文件包含

5、MIME-TYPE检测。

  • 什么是MIME
  • MIME(Multipurpose Internet Mail Extensions)多用途互联网邮件扩展类型。是设定某种扩展名的文件用一种应用程序来打开的方式类型,当该扩展名文件被访问的时候,浏览器会自动使用指定应用程序来打开。
  • 常见的MIME类型
  • text/plain(纯文本)
  • text/html(HTML文档)
  • text/javascript(js代码)
  • application/xhtml+xml(XHTML文档)
  • image/gif(GIF图像)
  • image/jpeg(JPEG图像)
  • image/png(PNG图像)
  • video/mpeg(MPEG动画)
  • application/octet-stream(二进制数据)
  • application/pdf(PDF文档)
  • 检测
  • if ((($_FILE["file"]["type"] == "image/gif") ||$_FILE["file"]["type"] == "image/jpeg") ||$_FILE["file"]["type"] == "image/pjpeg")
  • 绕过文件类型校验
  • 部分Web应用系统判定文件类型是通过content-type字段,黑客可以通过抓包,将content-type字段改为常见的图片类型,如image/gif,从而绕过校验。

6、文件头检测

  • 什么是文件头
  • 文件头就是为了描述一个文件的一些重要的属性,比如图片的长度、宽度、像素尺寸等,当程序打开文件时读取这些属性对文件进行处理。
  • getimagesize()函数
  • getimagesize() 函数用于获取图像大小及相关信息,成功返回一个数组,失败则返回 FALSE 并产生一条错误信息。
  • 语法:
  • getimagesize( string filename ) 例子:
  • <?php $array = getimagesize("images/flower_1.jpg"); print_r($array); ?>
  • 浏览器显示如下:
  • Array ( [0] => 350 [1] => 318 [2] => 2 [3] => width="350" height="318" [bits] => 8 [channels] => 3 [mime] => image/jpeg ) 返回结果说明
  • 索引 0 给出的是图像宽度的像素值
  • 索引 1 给出的是图像高度的像素值
  • 索引 2 给出的是图像的类型,返回的是数字,其中1 = GIF,2 = JPG,3 = PNG,4 = SWF,5 = PSD,6 = BMP,7 = TIFF(intel byte order),8 = TIFF(motorola byte order),9 = JPC,10 = JP2,11 = JPX,12 = JB2,13 = SWC,14 = IFF,15 = WBMP,16 = XBM
  • 索引 3 给出的是一个宽度和高度的字符串,可以直接用于 HTML 的 <image> 标签
  • 索引 bits 给出的是图像的每种颜色的位数,二进制格式
  • 索引 channels 给出的是图像的通道值,RGB 图像默认是 3
  • 索引 mime 给出的是图像的 MIME 信息,此信息可以用来在 HTTP Content-type 头信息中发送正确的信息,如:header("Content-type: image/jpeg");
  • memcmp函数
  • 原型为:int memcmp(const void *str1, const void *str2, size_t n));
  • 其功能是把存储区 str1 和存储区 str2 的前 n 个字节进行比较。
  • 该函数是按字节比较的,位于string.h。
  • 绕过文件头校验
  • Web应用程序在校验文件类型、文件扩展名的同时,也会校验文件头,从而进一步确定文件的类型。针对这种情况,可以通过在上传的一句话木马文件的开头加入特定的文件头从而绕过这种校验方式。
  • 常用的三个图片格式文件头
  •     JPG
  • FF D8 FF E0 00 10 4A 46 49 46
  •     png
  • 89 50 4E 47 0D 0A 1A 0A
  •     gif
  • 47 49 46 38 39 61
  • 如何修改文件头
  • 1.将文件的前面加通过16进制编辑器添加文件头。如:GIF89a
  • 2.将一个正常的图片文件添加到一个php文件前面,通过命令行copy。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章