CVE Explained
g4rg4m3l,
Nov 06
2024
In January 2024, Sonar’s Vulnerability Research identified a new vulnerability in Jenkins that could allow an attacker to read the first few lines of arbitrary files on servers, and could be used for remote code execution.
CVE-2024-23897 is a file read vulnerability discovered in Jenkins, an open-source continuous integration/continuous delivery and deployment (CI/CD) software, and it affects versions 2.441, LTS 2.426.2, and earlier.
After discovery, this vulnerability was assigned a Critical CVSS rating of 9.8 out of 10. It exploits an issue in the built-in command line interface (CLI) of the Jenkins server that allows users to read at least the first few lines of arbitrary files on the server, up to entire files. It can also lead to arbitrary code execution, although this requires more information.
The vulnerability was discovered along with CVE-2024-23898, which is a cross-site WebSocket hijacking (CSWSH) vulnerability affecting the same software. The team first published their discovery on the Jenkins Security Advisory and on Sonar's blog on January 24th.
On January 30, 2024, Censys reported that there were 83,509 Jenkins servers on the Internet, and of those, 79,952 were running a version vulnerable to CVE-2024-23898.
At the time of writing this post (18th October), only 4.2% of the hosts running Jenkins on the Internet are safe from this vulnerability—which means it poses a risk to 95.7% of Jenkins servers.
In response to this vulnerability, we released the machine Builder, a medium-difficulty Linux box that features a Jenkins instance that is found to be vulnerable to CVE-2024-23897 and allows unauthenticated users to read arbitrary files on the Jenkins controller file system.
An attacker is able to extract the username and password hash of the Jenkins user “jennifer”. Using the credentials to log into the remote Jenkins instance, an encrypted SSH key is exploited to obtain root access on the host machine.
This vulnerability has led from the arbitrary file read to stakes as high as a bank heist.
On July 31, 2024, the National Payment Corporation of India (NPCI) announced a temporary halt to all retail payments in several banks, citing a possible ransomware attack involving one of their service providers.
This news was followed by another announcement that a service provider to the bank, Brontoo Technology Solutions, had fallen victim to a ransomware attack, forcing the NPCI to temporarily close all retail payments in the affected banks and for customers.
The attack originated from a misconfigured Jenkins server allowing the attackers to use CVE-2024-23897 to gain unauthorized access to the victim’s environment, as reported by CloudSEK's threat research team.
They were then able to achieve remote code execution by accessing the private keys of the vulnerable system and using them to connect to an open SSH port.
When a client sends a request with commands in the Jenkins server CLI, it makes a request to the “/cli” directory of the server. The Jenkins CLI uses the Java library Args4j to parse these command arguments.
When parsing a new argument, the Args4j library executes the "expandAtFiles()” method, which treats any string after a “@” symbol as a file path.
This results in Jenkins replacing the “@” character followed by a file path in an argument with the actual file’s contents (hence the name “expandAtFiles”(. The expandAtFiles() method is enabled by default and cannot be disabled for Jenkins 2.441, LTS 2.426.2.
In the following example, we execute the version command followed by the string “@/etc/passwd.”
This command does not take any arguments, but the vulnerability allows us to leak part of the “/etc/passwd” file in the exception response.
Although password hashes in modern systems are stored in /etc/shadow, attackers can still leverage the /etc/passwd file for valuable information.
This includes gathering a list of valid usernames to use in brute force attacks, identifying service accounts that could potentially lead to privilege escalation, and identifying paths to user home directories to locate SSH keys.
If an attacker finds a command that takes an arbitrary number of arguments, they could leak file contents by passing a string containing the “@” symbol followed by the name of the file. As the Sonar team found out, the connect-node command is suitable for that effect.
This command requires the CONNECT permission, verified by the [cliConnect](URL_1) method. However, if an exception is thrown, the permission made by the [resolveForCLI](URL_2 "resolveForCLI") method never takes place.
Since the exception is thrown before the `cliConnect` permission check occurs, the command is no longer dependent on the CONNECT permission. Instead, the only requirement for executing the command is the initial [read-only verification](URL_3 "read-only verification").
The “read-only” feature in Jenkins allows non-administrator users to access system information without the ability to modify it. This feature helps users troubleshoot and debug build issues more easily, without requiring elevated privileges or assistance from administrators.
This means that an attacker could execute the `connect-node` command and pass the string “@/etc/passwd”, then Jenkins will respond by leaking the contents of the files.
The Local File Disclosure is limited as we can only read around 19 lines from the file, however there are some extremely sensitive files we can read that could allow us to gain the ability to remotely access the server.
The most common next step, takes advantage of the fact that Jenkins doesn't use a traditional database, instead it uses XML Files for Persistent Storage. This is important because it means a File Disclosure Vulnerability has a greater chance of being able to access sensitive data like password hashes.
(This attack path is shown in the Builder machine, so check that out if you want to know more.)
There are multiple ways to identify a vulnerable Jenkins version, but for this example, we’re using the WhatWeb tool and trying to execute the vulnerability.
To interact with the Jenkins CLI, you must first download the JAR file for the command-line client from the "/jnlpJars/jenkins-cli.jar" path on a local server.
By using the client to communicate with the Jenkins server, we can take advantage of CVE-2024-23897 to read arbitrary files on the target, as described in the previous section. Use the `connect-node` command and pass a string that starts with "@" followed by the name of the file we want to read.
For our proof of concept, we will try to read the `/proc/self/environ` file, which lets us retrieve the Jenkins base directory on the target.
java -jar jenkins-cli.jar -s http://jenkins:8080/ connect-node "@/proc/self/environ"
Next, we specify a sensitive file, such as like master.key or secrets.key
We can also read other sensitive files, such as etc/passwd, using the same command.
If any SSH private keys are stored on the server, an attacker could use the above methods to leak them. This lets them expand the attack by logging into the server or other systems on the compromised network, where they can attempt remote code execution.
Editor’s note: Some may find it misleading to say the file disclosure vulnerability will result to leaking ssh keys without mentioning the steps in the middle. The attackers likely used the CVE to leak the user password, gained access to the jenkins instance, and then used the groovy console to decrypt ssh keys.
The best way to address the CVE-2024-23897 vulnerability is to update Jenkins to the latest version. Jenkins versions 2.442, LTS 2.426.3, and LTS 2.440.1 have disabled the command parser expandAtFiles() feature.
However, if updating is not an option, Jenkins security advisor recommends that users disable CLI access to prevent exploitation. Documentation for this workaround can be found at the Jenkinsci-cert GitHub repo.
HTB releases new content every month that’s based on emerging threats and vulnerabilities. This allows teams to train on real-world, threat-landscape-connected scenarios in a safe and controlled environment.
In response to this vulnerability, we released the machine Builder, a medium-difficulty Linux box that features a Jenkins instance that is found to be vulnerable to CVE-2024-23897 and allows unauthenticated users to read arbitrary files on the Jenkins controller file system.
An attacker is able to extract the username and password hash of the Jenkins user “jennifer”. Using the credentials to log into the remote Jenkins instance, an encrypted SSH key is exploited to obtain root access on the host machine.