Lookups Gone Wild: The New JNDI Injection Angle in CVE-2024-20931

Lookups Gone Wild: The New JNDI Injection Angle in CVE-2024-20931

In Oracle's latest official January 2024 patch, a remote command execution vulnerability CVE-2024-20931 based on the WebLogic T3\IIOP protocol was fixed. This vulnerability was submitted to Oracle by the author in October 2023. In principle, it is a bypass of the CVE-2023-21839 patch, which involves a new attack surface of JNDI. I share it here.

Vulnerability Analysis

CVE-2023-21839 Overview

When a remote object bound to WebLogic via T3\IIOP implements the OpaqueReference interface, when a lookup is performed on the object, the object's getReferent function is called to perform the query.

There happens to be an object called ForeignOpaqueReference, whose getReferent function will initiate a JNDI query again when performing a remote object query, thus causing JNDI injection

The utilization steps are roughly divided into three steps (the key steps are marked with red boxes).

  1. Create a malicious ForeignOpaqueReference object and set the remoteJNDIName to the remote malicious JNDI service.
  2. The malicious object is bound to WLS via the T3\IIOP protocol.
  3. The malicious object is queried through a lookup, triggering the call of ForeignOpaqueReference.getReferent, thus causing malicious JNDI injection.

CVE-2023-21839 Patch Analysis

Oracle officially fixed the vulnerability in January 2023. The patch is divided into two parts.

The first part restricts the setting of providerURL in jndiEnvironment when binding ForeignOpaqueReference objects.

The second part also imposes strict restrictions on the protocol of the loopup JNDI link.

Intuitively, the way to continue to use ForeignOpaqueReference to do JNDI injection has been blocked.

Exploitation of CVE-2024-20931

After some analysis, we can feel that there are three possible paths.
The first path is to find a breakthrough in the getReferent of other classes that implement the OpaqueReference interface (it is interesting that ForeignOpaqueReference is linked in both packages, and the code has some subtle differences).

This approach is feasible, but there are too many classes to analyze, so I did not share it in depth.
The second approach is to try to bypass the JNDIUtils.isValidJndiScheme function in the patch.

I tried a lot, but ultimately failed.
The third way is to do something dangerous if java.naming.provider.url is empty.

Because other envs can still be controlled, it may be possible to create possibilities when specifying java.naming.factory.initial for initialization. Fortunately, WLS provides a lot of InitialContextFactory, and there is exactly one AQjmsInitialContextFactory that needs to obtain the remote DataSource through JNDI during initialization.

By initializing the JNDI injection initiated by AQjmsInitialContextFactory, a secondary JNDI injection was successfully achieved, realizing remote RCE.

Summarize

Compared to the previous JNDI injection vulnerability, this one doesn't seek a breakthrough in the key JNDI injection function of lookup. Instead, it focuses on the initialization phase of Context, thereby bypassing the patch of the previous vulnerability. I personally think it is a relatively interesting vulnerability. Oracle has performed signature verification on the setting of java.naming.factory.initial in subsequent patches. Undoubtedly, there are still some jndiEnvironment settings that can be set. As for whether new bypasses can be found, further research is needed.

Download:
https://github.com/nullcult/CVE_2024_209321.git