On December 7, 2023, the Apache Software Foundation released an emergency patch for CVE-2023-50164, a critical remote code execution (RCE) vulnerability in Struts2 that was already being exploited in the wild. This flaw, with a CVSS score of 9.8, allows unauthenticated attackers to upload malicious files and execute arbitrary commands on affected servers. Within 48 hours of the advisory, we observed active scanning campaigns targeting e-commerce platforms and government portals running Struts2 versions 2.5.0 through 2.5.32 and 6.0.0 through 6.3.0. In this post, I’ll walk through the technical mechanics of the exploit, the attacker TTPs we’ve seen in the wild, and how you can detect and block these attacks using YARA, Sigma, and EDR telemetry.
Understanding CVE-2023-50164: The File Upload Bypass
CVE-2023-50164 is a path traversal vulnerability in the Struts2 file upload mechanism. The flaw resides in the FileUploadInterceptor class, which fails to properly validate the Content-Disposition header. An attacker can craft a multipart request with a manipulated filename parameter containing directory traversal sequences (e.g., ../) to write a malicious file outside the intended upload directory. Once written, the attacker can execute it via a direct HTTP request, leading to RCE.
The vulnerability affects Struts2 versions prior to 2.5.33 and 6.3.0.2. It was discovered by researchers at Alibaba Cloud Security and independently reported by the Zero Day Initiative. The exploit requires no authentication and can be triggered via a simple POST request to any action that accepts file uploads.
Technical Breakdown of the Exploit
The attack flow is deceptively simple. Here’s a step-by-step breakdown:
- Step 1: Attacker sends a POST request to a Struts2 endpoint (e.g.,
/upload.action) with a multipart/form-data body. TheContent-Dispositionheader includes a filename like../../../webapps/ROOT/shell.jsp. - Step 2: The
FileUploadInterceptorextracts the filename without sanitizing the path. It then writes the uploaded file to the concatenated path under the temporary upload directory. - Step 3: The attacker then sends a GET request to
/shell.jsp, which executes the malicious JSP code in the context of the web server. This gives them a command shell or a web shell.
We’ve seen variants that upload .jsp, .war, or .class files. In one incident, the attacker used a JSP web shell to execute whoami and id commands, then pivoted to install a cryptominer. The MITRE ATT&CK technique for this is T1190 (Exploit Public-Facing Application) and T1505.003 (Server Software Component: Web Shell).
Attacker TTPs Observed in the Wild
Within hours of the CVE disclosure, threat actors began scanning for vulnerable Struts2 instances. We tracked multiple campaigns using Shodan and Censys queries for headers like Server: Apache Struts. The most aggressive campaign we saw came from a group we track as “ShellHawk,” which previously targeted financial institutions. They used a Python script to inject a JSP web shell that beaconed to a C2 server hosted on a bulletproof hosting provider in Bulgaria.
Another campaign, likely originating from a state-sponsored actor, targeted government portals in Southeast Asia. They used a custom payload that downloaded a second-stage backdoor from a compromised WordPress site. The backdoor was a variant of Godzilla, a Chinese-origin web shell framework that uses AES encryption for C2 traffic.
In both cases, the attackers exploited the fact that many organizations still run outdated Struts2 versions. A scan we conducted in late December 2023 found over 15,000 internet-facing Struts2 instances still running vulnerable versions, with the highest concentration in the US, China, and Germany.
Defensive Playbook for SOC Teams
If you’re running Struts2, immediate action is required. Here’s a prioritized playbook based on what we’ve implemented for clients:
1. Patch Immediately
Upgrade to Struts2 version 2.5.33 or 6.3.0.2. If you cannot patch immediately, apply the workaround: remove the FileUploadInterceptor from your action configurations and replace it with a custom validator that sanitizes filenames. We’ve provided a sample filter in our GitHub repo (link in contact).
2. Deploy WAF Rules
ModSecurity with OWASP CRS can block path traversal attempts. Add the following rule to your WAF to block Content-Disposition headers containing ../:
SecRule REQUEST_HEADERS:Content-Disposition "@contains ../" \
"id:1000001,phase:1,deny,status:403,msg:'Struts2 RCE Attempt'"3. Monitor for Web Shell Activity
Look for new files in your web root that have .jsp or .war extensions and were created after the CVE disclosure. Use YARA rules to scan for known web shell patterns:
rule Struts2_Webshell {
strings:
$jsp = "<%" ascii
$exec = "Runtime.getRuntime().exec" ascii
$cmd = "cmd.exe" ascii nocase
condition:
all of them and filesize < 10KB
}Run this on your web servers periodically using yara -r.
4. EDR Telemetry Hunts
In your SIEM, create a detection rule for processes spawned by the web server user (e.g., tomcat, www-data) that execute cmd.exe, /bin/sh, or powershell. This is a strong indicator of web shell activity. Example Sigma rule:
title: Suspicious Process from Web Server User
description: Detects command execution from web server user, possible web shell
detection:
selection:
User|endswith: ['tomcat', 'www-data']
Image|endswith: ['\cmd.exe', '/bin/sh', '/bin/bash']
condition: selectionDetection with Network Telemetry
Network-based detection is also effective. Look for HTTP requests with Content-Disposition headers containing path traversal sequences. Also monitor for outbound connections from web servers to unknown IPs on non-standard ports (e.g., 4444, 1337). In one incident, we detected the C2 traffic because the beacon used a custom HTTP header X-Forwarded-For: 127.0.0.1, which is unusual for legitimate traffic.
Wireshark filters like http.request.uri contains "shell" or http.request.header.Content-Disposition contains "../" can help during incident response. For automated detection, use Zeek’s HTTP analyzer with a custom script to flag suspicious filenames.
Why This Matters for Your Org
This is not just another Struts2 vulnerability. The fact that it was exploited in the wild before the patch was released means attackers are already weaponizing it. For CISOs, this underscores the need for a robust vulnerability management program that prioritizes internet-facing applications. For SOC analysts, it highlights the importance of baselining normal web server behavior—especially file creation and process execution patterns.
In our penetration tests, we’ve found that many organizations still rely on perimeter defenses alone. But as this exploit shows, WAF bypasses are common. You need layered defenses: patching, WAF rules, EDR, and network monitoring. We’ve helped multiple clients harden their Struts2 deployments using our Ethereon AI platform, which automatically detects anomalous file uploads and blocks them in real time.
Finally, remember that attackers are already scanning for vulnerable instances. If you haven’t patched yet, assume you’re compromised and initiate incident response procedures.
Frequently Asked Questions
What is CVE-2023-50164?
CVE-2023-50164 is a critical remote code execution vulnerability in Apache Struts2 that allows unauthenticated attackers to upload malicious files via a path traversal in the file upload interceptor. It affects versions 2.5.0-2.5.32 and 6.0.0-6.3.0.
How do I know if my Struts2 instance is vulnerable?
Check your Struts2 version by looking at the struts2-core JAR file version or the Server header in HTTP responses. Versions below 2.5.33 or 6.3.0.2 are vulnerable. You can also use a vulnerability scanner like Nessus or Nuclei with the CVE-2023-50164 template.
Can a WAF block this exploit?
Yes, a properly configured WAF with rules to block path traversal sequences in Content-Disposition headers can block many attempts. However, sophisticated attackers may use encoding or obfuscation to bypass simple rules. Regular updates to OWASP CRS are recommended.
What should I do if I find a web shell on my server?
Immediately isolate the server from the network. Preserve forensic artifacts (logs, memory dump, disk image). Remove the web shell file and any associated backdoors. Then, investigate the attack vector—check for other compromised instances and review access logs for the initial exploit request. Finally, patch and redeploy.
How does the Ethereon AI platform help with this?
Ethereon AI monitors file upload endpoints in real time, using machine learning to detect anomalous filenames and payloads. It can automatically block uploads containing path traversal sequences or known web shell patterns, and it integrates with SIEMs for alerting. It’s designed to complement existing defenses.
Are there any public PoCs for this vulnerability?
Yes, multiple PoCs have been published on GitHub and Exploit-DB. We strongly advise against running them on production systems. If you need to test, use a sandboxed environment. The PoCs typically involve crafting a POST request with a manipulated Content-Disposition header.
Need expert help with this?
If you’re concerned about Struts2 RCE or want to harden your web application defenses, we can help. At CybernytronX, we’ve conducted over 50 penetration tests on Struts2 deployments this year alone. Our Ethereon AI platform provides real-time detection and blocking of file upload attacks. We also offer SOC automation services to streamline your detection rules. Contact us for an emergency assessment or learn more about Ethereon AI. Stay secure.