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 环境搭建
配置要求
- 修改
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>
- 使用调试模式启动Tomcat:
catalina.bat jpda start
- 将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错误
- 尝试PUT上传
-
版本信息确认:
- 通过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功能、操作系统和版本信息三个维度。