Over the last few days, developers, security engineers, and CISOs have been frantically scanning their software infrastructures for the presence of the Apache Struts 2 framework; one of the most common Java frameworks for building web applications.
This panic was brought on after a new critical vulnerability in the Apache Struts 2 framework was disclosed on Monday, March 6th by the Apache Struts team. The team also released a new Struts 2 version that fixed the bug, resolving the vulnerability.
The vulnerability existed in the Jakarta Multipart parser that is used for file uploads. The logic of the parser that handles the parsing of Content-Type header values can be tricked into executing OGNL expressions provided by an attacker. The result is unconditional code injection and command execution that can be achieved with zero complexity and no authentication. To make things even worse, Struts 2 applications do not even need to implement any file upload functionality in order to be vulnerable. The mere presence of the vulnerable component in an affected Struts 2 application is all that is needed to allow the exploitation. For these reasons the vulnerability is considered to be critical and has been given a CVSS score 10.
The vulnerability was first introduced in the Apache Struts 2.3.5, which was released in October 2012. This is a four-year window of exposure that this zero-day exploit has been under the noses of the developer and security communities. Based on such a long exposure, it is not a surprise to see reports stating that 68 percent of Struts 2 applications are vulnerable to the new CVE-2017-5638 vulnerability.
What is possibly even more alarming is that several Proof-Of-Concept exploits were made publicly available within a few hours of the vulnerability being disclosed. Just a day after the disclosure a Metasploit module was created by Vex Woo, a Metasploit contributor, that made the exploitation trivial to perform even by novice users. Researchers from several security organizations have gathered exploitation statistics and have reported that a huge number of people have attempted to exploit the vulnerability using numerous payloads just hours after the vulnerability was disclosed. This extraordinary activity, which keeps increasing, demonstrates how quickly attackers respond.
To mitigate the attacks there are several possible solutions with the recommended being to upgrade the Struts 2 dependency to Struts 2.3.32 or 188.8.131.52, which contains a fix. However, this is not always possible. Especially when upgrading a four-year-old Struts 2 applications. Such a task could become very difficult, lasting for weeks or even months of development if custom changes have been made. Coding-wise, the closer your Struts version is to Struts 2.3.32 or 184.108.40.206 the easier it would be to upgrade. However, even if the upgrade process can be achieved relatively easily, extensive QA, UAT, and Integration Tests needs to be performed before the new version is deployed into production. Such deployment problems become a true nightmare for enterprise organizations that host thousands of applications on several thousand nodes. Migrating to another MVC framework and completely remove the Struts 2 dependency is not feasible in most cases because it requires an almost complete rewrite of the application.
Another alternative would be to switch to a different implementation of the Multipart parser, such as the Pell parser plugin. Note that because the Pell parser plugin is offered with the LGPL license it must be manually downloaded and deployed in the classpath of your Struts 2 app. Then, the Struts 2 configuration needs to be changed to use the Pell parser instead of the Jakarta parser.
If it is not possible to change the configuration source code of a Struts 2 application then an alternative way to protect the application would be to use a WAF. This approach has significant disadvantages, mostly because of their heuristic nature. WAFs use naive rule triggers, pattern matching, regular expressions, and/or black/white lists. Any article that explains how such WAF solutions work, describes how profiling of each application is required before enabling any such protection. After profiling, custom rules may be required by security experts that understand the technical specifics of each application. And even after all this effort, the protection will still not be adequate due to the heuristic nature of WAFs. These heuristic approaches are guaranteed to produce false positives that will disrupt the normal service of the applications.
All the above practices indicate that attackers will always win the zero-day race. Attackers have the significant advantage of having available robust exploits from the moment of disclosure. Defenders, on the other hand, are racing to detect the vulnerable components in their infrastructure, make source code or binary changes, apply custom configurations, perform extensive tests, and reliably deploy the changes in their production servers. This lost time gives the advantage to the attackers to perform their exploits knowing that the vast majority of their attempts they will successfully compromise the target systems.
Despite the criticality of the vulnerability and the effort that is needed to mitigate it, a Tier-1 Global Investment Bank with hundreds of deployed Java applications on thousands of production nodes did not sweat at all about it. This is because their Java apps have self-healing capabilities. This is achieved by the use of a runtime protection via virtualization, which controls the application’s runtime environment, hardens the software stack, patches known CWEs and CVEs in real-time, and blocks any detected attack. This protection is achieved with no false positives and minimal performance overhead.
Because of the fact that all publicly available POCs of this new Struts 2 vulnerability perform Remote Command Execution (RCE) the bank was already protected against any zero-day RCE exploits, the available POC exploits, and the Metasploit module even before the public disclosure of the vulnerability because their deployed runtime protection solution was already mitigating command injection attacks.
However, the powerfulness of runtime protection via virtualization does not stop there. Using a simple virtual rule that was provided by the vendor in less than 24 hours after the disclosure the vulnerability was completely remediated. The virtual rule was hot deployed without making any source code or binary changes and avoiding the urgency of upgrading.
It is apparent that enterprise organizations have different cybersecurity standards than smaller companies. In such fast-paced and high-demanding environments, critical vulnerabilities must be mitigated as fast as possible usually according to specific SLAs, ideally at a push of a button with no effort and without disrupting the service either because of a restart or because of false positives. Additionally, proactive protection must be in place that mitigates zero-day exploits or reduces significantly their severity with no false positives even before they are publicly disclosed. This is exactly why the advantages of self-healing applications and runtime protection via virtualization are transforming the application security landscape.