
CVE-2020-2551 POC to use in Internet
Test POC (can be used for external network testing)
python CVE-2020-2551.py [HOST] [IP]
Attempt to modify codebase for remote class loading (failed)
python CVE-2020-TEST.py [HOST] [IP]
(First published on Anquanke, original link)
Learning this vulnerability requires some prerequisite knowledge, such as CORBA and RMI.
A brief overview:
CORBA is a set of technical standards formulated by OMG for distributed applications, which uses IDL for cross-language support, and communication between client and server uses the IIOP protocol.
RMI is another distributed application technology. In Java, JNDI can be used to simplify its application. The client and server communicate using the JRMP protocol. However, in weblogic, RMI uses the T3 protocol, for which many vulnerabilities have been reported before.
RMI-IIOP combines the advantages of RMI and CORBA, deploying RMI applications via the IIOP protocol.
The official documentation also mentions:
RMI server objects can use the IIOP protocol and communicate with CORBA client objects written in any language
Leaving weblogic aside for now, let's first focus on how to write an RMI-IIOP example:
Client code can refer to the test project in Java: RMI, JNDI, LDAP, JRMP, JMX, JMS (Part 1). You can compile HelloClient and HelloServer yourself, or use the pre-compiled ones from the test project.
Start the naming server (built-in in Java) from the command line:
start orbd -ORBInitialPort 1050
Start the server-side HelloServer from the command line and configure remote debugging. For how to perform remote debugging with IDEA, refer to the method mentioned at the beginning of this article:
java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005 HelloServer
Of course, you can also just run it directly without remote debugging to see the result. Simply start:
java HelloServer
Start the client from the command line:
Java HelloClient
At this point, the calculator will pop up. If remote debugging is successful, you can see the following call stack:

Command execution in EvilMessage.readObject():

Side note: Articles about weblogic installation and debugging.
Now, what about RMI-IIOP in weblogic? The article About RMI-IIOP in Java mentions exploitation of weblogic RMI-IIOP. Based on it, further research was done. Using WebLogic’s RMI over IIOP discusses several ways for weblogic to use RMI-IIOP clients, including:
The difference between the first two methods seems to be only the JNDI_FACTORY setting:

When studying the weblogic T3 deserialization earlier, I deployed a HelloServer application on weblogic, which has a sayhello() method that can be exploited. I tried setting two different JNDI_FACTORY values and successfully invoked the sayHello() method using the second JNDI_FACTORY:
Then I modified the weblogic T3 protocol POC, simply changing RMI to IIOP. The jtaTransactionManager exploitation chain executed successfully, sending a jrmp request to the local jrmplisten:

Looking at the traffic, when the remove() method is called, a remove__java_lang_Object request is sent. Malicious data is present in the traffic, but the aced magic header is not found:

It is speculated that the server performs special parsing before deserializing the data. Looking at the call stack, the latter part of the execution chain is very similar to the native RMI-IIOP execution chain. The former part is triggered from CDRInputStream.read_value(), while here it is triggered from weblogic's IIOPInputStream.read_value(). (The read_value point was also mentioned in the 2019 Black Hat talk)

Here, the request first goes to clusterableServerRef.invoke() for handling. Based on different invokers, it calls this.invoker.invoke(). Then it calls Mejb_dj5nps_HomeImpl_WLSkel.invoke(). Because it is "remove", it enters case 6 and calls IIOPInputStream.readObject(). In the read_value() method, it parses the IIOPInputStream data and triggers deserialization. This is the POC for exploiting the remove() method.
Lucifaer's analysis [article](https://lucifaer.com/2020/02/25/WebLogic WLS核心组件RCE分析(CVE-2020-2551)/?from=timeline&isappinstalled=0#2-2-Weblogic解析流程) mentions exploiting the bind() method, which is also the mainstream exploitation method on the internet. Let's trace the call stack:

Similar to before, the request first goes to clusterableServerRef.invoke(). Based on different invokers, it calls this.invoker.invoke(). Here it calls CobraServerRef.invoke(), and then in _NamingContextAnyImplBase._invoke(), because va1 is "bind_any", it enters case 0 and calls IIOPInputStream.read_any(). Later, it calls IIOPInputStream.read_value() to trigger deserialization. Earlier, I said that the aced magic header was not seen in the traffic. This is because there is a set of parsing methods in IIOPInputStream. The hex-value form of IIOPInputStream is as follows, which includes the class name and field information:

Eventually, it calls the readObject() method of the malicious class:
