Tomcat CVE-2024-50379 / CVE-2024-56337 条件竞争漏洞分析
字数 1703 2025-08-22 12:22:54

Tomcat CVE-2024-50379 / CVE-2024-56337 条件竞争漏洞分析

0x01 漏洞描述

这两个漏洞本质上是相同的,只是CVE-2024-50379修复不完全,CVE-2024-56337做了二次修复。

漏洞描述:Apache Tomcat在JSP编译过程中存在Time-of-check Time-of-use (TOCTOU)条件竞争漏洞,当默认servlet启用写操作(非默认配置)且在大小写不敏感的文件系统上时,可能导致远程代码执行(RCE)。

关键点

  • 仅影响大小写不敏感系统(如Windows)
  • 需要DefaultServlet启用写操作(非默认配置)
  • 属于条件竞争(Race Condition)漏洞
  • 与JSP编译过程相关

0x02 环境搭建

配置要求

  1. 修改conf/web.xml,将DefaultServlet的readonly参数设为false:
<servlet>
    <servlet-name>default</servlet-name>
    <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
    <init-param>
        <param-name>debug</param-name>
        <param-value>0</param-value>
    </init-param>
    <init-param>
        <param-name>listings</param-name>
        <param-value>false</param-value>
    </init-param>
    <init-param>
        <param-name>readonly</param-name>
        <param-value>false</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>
  1. 使用调试模式启动Tomcat:
catalina.bat jpda start
  1. 将Tomcat的lib/*.jar文件作为库添加到IDEA中

0x03 漏洞原理分析

核心流程

  1. DefaultServlet:负责处理静态资源请求
  2. JspServlet:负责处理.jsp/.jspx文件请求和编译

关键发现

  • 访问a.JSP和a.Jsp等变形内容都由DefaultServlet处理
  • 两个Servlet在寻找文件时都调用StandardRoot#getResource方法
  • Windows系统下,getCanonicalPath()方法会返回实际存在的文件名(大小写敏感)

条件竞争场景

  1. 线程A:通过PUT方法上传a.JSP文件
  2. 线程B:同时访问a.jsp文件
  3. 由于Windows文件系统大小写不敏感,可能导致JspServlet处理了a.JSP文件

0x04 深入技术分析

文件路径处理流程

  1. StandardRoot#getResource调用路径:

    • 判断是否启用缓存
    • 最终调用getResourceInternal方法
  2. AbstractFileResourceSet#file方法关键点:

    • 调用getCanonicalPath()获取规范化路径(can path)
    • 与绝对路径(abs path)比较
    • 只有两者相等时才返回文件对象

Windows路径处理细节

  • WinNTFileSystem#canonicalize0方法行为:
    • 输入a.jsp时,如果存在a.JSP文件,返回a.JSP
    • 不存在a.JSP文件时,原样返回a.jsp
  • 路径缓存机制:
    • 默认缓存30秒
    • 最大缓存300条记录

条件竞争关键

  • 需要在PUT a.JSP文件落地前,确保多次file方法调用都获取到a.jsp -> a.jsp的缓存
  • 任何一次获取到a.jsp -> a.JSP都会导致校验失败
  • 最终需要在文件读取时确保a.JSP文件已存在

0x05 漏洞修复

CVE-2024-50379修复

  • 在读操作和写操作之间加锁
  • 锁键值处理:
    • 大小写敏感系统:使用原始路径
    • 大小写不敏感系统:转换为小写

CVE-2024-56337二次修复

  • 建议设置sun.io.useCanonCaches为false
  • 禁用路径缓存可彻底避免条件竞争

0x06 漏洞检测方案

检测步骤

  1. 验证PUT操作有效性

    • PUT随机文件,确认返回204
    • 可选:GET验证文件存在后DELETE
  2. 判断操作系统

    • 尝试PUT上传:.txt文件
    • Windows系统会返回409错误
  3. 版本信息确认

    • 通过404路径获取Tomcat版本
    • 受影响版本:
      • 11.0.0-M1 through 11.0.1
      • 10.1.0-M1 through 10.1.33
      • 9.0.0.M1 through 9.0.97

检测逻辑示例

if (ver >= 9_000_000 && ver <= 9_000_097) || 
   (ver >= 10_001_000 && ver <= 10_001_033) || 
   (ver >= 11_000_000 && ver <= 11_000_001) ||
   (strings.Contains(verStr, "M") && 
    (strings.HasPrefix(verStr, "9.") || 
     strings.HasPrefix(verStr, "10.") || 
     strings.HasPrefix(verStr, "11."))) {
    // 报告漏洞
}

0x07 总结

该漏洞利用Windows文件系统特性,通过精心设计的条件竞争,使得JspServlet处理了本应由DefaultServlet处理的文件。修复方案通过加锁和禁用缓存两种方式确保路径解析的一致性。检测时需综合考虑PUT功能、操作系统和版本信息三个维度。

Tomcat CVE-2024-50379 / CVE-2024-56337 条件竞争漏洞分析 0x01 漏洞描述 这两个漏洞本质上是相同的,只是CVE-2024-50379修复不完全,CVE-2024-56337做了二次修复。 漏洞描述 :Apache Tomcat在JSP编译过程中存在Time-of-check Time-of-use (TOCTOU)条件竞争漏洞,当默认servlet启用写操作(非默认配置)且在大小写不敏感的文件系统上时,可能导致远程代码执行(RCE)。 关键点 : 仅影响大小写不敏感系统(如Windows) 需要DefaultServlet启用写操作(非默认配置) 属于条件竞争(Race Condition)漏洞 与JSP编译过程相关 0x02 环境搭建 配置要求 修改 conf/web.xml ,将DefaultServlet的readonly参数设为false: 使用调试模式启动Tomcat: 将Tomcat的lib/* .jar文件作为库添加到IDEA中 0x03 漏洞原理分析 核心流程 DefaultServlet :负责处理静态资源请求 JspServlet :负责处理.jsp/.jspx文件请求和编译 关键发现 访问a.JSP和a.Jsp等变形内容都由DefaultServlet处理 两个Servlet在寻找文件时都调用 StandardRoot#getResource 方法 Windows系统下, getCanonicalPath() 方法会返回实际存在的文件名(大小写敏感) 条件竞争场景 线程A:通过PUT方法上传a.JSP文件 线程B:同时访问a.jsp文件 由于Windows文件系统大小写不敏感,可能导致JspServlet处理了a.JSP文件 0x04 深入技术分析 文件路径处理流程 StandardRoot#getResource 调用路径: 判断是否启用缓存 最终调用 getResourceInternal 方法 AbstractFileResourceSet#file 方法关键点: 调用 getCanonicalPath() 获取规范化路径(can path) 与绝对路径(abs path)比较 只有两者相等时才返回文件对象 Windows路径处理细节 WinNTFileSystem#canonicalize0 方法行为: 输入a.jsp时,如果存在a.JSP文件,返回a.JSP 不存在a.JSP文件时,原样返回a.jsp 路径缓存机制: 默认缓存30秒 最大缓存300条记录 条件竞争关键 需要在PUT a.JSP文件落地前,确保多次 file 方法调用都获取到a.jsp -> a.jsp的缓存 任何一次获取到a.jsp -> a.JSP都会导致校验失败 最终需要在文件读取时确保a.JSP文件已存在 0x05 漏洞修复 CVE-2024-50379修复 在读操作和写操作之间加锁 锁键值处理: 大小写敏感系统:使用原始路径 大小写不敏感系统:转换为小写 CVE-2024-56337二次修复 建议设置 sun.io.useCanonCaches 为false 禁用路径缓存可彻底避免条件竞争 0x06 漏洞检测方案 检测步骤 验证PUT操作有效性 : PUT随机文件,确认返回204 可选:GET验证文件存在后DELETE 判断操作系统 : 尝试PUT上传 :.txt 文件 Windows系统会返回409错误 版本信息确认 : 通过404路径获取Tomcat版本 受影响版本: 11.0.0-M1 through 11.0.1 10.1.0-M1 through 10.1.33 9.0.0.M1 through 9.0.97 检测逻辑示例 0x07 总结 该漏洞利用Windows文件系统特性,通过精心设计的条件竞争,使得JspServlet处理了本应由DefaultServlet处理的文件。修复方案通过加锁和禁用缓存两种方式确保路径解析的一致性。检测时需综合考虑PUT功能、操作系统和版本信息三个维度。