文件上传漏洞-学习笔记

KaldX

参考资料:
【WEB】文件上传 | 狼组安全团队公开知识库
[Web安全]文件上传漏洞及绕过基础详解+实操_截断绕过-CSDN博客


一、什么是文件上传漏洞?

文件上传漏洞是指 Web 应用程序在处理用户上传文件的功能时,没有对上传的文件进行严格、充分的验证和过滤,导致攻击者可以上传恶意文件(如 Webshell、病毒、恶意脚本等)到服务器上。一旦上传成功,攻击者可能通过访问该文件,获得服务器的控制权、执行任意命令、窃取数据、篡改网页等。

二、文件上传的过程

  1. 客户端: 用户在浏览器选择要上传的文件。
  2. 客户端验证(可选): 浏览器端可能通过 JavaScript 对文件类型、大小进行初步检查。
  3. 服务器接收: 文件数据通过 HTTP POST 请求发送到服务器。
  4. 服务器端处理:
    • Web 应用程序接收文件数据。
    • 验证与过滤(关键步骤): 程序对文件进行检查(如后缀名、MIME 类型、文件头、内容扫描等)。
    • 临时存储: 文件通常先被存放在服务器的临时目录中。
    • 移动文件: 如果验证通过,文件被从临时目录移动到指定的、可通过 Web 访问或程序引用的最终路径。
  5. 返回结果: 服务器向客户端返回上传结果(成功或失败信息)。

三、文件上传返回值(PHP 示例)

PHP 在处理文件上传时,$_FILES['userfile']['error'] 会包含一个错误代码,常见的有:

  • UPLOAD_ERR_OK (0): 上传成功。
  • UPLOAD_ERR_INI_SIZE (1): 上传的文件大小超过了 php.iniupload_max_filesize 指令限制的值。
  • UPLOAD_ERR_FORM_SIZE (2): 上传文件的大小超过了 HTML 表单中 MAX_FILE_SIZE 选项指定的值。
  • UPLOAD_ERR_PARTIAL (3): 文件只有部分被上传。
  • UPLOAD_ERR_NO_FILE (4): 没有文件被上传。
  • UPLOAD_ERR_NO_TMP_DIR (6): 找不到临时文件夹。
  • UPLOAD_ERR_CANT_WRITE (7): 文件写入失败。
  • UPLOAD_ERR_EXTENSION (8): PHP 扩展程序停止了文件上传。

四、什么是 Webshell?

Webshell 本质上是一个运行在 Web 服务器上的服务端脚本文件(如 PHP、ASP、JSP、ASPX 等编写),它充当了一个可以通过 Web 浏览器访问的远程管理后门。攻击者上传 Webshell 成功后,可以通过访问这个 Webshell 文件,执行系统命令、管理文件、操作数据库、查看服务器信息等,从而达到控制网站或服务器的目的。

五、Webshell 的分类

分类 体量 特点
大马 体积大 功能全面,通常包含文件管理、数据库管理、命令执行、端口扫描等多种功能。常进行代码加密或混淆以躲避检测。
小马 体积小 功能单一,通常只包含核心功能,如文件上传或命令执行,用于后续上传大马或执行简单命令。
一句话木马 极短 代码通常只有一行,隐蔽性强。需要配合客户端工具(如中国蚁剑、菜刀、Behinder)使用。易于变形和插入正常文件中,难以检测。

六、文件上传的攻击方法/步骤

  1. 信息收集: 寻找目标网站上存在文件上传功能的地方(如用户头像、附件上传、编辑器图片上传、资料导入等)。
  2. 初步测试: 尝试直接上传一个简单的 Webshell 文件(如 shell.php),看是否能成功,并尝试访问。
  3. 识别防护机制: 如果直接上传失败,分析错误提示、前端代码、服务器响应,判断服务器可能采用了哪种防护措施(前端 JS 检查、MIME 类型检查、后缀名黑/白名单、文件内容检查等)。
  4. 尝试绕过: 针对识别出的防护机制,使用相应的绕过技术(详见下一节)。
  5. 上传成功与验证: 绕过成功后,上传 Webshell。
  6. 获取访问路径: 确定上传后的文件在服务器上的确切 URL 路径。这可能需要猜测、读取响应信息或利用其他漏洞。
  7. 连接 Webshell: 使用 Webshell 管理工具(如蚁剑、菜刀)连接上传的 Webshell URL,验证是否能成功执行命令或管理文件。
  8. 后渗透(可选): 利用 Webshell 进行提权、信息收集、持久化等操作。

七、上传绕过技术

1. 绕过前端 JS 检测

  • 原理: 只在浏览器端使用 JavaScript 检查文件后缀名,数据包未发送到服务器前进行拦截。
  • 绕过方法:
    • 禁用浏览器 JS: 在浏览器设置中临时禁用 JavaScript 功能。
    • 修改前端代码: 使用浏览器开发者工具(F12)找到负责检查的 JS 代码,将其删除或修改判断逻辑。
    • 抓包改包: 先将文件后缀改为允许的类型(如 .jpg)骗过 JS 检查,然后使用 Burp Suite 等代理工具抓取 HTTP 请求包,在发送给服务器前,将数据包中的文件名或后缀名改回恶意文件的后缀(如 .php)。

2. 绕过 Content-Type 检测

  • 原理: 服务器端检查 HTTP 请求头中的 Content-Type 字段,判断文件类型是否在允许的列表中(如 image/jpeg, image/png)。
  • 绕过方法: 使用 Burp Suite 抓包,修改请求包中的 Content-Type 字段为服务器允许的值(如 image/jpeg),即使实际上传的是 .php 文件。

3. 黑名单绕过

  • 原理: 服务器端维护一个不允许上传的文件后缀名列表(黑名单),如 .php, .asp, .jsp
  • 绕过方法:
    • 寻找替代后缀名: 尝试使用未被列入黑名单但仍能被服务器解析为脚本的后缀名,如 php3, php4, php5, phtml, pht (Apache), asa, cer, cdx (IIS), jspx (JSP) 等。
    • 大小写绕过: 如果服务器检查时未将后缀名统一转换为小写(或大写),可以尝试 pHp, PhP, PHP 等。
    • 特殊文件名绕过 (Windows):
      • 末尾加点 . Windows 会自动去除文件名末尾的点,上传 shell.php. 可能会被保存为 shell.php
      • 末尾加空格 Windows 会自动去除文件名末尾的空格,上传 shell.php (抓包修改,文件名后加空格) 可能会被保存为 shell.php
      • NTFS 交换数据流 (::$DATA): 在文件名后附加 ::$DATA ,如 shell.php::$DATA,在某些 Windows 环境下,文件内容会写入 shell.php 本身。
    • 双写绕过: 如果服务器过滤机制是简单地替换或删除黑名单中的子串(如将 php 替换为空),可以尝试双写,如 shell.pphphp,过滤后可能剩下 shell.php
    • . . 绕过 (特定场景): 如果服务器过滤逻辑是先去点再去空格(或类似顺序),shell.php. . 可能会绕过过滤。 (如 upload-labs 第十关)
    • 利用系统特性 (Windows): 文件名 shell.php:.jpg 在特定环境下可能生成 shell.php 文件。Windows 下 " 等价于 .> 等价于 ?< 等价于 *,可能用于绕过正则。

4. 使用 .htaccess 绕过 (Apache)

  • 原理: .htaccess 是 Apache 服务器的分布式配置文件。如果服务器允许上传并解析 .htaccess 文件,并且开启了 AllowOverride 选项,攻击者可以上传自定义的 .htaccess 文件来改变服务器行为。
  • 绕过方法:
    1. 创建一个名为 .htaccess 的文件。
    2. 在文件中写入指令,让 Apache 将特定后缀(甚至是所有文件)当作 PHP 执行。例如:
      • SetHandler application/x-httpd-php (将当前目录下所有文件当作 PHP 解析)
      • AddType application/x-httpd-php .jpg (将 .jpg 文件当作 PHP 解析)
    3. 上传这个 .htaccess 文件到目标目录。
    4. 上传一个包含 Webshell 代码的文件,其后缀名符合 .htaccess 文件中设置的规则(如 shell.jpg)。
    5. 访问这个 shell.jpg 文件,它将被 Apache 当作 PHP 执行。

5. 白名单绕过

  • 原理: 服务器只允许上传指定后缀名的文件(白名单),如 jpg, png, gif。这通常比黑名单更安全,但仍有绕过可能。
  • 绕过方法:
    • %00 截断 (路径/文件名截断):
      • 条件: PHP 版本 < 5.3.4 且 magic_quotes_gpc 配置为 Off。
      • 原理: %00 (URL 编码的 NULL 字节) 在 C 语言系的函数中通常表示字符串结束。如果上传路径或文件名参数可控,可以在路径中注入 %00
      • GET 型截断:save_path=../upload/shell.php%00,后面即使拼接了 .jpg,最终保存路径可能只取到 shell.php
      • POST 型截断: POST 请求中的 %00 不会被自动解码,需要在 Burp Suite 中找到包含路径的参数,修改为 ../upload/shell.php%00,然后对 %00 进行 URL Decode (Hex 视图下修改为 00) 再发送。
      • 目的: 使服务器在拼接最终保存路径时,在 %00 处截断,丢弃后面用于满足白名单验证的后缀(如 .jpg),从而以期望的恶意后缀(如 .php)保存文件。

6. 解析漏洞绕过

  • 原理: 利用 Web 服务器(Apache, Nginx, IIS)自身或其与脚本解释器(如 PHP)配合时的解析缺陷。
  • 常见漏洞:
    • Apache 解析漏洞:
      • 从右向左解析后缀,不认识的后缀向前跳过。shell.php.xxx 会被解析为 shell.php
      • .htaccess 配置错误。
      • AddHandlerAddType 配置了非标准后缀(如 php5, phtml)。
    • Nginx 解析漏洞:
      • cgi.fix_pathinfo=1 (PHP 配置) + Nginx 配置不当:访问 shell.jpg/xxx.phpshell.jpg%00.php 时,shell.jpg 可能被当作 PHP 执行。
      • Nginx < 0.8.41 空字节代码执行漏洞。
    • IIS 解析漏洞:
      • 目录解析: 目录名以 .asp, .asa 结尾时,该目录下的所有文件(无论后缀)都可能被当作 ASP 执行。
      • 文件解析: 文件名 shell.asp;.jpg 可能被当作 shell.asp 执行。
      • IIS 7/7.5 + PHP (FastCGI): 类似 Nginx 的 cgi.fix_pathinfo 问题,访问 shell.jpg/.php 可能导致 shell.jpg 被当作 PHP 执行。

7. 文件内容检测绕过

  • 原理: 服务器不仅检查后缀名,还检查文件内容,如文件头(Magic Number)、调用 getimagesize() 函数检查图片信息、扫描文件内容是否包含恶意代码特征(如 <?php)。
  • 绕过方法:
    • 伪造文件头: 在 Webshell 代码前添加合法的文件头标识(Magic Number),如 GIF89a (GIF), ‰PNG (PNG), ÿØÿà (JPG)。
    • 图片马: 将 Webshell 代码插入到正常图片文件的元数据(如 EXIF)或文件末尾,或者与图片文件二进制合并。需要配合文件包含漏洞 (LFI) 或特定解析漏洞才能执行。
    • 绕过内容扫描:
      • 使用短标签 <?= @eval($_POST['cmd']);?> (需服务器开启 short_open_tag)。
      • 使用 <script language="php">@eval($_POST['cmd']);</script>
      • 对 Webshell 代码进行编码、加密、混淆。
    • 二次渲染绕过: 某些网站会对上传的图片进行压缩、裁剪等二次处理。可以构造特殊的图片,使得 Webshell 代码在渲染后仍然保留并可执行。这通常需要对 GD 库等图像处理库有深入了解。

8. 竞争条件 (Race Condition) 绕过

  • 原理: 网站的处理逻辑是:先将文件上传到临时目录 -> 再检查文件是否合法 -> 如果不合法则删除。在“上传完成”到“检查并删除”之间存在一个短暂的时间窗口。
  • 绕过方法:
    1. 上传一个“写入器”脚本(如 write.php),其功能是创建或写入真正的 Webshell 文件(如 shell.php)。
    2. 在上传 write.php 后,立即、高频地访问 write.php 的 URL。
    3. 如果在 write.php 被删除之前成功访问到它,它就会执行并创建 shell.php
    4. shell.php 因为不是直接上传的,可能不会被检查逻辑删除。

9. 双文件上传绕过

  • 原理: 网站允许一次上传多个文件,但其安全检查逻辑只检查了第一个文件。
  • 绕过方法: 同时上传两个文件,第一个是合法的(如 image.jpg),第二个是 Webshell(如 shell.php)。

10. 目录穿越漏洞结合

  • 原理: 如果上传时可以通过修改文件名或路径参数实现目录穿越(如 filename=../../shell.php),即使文件保存在非 Web 目录下,也可能通过穿越将其保存到 Web 可访问路径下。
  • Title: 文件上传漏洞-学习笔记
  • Author: KaldX
  • Created at : 2025-04-22 20:00:00
  • Updated at : 2025-04-22 20:00:00
  • Link: https://blog.kaldx.com/2025/04/22/文件上传漏洞-学习笔记/
  • License: This work is licensed under CC BY-NC-SA 4.0.
Comments