Tomcat 历史漏洞复现
Tomcat 是一个开源的、轻量级的 Web 应用服务器和 Servlet 容器。它由 Apache 软件基金会下的 Jakarta 项目开发,是目前最流行的 Java Web 服务器之一。
CVE-2025-24813(反序列化代码执行)
漏洞描述
Apache Tomcat 在处理 HTTP PUT 请求时,存在一个不安全文件上传漏洞(CVE-2025-24813),攻击者可利用该漏洞在服务器上写入恶意文件,并在特定条件下触发反序列化攻击,最终导致远程代码执行(RCE)。
利用条件
- 应用程序启用了 DefaultServlet 写入功能,该功能默认关闭。
- 应用支持了 partial PUT 请求,能够将恶意的序列化数据写入到会话文件中,该功能默认开启。
- 应用使用了 Tomcat 的文件会话持久化并且使用了默认的会话存储位置,需要额外配置。
- 应用中包含一个存在反序列化漏洞的库,比如存在于类路径下的 commons-collections,此条件取决于业务实现是否依赖存在反序列化利用链的库。
影响版本
- Apache Tomcat 11.0.0-M1 to 11.0.2
- Apache Tomcat 10.1.0-M1 to 10.1.34>
- Apache Tomcat 9.0.0.M1 to 9.0.98
漏洞原理
Content-Range
在 Tomcat 的 HTTP PUT 请求中主要用于实现大文件的分块传输。在文件上传未完成的情况下,内容会被临时存储在 Tomcat 的工作目录:$CATALINA_BASE/work/Catalina/localhost/ROOT
。
该漏洞的核心在于不完整 PUT 请求上传时的文件名处理机制:文件路径中的分隔符 /
会被转换为 .
。例如:访问 /xxxxx/session
会被解析为 .xxxxx.session
因此整个漏洞的利用过程为:
- Tomcat 的 File 会话存储默认路径同样位于:
CATALINA_BASE/work/Catalina/localhost/ROOT
- 当存在反序列化利用链时,可以上传包含恶意序列化数据的文件
- 通过设置
JSESSIONID=.xxxxx
来触发漏洞
环境搭建
可以直接使用 git 克隆已经搭建好的环境
1 | git clone git@github.com:x1ongsec/CVE-2025-24813.git |
也可以根据后续步骤自行搭建。
下载文件
下载 tomcat:https://archive.apache.org/dist/tomcat/tomcat-9/v9.0.98/bin/apache-tomcat-9.0.98.zip
下载 CC 依赖:commons-collections-3.2.1.jar
开启文件存储会话
在 conf/context.xml 文件中添加如下配置:
1 | <Manager className="org.apache.catalina.session.PersistentManager"> |
启用写入功能
在 conf/web.xml 文件中添加如下配置(大约 118 行位置开始):
1 | <servlet> |
添加 cc 依赖
在 webapps/ROOT/WEB-INF 目录下新建 lib 目录,将 commons-collections-3.2.1.jar 放入到该目录。
修改端口运行
在 conf/server.xml 文件中搜索 8080 将其修改为 9001:
接着来到 bin 目录下执行 如下命令:
1 | ./catalina.sh run |
访问
漏洞复现
生成一个恶意的序列化文件,使用以下数据包上传,需要注意 Range
的分块值需要与 Length
保持一致,且大于当前文件的长度。
这里恶意的序列化文件我通过 yakit 的 Yso-Java Hack 生成:
构造请求:
1 | PUT /x1ongsec/session HTTP/1.1 |
构造触发请求:
1 | GET / HTTP/1.1 |
接着先发送第一个请求:
发送第二个触发请求,成功触发。
漏洞修复
- 将 tomcat 升级至安全版本
参考
- https://forum.butian.net/article/674
- https://www.bilibili.com/video/BV14dQjYcEc5/
- https://www.cnblogs.com/smileleooo/p/18772389
CVE-2024-50379(条件竞争代码执行)
漏洞描述
由于 Apache Tomcat 在路径校验逻辑中存在缺陷,当在不区分大小写的系统(如 Windows )上启用了 default servlet 的写入功能(默认关闭)时,攻击者可构造恶意请求绕过路径一致性检查,从而可能上传webshell 并造成远程代码执行。漏洞利用需要条件竞争,对网络以及机器性能环境等有一定要求。
影响版本
- 11.0.0-M1 <= Apache Tomcat < 11.0.2
- 10.1.0-M1 <= Apache Tomcat < 10.1.34
- 9.0.0.M1 <= Apache Tomcat < 9.0.98
环境搭建
复现环境:Windows + Tomcat 9.0.96
将 Tomcat 中的 config/web.xml 配置如下(加入 readonly 选项)大约 115 行处。
1 | <servlet> |
启动项目:
1 | /bin/catalina.bat run |
接着访问默认端口 8080:
漏洞复现
使用 Burpsuite 构造一个 PUT 数据包,如下:
1 | PUT /a.Jsp |
然后再构造一个访问 PUT 请求创建文件的数据包:
1 | GET /a.jsp |
将两个请求都发送到 Intruder 模块,然后都设置为无限重发。
开启两个请求的重发,接着等一段时间,就疯狂的弹出画图工具:
漏洞修复
- 将 Tomcat 升级至安全版本。
- 临时修复:若配置了 readonly 参数,则可以在 Tomcat 程序根目录 /conf/web.xml 中将 readonly 参数设置为 true 或将配置代码注释或移除。
参考
CVE-2020-1938(AJP 文件包含漏洞)
漏洞描述
由于 Tomcat AJP
协议设计上存在缺陷,攻击者通过 Tomcat AJP Connector
可以读取或包含 Tomcat
上所有 webapp
目录下的任意文件,例如可以读取 webapp 配置文件或源代码。此外在目标应用有文件上传功能的情况下,配合文件包含的利用还可以达到远程代码执行的危害。
影响版本
- Apache Tomcat 9.x < 9.0.31
- Apache Tomcat 8.x < 8.5.51
- Apache Tomcat 7.x < 7.0.100
- Apache Tomcat 6.x
漏洞原理
tomca t默认的 conf/server.xml
中配置了 2 个 Connector
,一个为 8080 的对外提供的 HTTP 协议端口,另外一个就是默认的 8009 AJP 协议端口,两个端口默认均监听在外网 ip。
详细请参考:https://mp.weixin.qq.com/s/GzqLkwlIQi_i3AVIXn59FQ
环境搭建
执行如下命令启动一个Tomcat 9.0.30:
1 | cd vulhub/tomcat/CVE-2020-1938 |
此时公网也开启了 Tomcat AJP 协议的 8009 端口:
漏洞复现
复现脚本:https://github.com/YDHCUI/CNVD-2020-10487-Tomcat-Ajp-lfi
1 | python CNVD-2020-10487-Tomcat-Ajp-lfi.py 120.48.128.24 -p 8009 -f WEB-INF/web.xml |
漏洞修复
- 将 Tomcat 升级至安全版本
- 临时禁用 AJP 协议(不推荐)
参考
- https://github.com/vulhub/vulhub/blob/master/tomcat/CVE-2020-1938/README.zh-cn.md
- https://mp.weixin.qq.com/s/GzqLkwlIQi_i3AVIXn59FQ
CVE-2017-12615(PUT 任意文件写入漏洞)
漏洞描述
Apache Tomcat 7.0.0 - 7.0.81 版本攻击者可以利用该漏洞向服务器写入非 JSP 后缀的文件,利用操作系统特性,可将非 JSP 后缀的文件修改为 JSP 后缀,最终导致命令执行。
影响版本
- Apache Tomcat 7.0.0 - 7.0.81
漏洞原理
Tomcat 配置允许使用 PUT 请求方法(在 web.xml 文件中配置了 readonly = false)。导致我们可以向服务器写入文件。
1 | <servlet> |
虽然 Tomcat 对文件后缀有一定检测(不能直接写jsp),但我们使用一些文件系统的特性(如Linux下可用/)来绕过了限制。
环境搭建
1 | cd vulhub/tomcat/CVE-2017-12615 |
漏洞复现
Linux 服务器
Linux 目录下直接通过 /
结尾可直接写入 JSP 后缀的文件。
1 | PUT /shell.jsp/ |
当出现响应状态码为 201 表示创建成功。
windows 服务器
windows 断可以使用 ::$DATA
的特性进行绕过不能写 JSP 后缀的限制。
1 | PUT /111.jsp::$DATA |
漏洞修复
- 将 Tomcat 升级至安全的版本
- 临时修复将 readonly 设置为 false。