Software Integrity Blog

 

CVE-2017-5638: The Apache Struts vulnerability explained

We explain the critical Apache Struts vulnerability CVE-2017-5638: What is it? Why did it occur? How can an attacker exploit it? How can you mitigate it?

CVE-2017-5638 explained: The Apache Struts vulnerability

With good reason, a lot of attention has been given to the recent vulnerability in the Struts MVC framework (CVE-2017-5638). Because of its extensive functionality, Struts is a widely used open source component in web applications. However, these same benefits and Struts’ integration with other frameworks can make upgrades and patches challenging. My goal is to explain how an attacker might exploit this Apache Struts vulnerability.

RELATED: Equifax, Apache Struts, and CVE-2017-5638 vulnerability

What is CVE-2017-5638?

Struts is vulnerable to remote command injection attacks through incorrectly parsing an attacker’s invalid Content-Type HTTP header. The Struts vulnerability allows these commands to be executed under the privileges of the Web server. This is full remote command execution and has been actively exploited in the wild from the initial disclosure.

The vulnerable code is in the Jakarta Multipart parser. If the Content-Type value isn’t valid, that is, it does not match an expected valid type, an exception is thrown that is then used to display an error message to a user. In this case, we can set the Content-Type to an OGNL expression such as:

Content-Type: ${(#_='multipart/form-data').

How did this Apache Struts vulnerability occur?

The vulnerability occurs because the Content-Type is not escaped after the error, and is then used by LocalizedTextUtil.findText function to build the error message. This function will interpret the supplied message, and anything within ${…} will be treated as an Object Graph Navigation Library (OGNL) expression and evaluated as such. The attacker can leverage these conditions to execute OGNL expressions that in turn execute system commands.

OGNL is also an expressive and extensive language in and of itself. It’s a very powerful and reliable tool for the attacker. Many core JAVA functions can be exposed, for example, java.core.ProcessBuilder() allows an external program to be run on the system.

Exploitation is also further facilitated by the ability to receive information back from the server on the status and output of the commands that are executed by the web server. No additional communication channel is needed, which aids in minimizing detection and bypassing outgoing firewall rules.

The curl command shown above demonstrates whether the server is vulnerable or not by sending an http request with an embedded OGNL expression in the Content-Type header and receiving a response.

The OGNL expression sets default access rights to the members of the OgnlContext JAVA object, which represents the execution context of the expression. It empties the blacklist of excluded packages and classes to expose more functionality.

Variable “#eps” is set to the container objects String representation via its toString() method to demonstrate potential manipulation of core servlet parameters safely and to provide a string to return to the user via the system echo command.

#eps=#container.toString()

#cmds=({'/bin/echo', #eps})

A JAVA ProcessBuilder object is created with the echo command that outputs the String value. Using further JAVA functionality, the input stream of this process is redirected to the output stream of the servlets response. This allows the servlet to respond to the attacker with information, as can be seen with a response:

com.opensymphony.xwork2.inject.ContainerImpl@d0d2b00

This command is safe and demonstrates remote command execution, java functionality and an exfiltration channel.

Exploits and proofs-of-concept for this vulnerability are widely available, substantially lowering the expertise required to execute an attack. Because Struts is widely used, non-targeted attacks are also likely to occur.

RELATED: Attacks on CVE-2017-5638 critical vulnerability escalating

How do I mitigate CVE-2017-5638?

Web application firewalls such as mod_security could mitigate this attack if the rules are set to whitelist valid content types or blacklist OGNL expressions. An alternative mitigation to upgrading Struts is to switch to using Jason Pells multipart parser. This plugin replaces the vulnerable Struts component and can be installed by copying the plugin jar into your application’s /WEB-INF/lib directory. The library will need to be included in your application as well.

Get the 2019 OSSRA report

This post was originally published on April 6, 2017 and refreshed Sept. 14, 2017.