Strutting to Remote Code Execution Anatomy of CVE-2018-11776

By Radu-Emanuel Chiscariu | Here at the Application and Threat Intelligence (ATI) Research Center, our team analyzes current security threats captured in the wild by our honeypots to determine the malicious actors’ weapons and strategies. The result of such research is usually a strike, which is a set of directives that the BreakingPoint security test solution uses for the generation of traffic that mimics the behavior of a specific threat, or a signature to identify malicious IP addresses for our ThreatARMOR product. In effect, the customer can use the BreakingPoint strikes to test the security of their infrastructure and ThreatARMOR to protect their network from attacks.

A recently discovered threat is CVE-2018-11776, a highly-critical expression language injection vulnerability within the Apache Struts Core open-source Web application framework. Successful exploitation of this vulnerability allows remote code execution under the privilege of the user running the web service.

This vulnerability is similar in terms of exploitation conditions to CVE-2017-5638, another Apache Struts flaw that was at the root of the Equifax breach. A failure to patch the vulnerability lead to the exposure of personal details for 147 million consumers.

VULNERABILITY ANALYSIS

A security bulletin on this vulnerability was published on August 22nd, stating that the affected versions are Struts 2.3 to 2.3.34 and Struts 2.5 to 2.5.16, with the side note that older, unsupported Struts versions may be also affected.

The vulnerability can be triggered if a Struts configuration file (struts.xml) contains an "action" or "url" tag that does not specify the optional namespace attribute or specifies a wildcard namespace, for example “/*”, as shown in the configuration file provided below. Another requirement is that the alwaysSelectFullNamespace flag must also be set to true in the Struts configuration, and this is the default Struts configuration setting. In effect, any clean install in which a new package is configured with no explicit declaration of the namespace attribute is vulnerable to this threat.

Remote code 1

Struts vulnerable configuration. Comments are added for clarity.

Under these conditions, parseNameAndNamespace() method is called to extract the namespace component without any validation (line 27). Sample code below was taken from struts2-core.jar version 2.3.12.

Remote code 2

Code snippet from DefaultActionMapper.class. Comments are added for clarity.

The namespace from URI, which is in control of the attacker, is then passed to the namespace variable of ServletActionRedirectResult.class via a call to getNamespace() method (line 6). Then, a new ActionMapping object is instantiated (invocation), containing the attacker-controlled namespace variable (line 21). This flows into execute() method (line 26):

Remote code 3

Code snippet from ServletActionRedirectResult.class Comments are added for clarity.

Finally, the namespace is evaluated as an Object Graph Navigational Language expression, resulting in arbitrary code execution (line 11). OGNL is a dynamic Expression Language (EL) that can be used for getting and setting properties of Java objects. OGNL expressions contain strings combined to form a navigation chain. The strings can be, for example, property names, method calls, or array indices. OGNL expressions are evaluated against the initial, or root context object supplied to the evaluator in the form of OGNL Context. OGNL is the primary EL used by Struts. An expression such as %{<ognl_exp>} or ${<ognl_exp>} will force OGNL evaluation of an attribute that would normally be a string.

Remote code 4

Code snippet from StrutsResultSupport.class. Comments are added for clarity.

A security patch for this vulnerability was published by the Apache Struts team with the release of Struts versions 2.3.35 and 2.5.17. The fix essentially ensures that the namespace attribute contains valid characters.

Remote code 5

The security patch for Apache Struts 2 vulnerability.

EXPLOITATION

Just one day after the security advisory has been released, exploits for this vulnerability have already started to show up on Github. Some of them come together with Dockerfiles or even explicit steps to set up a vulnerable environment.

demogif

Proof of Concept: Exploiting the CVE-2018-11776.

A vulnerable request would look like this:

Remote ,code 7

CVE-2018-11776 - malicious request sample.

The vulnerability can be exploited using other HTTP methods too, such as POST, HEAD, PUT, OPTIONS, DELETE and PATCH.

ACTIVITY IN THE WILD

At the time of writing, over 300 attacks targeting vulnerable instances of Apache Struts2 had been caught by our honeypots starting with July 14th, which is 5 weeks after the patch has been committed to the Struts core project. While some of the malicious requests attempt to probe whether the Struts instance is vulnerable (by sending a valid, simple OGNL expressions within the namespace field), the others attempt to execute different bash commands remotely.

splunk time chart

CVE-2018-11776 – related activity: Splunk timechart.

Volexity also reports active scanning and attempts to exploit CVE-2018-11776 in order to deploy cryptocurrency miners.

CONCLUSION

With almost 40,000 instances live on the Web, Apache Struts platforms continue to be targeted by malicious attackers. Even if the vulnerability requires certain server-side conditions to be exploitable, this could potentially lead to another Equifax event. In effect, our team recommends immediate patching, either to version 2.3.35 or 2.5.17.

The ATI Research Center continuously monitors threats as they appear in the wild. Customers of our BreakingPoint product have access to strikes for CVE-2018-11776, allowing them to test their currently deployed security control’s ability to detect or block such attacks; this capability can afford you time to patch your deployed web applications based on Apache Struts. Our monitoring of in-the-wild attackers ensures that such attacks are also blocked for customers of Ixia ThreatARMOR.

limit
3