实战|记一次有趣的文件上传绕过getshell
字数 1725 2025-08-11 00:08:50

文件上传绕过与条件竞争漏洞利用实战教学

1. 前言

本文详细讲解一次实战渗透测试中通过文件上传条件竞争漏洞绕过白名单限制实现Getshell的过程。该案例展示了如何从信息收集到最终漏洞利用的完整链条,特别关注了文件上传绕过的创新思路。

2. 信息收集阶段

2.1 目标侦察

  • 域名/子域名扫描:使用工具如Sublist3r、Amass等收集目标所有相关域名和子域名
  • 端口扫描:识别开放服务,特别是25(SMTP)、80/443(HTTP/HTTPS)等关键端口
  • 目录爆破:使用Dirsearch、Gobuster等工具发现敏感目录

2.2 突破点发现

  • JS文件审计:在前端JavaScript中发现可疑注释和版本号信息
  • GitHub信息收集:使用Gitrob等工具搜索与目标相关的代码仓库
    • 关键词:公司名称、产品名称、发现的版本号
    • 重点关注:配置文件、数据库连接字符串、API密钥等敏感信息

3. 代码审计与漏洞发现

3.1 源码分析

获取部分源码后进行Java代码审计,重点关注以下危险函数:

  • readObject() - 可能导致反序列化漏洞
  • ProcessBuilder/Runtime.exec() - 可能导致命令注入
  • ScriptEngine - 可能导致代码注入
  • parseObject - JSON/XML解析漏洞
  • MultipartFile - 文件上传相关处理

3.2 任意文件读取漏洞

发现使用InputStream类且输入未过滤的代码段:

// 示例漏洞代码
public void readFile(HttpServletRequest request) {
    String filePath = request.getParameter("file");
    InputStream in = new FileInputStream(filePath); // 未过滤用户输入
    // ...文件操作...
}

利用方法

  • 读取服务器配置文件:/etc/passwd, /etc/shadow
  • 读取应用日志:../logs/catalina.out
  • 读取数据库配置文件:WEB-INF/classes/database.properties

4. 日志分析与接口发现

通过读取中间件日志发现:

  • 其他应用的API接口
  • 遗留的未授权上传接口
  • 敏感操作日志记录

5. 文件上传漏洞利用

5.1 初步测试

发现图片上传接口,测试发现:

  • 白名单限制:仅允许JPEG、JPG、PNG、BMP等图片格式
  • 未验证文件内容:仅检查文件扩展名,不验证文件头

5.2 条件竞争漏洞利用

原理
当文件上传处理流程如下时可能产生条件竞争:

  1. 服务器接收文件
  2. 检查文件扩展名(白名单)
  3. 将文件移动到最终目录
  4. 检查文件内容(如果有)

如果在步骤2和步骤3之间存在时间差,攻击者可以利用高并发请求在文件被移动但内容检查完成前访问该文件。

利用步骤

  1. 准备特殊构造的Webshell:

    • 文件扩展名为.jpg以通过白名单检查
    • 实际内容为JSP Webshell
  2. 使用Burp Suite Intruder:

    • 设置两个并行攻击:
      • 一个用于上传恶意文件
      • 一个用于访问上传的文件
    • 将并发请求设置为100+
  3. 持续攻击直到:

    • 上传请求和访问请求的时间窗口重叠
    • 在文件被服务器删除前访问到它
  4. 成功访问后:

    • 使用Webshell写入更持久的后门
    • 注入内存马保持访问

5.3 Webshell设计

初级Webshell(用于条件竞争):

<%-- 伪装成图片的JSP Webshell --%>
<%
if(request.getParameter("cmd")!=null){
    Process p = Runtime.getRuntime().exec(request.getParameter("cmd"));
    // ...处理命令输出...
}
%>

持久化Webshell(通过初级Webshell写入):

<%@ page import="java.io.*" %>
<%
String path = application.getRealPath("/shell.jsp");
String content = "<%@ page import=\"java.util.*,java.io.*\"%><%...%>";
new FileOutputStream(path).write(content.getBytes());
%>

6. 防御措施

6.1 文件上传安全

  1. 多阶段验证

    • 文件扩展名白名单
    • 文件内容验证(魔术字节)
    • 文件重命名
  2. 原子操作

    • 在临时目录完成所有验证后再移动文件
    • 使用锁机制防止条件竞争
  3. 权限控制

    • 上传目录不可执行
    • 使用单独的子域或路径存放上传文件

6.2 代码安全

  1. 输入验证

    • 对所有用户输入进行严格过滤
    • 使用安全的API处理文件操作
  2. 日志安全

    • 敏感接口访问日志
    • 异常操作监控
  3. 信息泄露防护

    • 前端代码混淆
    • 删除注释中的敏感信息
    • 定期检查公开代码仓库

7. 总结

本案例展示了从信息收集到最终漏洞利用的完整链条,关键点包括:

  1. 细致的信息收集(JS审计、GitHub搜索)
  2. 源码审计发现任意文件读取漏洞
  3. 通过日志分析发现隐藏接口
  4. 利用条件竞争绕过文件上传限制
  5. 高并发请求在时间窗口内完成攻击

这种攻击方式不仅适用于文件上传场景,也可应用于其他存在时间窗口的漏洞利用场景,如订单处理、兑换系统等。

文件上传绕过与条件竞争漏洞利用实战教学 1. 前言 本文详细讲解一次实战渗透测试中通过文件上传条件竞争漏洞绕过白名单限制实现Getshell的过程。该案例展示了如何从信息收集到最终漏洞利用的完整链条,特别关注了文件上传绕过的创新思路。 2. 信息收集阶段 2.1 目标侦察 域名/子域名扫描 :使用工具如Sublist3r、Amass等收集目标所有相关域名和子域名 端口扫描 :识别开放服务,特别是25(SMTP)、80/443(HTTP/HTTPS)等关键端口 目录爆破 :使用Dirsearch、Gobuster等工具发现敏感目录 2.2 突破点发现 JS文件审计 :在前端JavaScript中发现可疑注释和版本号信息 GitHub信息收集 :使用Gitrob等工具搜索与目标相关的代码仓库 关键词:公司名称、产品名称、发现的版本号 重点关注:配置文件、数据库连接字符串、API密钥等敏感信息 3. 代码审计与漏洞发现 3.1 源码分析 获取部分源码后进行Java代码审计,重点关注以下危险函数: readObject() - 可能导致反序列化漏洞 ProcessBuilder / Runtime.exec() - 可能导致命令注入 ScriptEngine - 可能导致代码注入 parseObject - JSON/XML解析漏洞 MultipartFile - 文件上传相关处理 3.2 任意文件读取漏洞 发现使用 InputStream 类且输入未过滤的代码段: 利用方法 : 读取服务器配置文件: /etc/passwd , /etc/shadow 读取应用日志: ../logs/catalina.out 读取数据库配置文件: WEB-INF/classes/database.properties 4. 日志分析与接口发现 通过读取中间件日志发现: 其他应用的API接口 遗留的未授权上传接口 敏感操作日志记录 5. 文件上传漏洞利用 5.1 初步测试 发现图片上传接口,测试发现: 白名单限制:仅允许JPEG、JPG、PNG、BMP等图片格式 未验证文件内容:仅检查文件扩展名,不验证文件头 5.2 条件竞争漏洞利用 原理 : 当文件上传处理流程如下时可能产生条件竞争: 服务器接收文件 检查文件扩展名(白名单) 将文件移动到最终目录 检查文件内容(如果有) 如果在步骤2和步骤3之间存在时间差,攻击者可以利用高并发请求在文件被移动但内容检查完成前访问该文件。 利用步骤 : 准备特殊构造的Webshell: 文件扩展名为 .jpg 以通过白名单检查 实际内容为JSP Webshell 使用Burp Suite Intruder: 设置两个并行攻击: 一个用于上传恶意文件 一个用于访问上传的文件 将并发请求设置为100+ 持续攻击直到: 上传请求和访问请求的时间窗口重叠 在文件被服务器删除前访问到它 成功访问后: 使用Webshell写入更持久的后门 注入内存马保持访问 5.3 Webshell设计 初级Webshell (用于条件竞争): 持久化Webshell (通过初级Webshell写入): 6. 防御措施 6.1 文件上传安全 多阶段验证 : 文件扩展名白名单 文件内容验证(魔术字节) 文件重命名 原子操作 : 在临时目录完成所有验证后再移动文件 使用锁机制防止条件竞争 权限控制 : 上传目录不可执行 使用单独的子域或路径存放上传文件 6.2 代码安全 输入验证 : 对所有用户输入进行严格过滤 使用安全的API处理文件操作 日志安全 : 敏感接口访问日志 异常操作监控 信息泄露防护 : 前端代码混淆 删除注释中的敏感信息 定期检查公开代码仓库 7. 总结 本案例展示了从信息收集到最终漏洞利用的完整链条,关键点包括: 细致的信息收集(JS审计、GitHub搜索) 源码审计发现任意文件读取漏洞 通过日志分析发现隐藏接口 利用条件竞争绕过文件上传限制 高并发请求在时间窗口内完成攻击 这种攻击方式不仅适用于文件上传场景,也可应用于其他存在时间窗口的漏洞利用场景,如订单处理、兑换系统等。