upload-labs是一个使用php语言编写的,专门收集渗透测试和CTF中遇到的各种上传漏洞的靶场。每一关都包含着不同上传方式。 [TOC] 20关都练会了那么也就基本掌握了php文件上传漏洞的各种方法了 项目地址:***.com 搭建了两个环境,分别是:

  1. docker安装的linux环境
  2. 绿色安装的win2003版本

pass01:前端js限制(双杀)

  1. 适合操作系统 windows、linux通用,不区分系统 不区分web中间件
  2. 如何测试 提交错误后缀文件后,控制台无数据交互产生,说明文件类型验证是通过前端页面验证的
  3. 如何绕过 直接禁用js、修改页面函数、bp抓包

pass02:mime类型限制(双杀)

  1. 适合操作系统 windows、linux通用,不区分系统 不区分web中间件
  2. 如何测试 上传php文件抓包,将Content-Type: application/octet-stream改为Content-Type: image/jpeg后提交 能提交成功,且能正常访问,说明只是限制了mime文件类型
  3. 如何绕过 可以直接抓包修改mime类型 也可先将php文件改名为jpg,上传抓包后将文件名改回去

pass03:文件后缀限制不严格(双杀)

  1. 适合操作系统 windows、linux通用,不区分系统 不区分web中间件
  2. 如何测试 错误提示:“提示:不允许上传.asp,.aspx,.php,.jsp后缀文件! ” 上传文件后,文件会被改名,但后缀不变
  3. 如何绕过 以php为例,不光是php后缀可执行,还有php2、php3、php4、php5都可执行 所以文件后缀验证不严格时,可以用这些后缀绕过

pass04:文件后缀限制不严格(双杀)

  1. 适合操作系统 windows、linux通用,不区分系统 仅限于web中间件为apache,且
  2. mod_rewrite模块开启
  3. AllowOverride All
  4. 如何测试 上传php各种后缀均无效,说明文件后缀过滤更严格了 发现web中间件是apache,但未过滤.htaccess格式文件
  5. 如何绕过 上传一个htaccess文件,文件中允许任何文件当php文件执行 然后再将123.php改名为123.jpg后上传,访问改文件可执行phpinfo
  6. htaccess文件内容 $ cat 1.htaccess <FilesMatch ""> SetHandler application/x-httpd-php </FilesMatch>

    htaccess文件是Apache服务器中的一个配置文件,它负责相关目录下的网页配置。通过htaccess文件,可以帮我们实现:网页301重定向、自定义404错误页面、改变文件扩展名、允许/阻止特定的用户或者目录的访问、禁止目录列表、配置默认文档等功能。

pass05:大小写限制不严格(仅win)

  1. 适合操作系统 仅windows可用,因为windowns不区分文件写,而linux会严格区分
  2. 如何测试 各种后缀限制严格了,包括.htaccess格式 但是大小写为区分,且上传的大写文件名不现在
  3. 如果绕过 将123.php改为123.phP后上传,上传后可正常访问使用

pass06:空格绕过(仅win)

  1. 适合操作系统 仅windows可用,在windows下,如果新建文件“123.php ”,实际会被存储为”123.php“
  2. 如何测试 各种后缀限制严格,大小写也不行,可以考虑windows特性绕过
  3. 为什么能绕过 通过分析源码,发现是代码中没有处理文件后缀中的空格,导致在windows下的该漏洞

pass07:空格加点绕过(仅win)

  1. 适合操作系统 仅windows可用,在windows下,如果新建文件“123.php .”,实际会被存储为”123.php“
  2. 如何测试 各种后缀限制严格,大小写也不行,可以考虑windows特性绕过
  3. 为什么能绕过 通过分析源码,发现代码对文件名首尾进行了去空操作,但未处理文件名后的点

pass08: ::$DATA绕过(仅win)

  1. 适合操作系统 仅windows可用,利用了Windows文件流特性绕过 如果文件名+"::$DATA",会把::$DATA之后的数据当成文件流处理,不会检测后缀名,且保持"::$DATA"之前的文
  2. 如何测试 各种后缀限制严格,大小写也不行,可以考虑windows特性绕过
  3. 为什么能绕过 通过分析源码,发现是代码中过滤了点和前后空格,但未处理DATA流,导致在windows下的该漏洞

pass09:点空格点绕过(仅win)

  1. 适合操作系统 仅windows可用,在windows下,如果新建文件“123.php. .”,实际会被存储为”123.php“
  2. 如何测试 各种后缀限制严格,大小写也不行,可以考虑windows特性绕过
  3. 为什么能绕过 通过分析源码,发现代码对文件名首尾进行了去空,也限制了DATA流和空格加点,但未处理. .这种形式

pass10:关键字替换绕过(双杀)

  1. 适合操作系统 不区分操作系统,通用
  2. 如何测试 上传文件发现文件后缀中若包含php等关键字,这些关键字会被替换为空,典型的字符替换
  3. 如何绕过 仅需将上传的文件123.php,改为123.pphphp,中间的php被替换为空后,剩下的文件名变回123.php

pass11:可控目录00截断(双杀)

  1. 适合操作系统 不限操作系统(linux搭不起低版本环境,待验证),但对中间件有要求
  2. php版本要小于5.3.4
  3. php.ini中的配置magic_quotes_gpc=OFF
  4. 如何测试 上传截包后,发现上传路径在head头中可控,可以尝试00截断
  5. 如何绕过 截包后,head中的路径../upload/改为../upload/1.php%00,提交 回显上传路径为***.com 但实际上文件为***.com,后续被截断了

pass12:可控目录00截断(双杀)

  1. 适合操作系统 不限操作系统(linux搭不起低版本环境,待验证),但对中间件有要求
  2. php版本要小于5.3.4
  3. php.ini中的配置magic_quotes_gpc=OFF
  4. 如何测试 上传截包后,发现上次路径在body中可控,可以尝试00截断 上一个pass的%00不能成功,尝试另外一种00截断
  5. 如何绕过 截包后,body中的路径../upload/,改为../upload/1.php 切换为16进制,找到php代表70 68 70将后一个16进制数改为00 再上传,结果同pass11一样

pass13:文件包含加图片马(双杀)

本pass提供远程文件包含漏洞,只需要想办法上传图片马 1. 适合操作系统 不限操作系统 2. 如何测试 页面做了白名单,仅允许上传gif、jpg、png三种文件 尝试直接将123.php改名为123.jpg后上传拒绝 说明后端重新不光判断后缀名,还用了检测函数检测文件类型 3. 如何绕过 用copy命令做个真正的图片马即可copy 1.jpg/b + 1.php/b 1.jpg 或者修改包头,添加gif图片头:GIF89a 4. 绕过后分析: 分析源码,是截取文件前两个字符,判断文件类型是否是gif、jpg、png或位置

pass14:文件包含加图片马(双杀)

本pass提供远程文件包含漏洞,只需要想办法上传图片马 1. 绕过方法 同pass13,图片马或改包头都可以 2. 绕过后分析 分析源码,是用了getimagesize函数检测文件是否是图片,其实也是看包头

pass15:文件包含加图片马(双杀)

本pass提供远程文件包含漏洞,只需要想办法上传图片马 1. 绕过方法 同pass13,图片马或改包头都可以 2. 绕过后分析 分析源码,是用了exif_imagetype()函数检测文件是否是图片,其实也是看包头

pass16:文件包含加图片马(双杀)

本pass提供远程文件包含漏洞,只需要想办法上传图片马 1. 如何测试 发现图片马可以上传,改包头的文件不能上传 上传的图片,会被函数重写一次,导致图片马失效 2. 如何绕过 针对这种会重写的功能,思路是多尝试几个图片,对比上传前后图片,找出里面未变化的部分 将此部分改为一句话马再上传(我为实现) 3. 源码分析 先检测了文件后缀与检查了mime类型是否匹配 再根据图片类型,调用专门的检测函数如imagecreatefromjpeg检测是否是该型文件 最后用strval函数重写图片文件

pass17:先存再检再删(双杀)

  1. 源码分析 本pass困难,分析源码得知是先将文件存储,再检测该文件是否合法,不合法的删除。
  2. 如何绕过 既然会先存储,那么通过程序快速重传这个文件,达到一直可以访问的目的
  3. 麻蛋,没成功,改源码sleep才行

pass18:先存再检再改名(双杀)

  1. 利用条件 中间件为apache,且存在解析漏洞
  2. 源码分析 本pass困难,还是分析源码,发现会先将文件存放,再改名
  3. 如何绕过 截包,将123.php改为123.php.7z,然后连续重复提交 直到提示:"文件已经被上传,但没有重命名" 再利用解析漏洞访问该文件即可

pass19:文件名00截断(双杀)

  1. 适合操作系统 不限操作系统(linux搭不起低版本环境,待验证),但对中间件有要求
  2. php版本要小于5.3.4
  3. php.ini中的配置magic_quotes_gpc=OFF
  4. 如何测试 页面需要上传文件名,且需要输入文件上传后的新文件名,参数可控 上传截包后,将upload-19.jpg改为upload-19.php 尝试00截断,%00不能成功,16进制00截断成功 也可以利用windows特性,在文件名后加点,如upload-19.php.

pass20:数组文件名绕过(仅win)

  1. 适合操作系统 仅windows系统
  2. 源码分析检查过程 先检查mime类型,只能为jpeg、png、gif 再设置文件名,若将要保存的文件名存在就用,若为空就用上传文件的文件名 再检查文件名是否为数组,不是数组则用点号分割为数组 再检查文件名数组的最后值(即文件后缀)是否是jeg、png、gif 最后再将数组第0位与数组总个数-1位(正常情况下即后缀)重新用点拼接为新文件名并保存文件
  3. 绕过思路 需要绕过【判断是否为数组】这一步,那么需要提交的时候就提交为数组 一个很正常的数组(如a=["123",".","php"]),其a[-1]=a[count(a)-1] 手动指定数组下标(如a[0]="123",a[2]="php"),则a[-1]!=a[count(a)-1]
  4. 如何绕过 截包后,将seve_name复制一份 将第一份save_name的文件名改为UPLOAD-20.php,用数组0 将第二份save_name的文件名改为jpg,用数组除1外的任何下标 组后构造出来的文件名为UPLOAD-20.php.,结合windows特性绕过了 ```sh #原始包################# -----------------------------20346769815764617441374724817 Content-Disposition: form-data; name="upload_file"; filename="phpinfo.php" Content-Type: image/jpeg

-----------------------------20346769815764617441374724817 Content-Disposition: form-data; name="save_name"

upload-20.jpg

#改名,复制,加数组后的包############# -----------------------------20346769815764617441374724817 Content-Disposition: form-data; name="upload_file"; filename="phpinfo.php" Content-Type: image/jpeg

-----------------------------20346769815764617441374724817 Content-Disposition: form-data; name="save_name[0]"

upload-20.php -----------------------------20346769815764617441374724817 Content-Disposition: form-data; name="save_name[-1]"

jpg -----------------------------20346769815764617441374724817 ```