Written by Jeff Hamm and Jason Rebholz

In mid-July of 2013, CVE - a dictionary of publicly known information security vulnerabilities and exposures - identified three potential exploits against the Apache Struts2 web framework. HTTP requests are evaluated by the Apache Struts2 framework. A bug in the Apache Struts2 code allowed attackers to execute arbitrary commands on a web server.

In the wake of this public disclosure, Mandiant has been actively investigating a series of these of attacks. This post is intended to highlight steps an organization can take to determine if they have been attacked from this vector.

Additional information regarding the Apache Struts2 vulnerability is available at the URL https://cwiki.apache.org/confluence/display/WW/S2-015.

Note: All log examples in this post have been sanitized including IP addresses, file names, and time stamps.

Attack Life Cycle

Mandiant's analysis of these compromised systems showed three common threads:

  1. Attackers used search engine queries to identify websites that were running the Apache Struts2 web framework
  2. Attackers copied exploit code from public blogs and scanned vulnerable systems
  3. The initial exploit led to larger compromise

Early Reconnaissance

The earliest identified evidence of reconnaissance Mandiant discovered were search engine (Google or Baidu[1] were the most common) queries that led attackers to a vulnerable entity. In the Apache logs, the referrer field recorded the initial search engine query that led the attacker to the vulnerable entity's web site. We have chosen not to provide a screen capture or specifics regarding this activity because it would demonstrate how many servers may be vulnerable to this type of attack.

[1] Baidu is a Chinese-language search engine.

Scanning Activity

In every investigation involving Apache Struts2, Mandiant identified the same scanners that attempted to identify vulnerable Apache Struts2 instances. The most common scanning activity had the string "'id','goes','here'". This activity didn't result in command execution or creation of web shells. Figure 1 contains an example of this scanning activity.

Figure 1: Scanning activity
Figure 1: Scanning activity

Mandiant also identified scanners that executed commands against the system. This usually consisted of the commands "whoami", "netstat", or "cat /etc/passwd". Figure 2 contains an example of the command execution.

Figure 2: Command execution
Figure 2: Command execution

The command injection was prefaced by "new%20java.lang.String" followed by either "[]{" or the URL encoded "%5B%5D%7B". The command and path come next, such as "'cat','/etc/passwd'" in our example. Finally, the statement is closed with either "})" or "%7D)". In our example, the attacker attempted to display the contents of the "/etc/passwd" file. Figure 3 shows the commands in the GET request in a human readable format.

Figure 3:  Formatted command execution
Figure 3: Formatted command execution


The last type of activity we identified was the creation of web shells and/or exploit kits, which attackers used to gain a foothold on the system. Across all of the investigations, Mandiant identified the two most common web shells names to be "css3.jsp" and "inback.jsp". Mandiant believes attackers used the same code across multiple environments is because:

  • The web shells were publicly available
  • The public sites hosting these web shells included instructive steps on using the Apache Struts2 exploit as an attack vector

The initial web shell was often a simple file upload utility. The statement includes the Java module "FileOutputStream" and "write" (these Java functions are very common, and searching for these functions alone could yield numerous false positives). This code was found on numerous public sites, which listed the instructions as the "JSP writer" or "JSP word" function. Figure 3 shows an example of the web shell creation located in the Apache logs.

Figure 4: Web shell creation
Figure 4: Web shell creation

Figure 5 shows a formatted view of the web shell creation.

Figure 5: Formatted web shell creation
Figure 5: Formatted web shell creation

Search engine searches showed these HTTP requests throughout the Internet on blogs describing how to exploit the Struts2 vulnerability. This likely accounts for the overlap in activity identified during the investigations. Additionally, some attackers were able to successfully upload publicly available exploit kits from the Internet using the "wget" command as an injection.

Figure 6 shows an example of an attacker utilizing the Struts2 exploit to download "exp.py" to the web server from the attacker's website. The attacker placed the file in the "/tmp" directory on the webserver.

Figure 6:  Use of wget
Figure 6: Use of wget

The Compromise

In the cases Mandiant has investigated, the web servers running the Apache Struts2 framework were riddled with web shells and scanning activity. Most of the time, the attackers were battling each other by overwriting web shells with the same file name. The attackers usually had minimal interaction with the web shells - often just a quick HTTP GET request that confirmed that the web shell was running properly. The web shells left behind ensured that the attacker could interact with the system even if the Struts2 vulnerability was patched.

In more serious situations, attackers leveraged a web shell to begin poking around the system and executing system commands. This ultimately led to lateral movement and information theft.

What should you do?

If you suspect that you might have been compromised as a result of the Apache Struts2 vulnerability, we recommend the following specific steps:

1. Check to see if you're running a vulnerable version

Versions prior to of Apache Struts2 are vulnerable. Given the widespread scanning activity, it is likely that if you're running a vulnerable version of Apache Struts2, there will be malicious activity on the server.

2. Create a forensic image of compromised systems

Prior to accessing files or scanning the system, take a forensic image of the system. This will ensure that time stamps are as fresh as possible. Your analyst will thank you for this step.

3. Look for Indicators of Compromise (IOCs) in your web logs

There are many unique keywords that can be used during analysis of the web logs. A good start are the keywords "action:", "redirect:" or "redirectAction:".

Struts2 Indicators of Compromise

The examples below are some of the actual IOCs that Mandiant used to assist in identifying the extent of the compromise.

Apache Logs

  • "action:"
  • "redirect:"
  • "redirectAction:"
  • "new+java.io.FileOutputStream(application.getRealPath
  • "(new%20java.lang.String[]'"
  • "(new java.lang.String[]'"
  • "(new%20java.lang.String%5B%5D%20%7B"

File System

  • Web shells in the Struts2 Java web applications path(s) and/or WAR deployments including:
    • "css3.jsp"
    • "jspspy.jsp"
    • "inback.jsp"
    • "Silic.jsp"
    • "index2.jsp"
    • "jobs.jsp"
  • Exploit kits in the "/tmp" directory created by the user "http" or "web"

4. Rebuild and patch compromised systems

After you've fully investigated the incident and determined there was no OS-level access or lateral movement, it's time to move to remediation. The best course of action is to start with a fresh rebuild of the system that has all industry-standard settings in place. Most importantly, ensure that services and application are patched to the latest releases.

For more information on web shells, take a look at a Mandiant webinar on that topic.