
Pre-authentication remote code execution exploit for Oracle WebLogic ADF Faces (CVE-2022-21445, CVSS 9.8). Includes detailed environment setup, payload generation, and remote debugging instructions for penetration testing.
CVE-2022-21445 (CVSS 9.8), a vulnerability is an untrusted data deserialization, identified in the ADF Faces component, which can be exploited remotely by attackers without authentication (pre-authentication) to perform RCE.
This vulnerability was discovered by two cybersecurity experts: PeterJson from VNG Corporation and Nguyen Jang from VNPT. Oracle received this report in October 2021 and took 6 months, until April 2022, to release the patch.
In this article, exploitation focuses on Oracle Business Intelligence version 12.2.1.4.0.
Requirements: Install Windows 10+ Pro or Windows Home (x64) with active license, or use Windows Server (Oracle's products are preferred).
Step 1: Install Java, version jdk 8u112 or later (8Ux), download link: JDKv8U112

Step 2: Install Oracle Database 19c, download link: Oracle 19c
Prepare a folder for database installation, create a path like below and extract the downloaded database zip file into it: C:\app\oracle\product\19c\db_home1
Run setup.application with administrator privileges.

Follow each step by step as instructed in DB Installation Guide
Important note:
At step 8/17, remember to check Create as Container database to open a pluggable database for the upcoming Fusion Middleware installation.

At step 9/17, select character set as Unicode (AL32UTF8).

After the installation is complete, carefully check in Windows Services to ensure that the 4 main services as shown below have RUNNING status.


Step 3: Install SQL Developer, no-jre version, download link: SQLDev-NoJRE

Run sqldeveloper.application with administrator privileges.

Configure parameters for a new connection as shown below, note to change Username and Password (as in the example above: hr), Hostname (default is localhost), Port (default is 1521), SID (the global database name installed in step 2).

If when selecting Test you see a Success message, the connection is successful; then select Connect.
Step 4: Install Fusion Middleware Infrastructure (FMW) version 12.2.1.3.0, download link: FMW_ver_12.2.1.3.0

Step 5: Install Oracle Business Intelligence (OBIEE) version 12.2.1.4.0, download link: OBIEE_ver_12.2.1.4.0
Run setup_bi_platform-12.2.1.4.0_win64.exe with administrator privileges.

Install step by step according to OBIEE Installation Guide
Note: The BI path must match the FMW installation path, e.g., Oracle/Middleware/Oracle_Home.

Step 6: Set up BI Schema using the Repository Creation Utility (RCU)
At the path C:\Oracle\Middleware\Oracle_Home\oracle_common\bin, run rcu.bat as administrator.
Follow the steps below:




Step 7: Set up environment variables for OBIEE

Step 8: Create BI Domain





In step 4, if the system reports fail to logon, check the domain password for correctness.
In step 8, if the system shows an error like the image below, check whether you have activated your Windows license and whether your Windows meets the requirements described.
![]()
Step 9: After setup, access the newly created BI domain at path $Oracle_Home\user_projects\domains\bi\servers\AdminServer\tmp_WL_user\adf.oracle.domain.webapp\i83uao
Copy all jar files from here into a separate folder, share it to the attack machine (for lab environment do this; for real attacks, the attack machine must also have the same setup as the target to obtain the source code).
Also add the coherence.jar library from $Oracle_Home\coherence\lib into this folder.
This folder is crucial for payload success because each FMW or BI version or each machine's environment may differ, so the exact version is needed to minimize risks or exceptions during payload transmission.
Step 10 (only if remote debug is needed; again, if testing in a real environment, since you cannot freely set up the victim machine, the attacker must perform the target machine setup on their own machine to remote debug and check errors.)
Install Mozilla, add Burp Proxy with port 8181.
Enable Remote Debug on the BI server.
Access localhost:9500/console
In Domain Structure -> select bi -> Environment -> Servers

Two servers will appear: the Weblogic AdminServer and the BI bi_server1.

Click Lock & Edit in the upper left corner, select bi_server1 to edit its configuration. Then click Configuration -> Server start -> Scroll to the bottom, select Advanced (if present) -> Click to enter Arguments -> Enter the debug parameters:
-Xdebug -Xnoagent – Xrunjdwp:transport=dt_socket,address=5005,server=y,suspend=n
(you can try 0.0.0.0:5005 if later you encounter errors restarting bi_server1)
Enter the weblogic password (set earlier in the Config BI Domain step) -> Apply change & Restart.
Open Administrator terminal -> Navigate to $Oracle_Home\user_projects\domains\bi\bitools\bin run ./stop.cmd and ./start.cmd to restart bi_server1. During restart, if no errors occur, debug is enabled and listening on port 5005 as above. If there are errors, check the debug parameters for extra spaces or address issues.
Step 1: Download IntelliJ IDEA Ultimate, activate using code found on GitHub.
Step 2 (Only do this step if the attack process throws errors like 500 Server Error, ... due to exceptions in the payload.)
Change the jdk/sdk version of the project to match the target machine (installation as in Target Machine - Step 1).
Create an empty project for source code analysis and remote debugging.
Add all jar files received from the target machine to this project:
Project Structure -> Modules -> Click + -> 1 JARS or Directories -> Add the entire jar folder.


Set up Remote Debugging:
Run -> Edit Configurations -> + -> Remote JVM Debug

Run Remote Debug; if a message appears in the console: Connected … then it's successful.

Step 3:
Clone the code from this repository to your machine, delete the old coherence.jar in the lib folder and replace it with the file you received from the target machine in the previous step.
Next, add it to a project in IntelliJ, add the jar files in lib with the option Add as library.
Check the name of the class LambdaIdentity$.... for the correct Weblogic version; if there is a change, refactor the file and rename it.
Weblogic 12.2.1.3: LambdaIdentity$E12ECA49F06D0401A9D406B2DCC7463A
Weblogic 12.2.1.4: LambdaIdentity$423B02C050017B24DB10DFF759AA56BF
Edit the path to the LambdaIdentity$....class file in Main.java. To get the exact path, there are two ways: You can run javac on the jar file to generate the .class file; another approach is to comment out the main function's code, then run the project normally; the class file path can be found in the target directory.
Check that the jdk and sdk of the project match the target machine.
We see the web.xml file, which describes the servlet-mapping relationships. "resources" is a servlet related to system resources, containing important data and information; therefore, this is a location often targeted by attackers.






Analysis of the findResource() function in RemoteApplicationResourceLoader.class

This function returns a method containing a custom protocol RAStreamHandler(). RAStreamHandler creates a URLConnection object with the value new RAURLConnection.

The RAURLConnection function calls the _getPathBean function.

The _getPathBean function contains a bean object created by calling the getInstanceFromString() function, which processes the input string to extract the corresponding keys (filter).

The input bean string is converted via the SerializationUtils class from URL-encoded form into a URLEncoderPathBean object. If everything is still fine, the subsequent input continues to be passed to the fromURLEncodeString() function.


If the input string encounters an error, it throws an exception. Exceptions mainly come from the library used in the payload, due to version mismatch or incorrect path to the Lambda file.
In the fromURLEncodedString() function, a fromString function is returned with the url parameter, and its code is as follows:

In the fromString function, data is readObject() and returned. It can be seen that the input is not filtered at all. It passes through many functions and finally gets deserialized in fromString(). This is the sink for exploitation. With the sink found, now we need to find the source.
Therefore, to call the aforementioned class, we need a regex in the form “/.*/remote/(.*)”. Consequently, when a router or input path is of the form /em/afr/foo/remote/payload, it will satisfy the structure defined in this file, and RemoteApplicationResourceLoader will be used as the loader in doGet, and the corresponding class file oracle.adfinternal.view.resource.rich.RemoteApplicationResourceLoader will call the overridden function findResource(). So if a payload is sent to the correct address, the data will be transmitted easily without being blocked by any filter.
Here is the final URL used for exploitation:
__hostname:port/contextApp/afr/foo/remote/payload/__
Where contextApp is one of the paths that exists when OBIEE is first installed, such as /em; /bicomposer; ….
Foo is any arbitrary string.
Payload is the string generated when running the Main function of the prepared attack project.
### Code analysis for payload generation
This project follows the gadget chain of CVE-2020-14644

The class LambdaIdentity$E12ECA49F06D0401A9D406B2DCC7463A inherits from AbstractRemotable and is used to interact with the remote system.
By using the Java Reflection API, an attacker can easily retrieve the WorkAdapter from the current execution thread.
Next, they obtain the connectionHandler field of the WorkAdapter and perform a query to retrieve the ServletRequest and ServletResponse from the connectionHandler.
Then, they retrieve the value of the "cmd" header from the request (ServletRequest), and if "cmd" is not empty, execute a shell command corresponding to the current operating system (Windows or Linux/Unix).
Read the output from the shell command and send that result back in the response (ServletResponse).
If any error occurs during execution, it will be printed to the console via the printStackTrace() method.
The ID after the class name LamdaIdentity depends on the version of the Weblogic server. It is a string encoded from the MD5 hash of the class com.tangosol.internal.util.invoke.ClassIdentity. Since this class differs between versions, as mentioned, to avoid payload errors, this must be carefully checked.
Here, a variable cmd is extracted from the header of the incoming request, then added to the Runtime.getRuntime().exec() command below, encoded and decoded using MD5 hex. After being transmitted to the OBIEE system, it returns a deserialized value.
Finally, in the Main function, a RemoteConstructor object is created, and through the SerializationUtils library, it is converted into a URL-encoded string. This string is passed directly into the source URL, giving attackers the opportunity to inject an arbitrary __cmd__ command.

## Exploitation Reproduction


## Reference
1. https://peterjson.medium.com/miracle-one-vulnerability-to-rule-them-all-c3aed9edeea2
2. https://testbnull.medium.com/oracle-access-manager-pre-auth-rce-cve-2021-35587-analysis-1302a4542316
## Author of Vulnerability: Jang Nguyen & Duc PeterJson