1. 漏洞简介

1.1 什么是文件上传漏洞

  • 当Web服务没用验证文件上传的文件类型、名称、大小、内容等,则有可能导致恶意PHP、ASP文件绕过Web应用并顺利执行,此时攻击者可能直接拿到服务器权限WebShell。
  • 当得到WebShell,则可以提取Web数据、删除Web文件、本地提取、拿下整个服务器甚至内网渗透。
  • SQL注入攻击目标为数据库服务,而文件上传漏洞攻击的则是Web服务,实际渗透过程一般结合起来达到对集群的深度控制。

1.2 文件上传漏洞危害

  • 服务器被控制
  • 客户端被劫持
  • 敏感信息泄露
  • 恶意文件托管
  • 未经授权操作
  • 拒绝服务攻击

2. 文件上传漏洞预防

2.1 文件类型/大小/后缀/路径检测/文件名

  • 前端通过lavascript验证(文件扩展名、大小)
  • 后端检测MIME类型(白名单、重命名、大小)
  • 后端检测目录路径(是否合法)确保文件名不包含任何可能被解释为目录或遍历序列( ../) 的子字符串。
  • 重命名上传的文件以避免可能导致现有文件被覆盖的冲突。

2.2 文件内容解析

  • 排查恶意代码
  • 在完全验证之前不要将文件上传到服务器的永久文件系统。

2.3 上传文件目录修改权限

  • 无执行权限
  • 读写权限分离

2.4 最小权限运行Web服务

  • 降低被getshell后的风险

2.5 优化配置

  • 利用php.ini配置
  • 尽可能使用已建立的框架来预处理文件上传,而不是尝试编写自己的验证机制。

3. 文件上传漏洞绕过

3.1 客户端Javascript检测情况

  • 修改前端js绕过

3.2 服务器安全检测

3.2.1 修改MIME类型

  1. 修改 HTTP Header 中的content-type
  1. 有的站点使用文件头来检测文件类型,这种检查可以在Shell前加入对应的字节以绕过检查。几种常见的文件类型的头字节如下表所示
    1. 类型
      二进制值
      JPG
      FF D8 FF E0 00 10 4A 46 49 46
      GIF
      47 49 46 38 39 61
      PNG
      89 50 4E 47
      TIF
      49 49 2A 00
      BMP
      42 4D
  1. 修改文件扩展名
      • 部分服务仅根据后缀、上传时的信息或Magic Header来判断文件类型,此时可以绕过。
        • php由于历史原因,部分解释器可能支持符合正则 /ph(p[2-7]?|t(ml)?)/ 的后缀,如 php / php5 / pht / phtml / shtml / pwml / phtm 等 可在禁止上传php文件时测试该类型。
        • jsp引擎则可能会解析 jspx / jspf / jspa / jsw / jsv / jtml 等后缀,asp支持 asa / asax / cer / cdx / aspx / ascx / ashx / asmx / asp{80-90} 等后缀。
        • 除了这些绕过,其他的后缀同样可能带来问题,如 vbs / asis / sh / reg / cgi / exe / dll / com / bat / pl / cfc / cfm / ini 等。
      • 还可通过修改后缀,如:异形后缀、双写、大小写、编码
      • 提供多个扩展。根据用于解析文件名的算法,以下文件可能被解释为 PHP 文件或 JPG 图像:exploit.php.jpg
      • 添加尾随字符。一些组件会去除或忽略尾随空格、点等:exploit.php.
      • 尝试对点、正斜杠和反斜杠使用 URL 编码(或双 URL 编码)。如果在验证文件扩展名时该值没有被解码,但后来在服务器端被解码,这也可以让您上传否则会被阻止的恶意文件:exploit%2Ephp
      • 文件扩展名前添加分号或 URL 编码的空字节字符。如果验证是用 PHP 或 Java 等高级语言编写的,但服务器使用 C/C++ 中的低级函数处理文件,例如,这可能会导致文件名结尾出现差异:exploit.asp;.jpg exploit.asp%00.jpg
      • 尝试使用多字节 unicode 字符,在 unicode 转换或规范化后可能会转换为空字节和点。xC0 x2E如果文件名被解析为 UTF-8 字符串,则类似xC4 xAE或序列xC0 xAE可能会被转换为x2E,但随后会在用于路径之前转换为 ASCII 字符。

3.2.2 修改目录路径检测

  • 截断绕过

3.2.3 系统命名检测

在Windows系统中,上传 index.php.会重命名为 .,可以绕过后缀检查。 也可尝试 index.php%20, index.php:1.jpg index.php::$DATA等。 在Linux系统中,可以尝试上传名为 index.php/.或 ./aa/../index.php/.的文件

3.3 .user.ini

在php执行的过程中,除了主 php.ini之外,PHP 还会在每个目录下扫描 INI 文件,从被执行的 PHP 文件所在目录开始一直上升到 web 根目录($_SERVER['DOCUMENT_ROOT'] 所指定的)。如果被执行的 PHP 文件在 web 根目录之外,则只扫描该目录。 .user.ini 中可以定义除了PHP_INI_SYSTEM以外的模式的选项,故可以使用 .user.ini加上非php后缀的文件构造一个shell,比如 auto_prepend_file=01.gif

3.4 WAF绕过

有的waf在编写过程中考虑到性能原因,只处理一部分数据,这时可以通过加入大量垃圾数据来绕过其处理函数。
另外,Waf和Web系统对 boundary 的处理不一致,可以使用错误的 boundary 来完成绕过。

3.5 竞争上传绕过

有的服务器采用了先保存,再删除不合法文件的方式,在这种服务器中,可以反复上传一个会生成Web Shell的文件并尝试访问,多次之后即可获得Shell。

3.6 基于 URL 的文件上传中的竞争条件

在允许您通过提供 URL 来上传文件的函数中可能会出现类似的竞争条件。在这种情况下,服务器必须通过 Internet 获取文件并创建本地副本,然后才能执行任何验证。
由于文件是使用 HTTP 加载的,因此开发人员无法使用其框架的内置机制来安全地验证文件。相反,他们可以手动创建自己的流程来临时存储和验证文件,这可能不太安全。
例如,如果文件被加载到具有随机名称的临时目录中,理论上,攻击者应该不可能利用任何竞争条件。如果他们不知道目录的名称,他们将无法请求文件以触发其执行。另一方面,如果随机目录名称是使用 PHP 之类的伪随机函数生成的uniqid(),则它可能会被暴力破解。
为了使此类攻击更容易,您可以尝试延长处理文件所需的时间,从而延长暴力破解目录名称的窗口。一种方法是上传更大的文件。如果它以块的形式进行处理,您可以通过在开始时创建一个带有有效负载的恶意文件,然后是大量的任意填充字节来利用这一点。

3.6 编码或加密绕过

3.7 利用文件包含漏洞绕过

3.8 覆盖服务器配置

服务器通常不会执行文件,除非它们已被配置为这样做。例如,在 Apache 服务器执行客户端请求的 PHP 文件之前,开发人员可能必须将以下指令添加到他们的/etc/apache2/apache2.conf文件中:
许多服务器还允许开发人员在各个目录中创建特殊的配置文件,以便覆盖或添加一个或多个全局设置。例如,Apache 服务器将从一个名为(.htaccess如果存在)的文件中加载特定于目录的配置。
同样,开发人员可以使用web.config文件在 IIS 服务器上进行特定于目录的配置。这可能包括如下指令,在这种情况下允许将 JSON 文件提供给用户:
Web 服务器在存在时使用这些类型的配置文件,但通常不允许您使用 HTTP 请求访问它们。但是,您可能偶尔会发现无法阻止您上传自己的恶意配置文件的服务器。在这种情况下,即使您需要的文件扩展名被列入黑名单,您也可以欺骗服务器将任意自定义文件扩展名映射到可执行的 MIME 类型。

4. 靶场练习

4.1 使用 Burpsuite 官方靶场练习

4.1.1 Lab: Remote code execution via web shell upload

题目:通过 web shell 上传远程执行代码
  • 在账户内上传无限制,即可上传脚本
  • 在上传图片作为头像时候,点击 Burp 的 Proxy 中 HTTP History 的 Filter 中的:
notion image
  • 发现在上传完成返回账户时候会通过GET 加载文件
notion image
  • 那么通过上传 PHP 脚本:
    • <?php echo file_get_contents('/home/carlos/secret'); ?>
  • 然后返回账户,在 Burp 查看获取文件的GET请求便会发现钥匙
notion image

4.1.2 Lab: Web shell upload via Content-Type restriction bypass

题目:通过 Content-Type 限制绕过 Web shell 上传
思路:修改Content-Type类型绕过
  • 在正常上传 PHP 脚本通过 Burp 拦截会发现,Content-Type 不符合
notion image
  • 通过在 Burp 修改为image/png 成功上传 PHP 脚本,返回账户,成功获取钥匙
notion image

4.1.3 Lab: Web shell upload via path traversal

题目:通过路径遍历上传 Web shell
思路:修改路径将文件上传到非该路径
  • 正常情况下,在本题中上传的文件均当作文本,不执行
  • 那么利用路径绕过,在上传脚本文件的时候用 Burp 进行拦截,修改文件路径为../1.php 后放行,即将文件存储于上一级目录下,在路径中将/ 进行 URL 编码以绕过路径提取
notion image
  • 在修改成功后上传,返回账户查看GET请求,发现钥匙
notion image

4.1.4 Lab: Web shell upload via extension blacklist bypass

题目:通过扩展黑名单绕过 Web shell 上传
思路:通过上传配置文件.htaccess 使得可以自定义 MIME 类型以绕过类型检查
  • 在尝试上传 PHP 脚本的时候发现会出现错误
    • notion image
  • 修改filename.htaccess ,然后将Content-Type修改为text/plain
    • 文件中包含AddType application/x-httpd-php .l33t
      notion image
  • 上传后缀为.l33t 的一句话木马,
    • <?php echo file_get_contents('/home/carlos/secret'); ?>
      会自动映射到x-httpd-php 类型
      notion image
  • 回到账户,会发现钥匙
    • notion image
 

4.1.5 Lab: Web shell upload via obfuscated file extension

题目:通过混淆文件扩展名上传 Web shell
思路:通过修改后缀名绕过检测
  • 在尝试上传脚本文件的时候会发现只允许上传 Jpg 或 Png 文件,那么修改文件后缀名字,在后缀名字面前添加 URL 编码%00 即空字节编码;
notion image
  • 然后发送时候会发现系统剥离了文件空字节和后面的 Jpg 后缀;
notion image
  • 当返回账户时候修改访问文件为
notion image
  • 则能在返回结果中发现钥匙

4.1.6 Lab: Remote code execution via polyglot web shell upload

题目:通过多语言 Web shell 上传远程执行代码
思路:在本题目中不能直接提交非 jpgpng 的文件,但没有对文件后缀进行限制,则将图片和脚本文件结合,以 php 后缀从而绕过检测。
  • 尝试上传脚本文件,发现出现上传文件错误;
notion image
  • 通过在cmd中使用copy 1.jpg /b+1.php/a 2.php1.jpg1.php脚本文件生成包含图片二进制码的 2.php脚本文件,上传;
    • 1.php脚本文件:
      合成的2.php文件包含:
      notion image
  • 再返回账号然后在GET请求2.php文件中发现钥匙;
    • notion image

参考文章

 
💡
本文章仅提供学习使用,有任何问题,欢迎您在底部评论区留言,一起交流~
 
 
文件包含漏洞Webshell与冰蝎、蚁剑、哥斯拉