Finding and exploiting SSRF
Previous year Cyber Eagle discovered a Server-side Request Forgery (SSRF) vulnerability in a website owned by a Fortune Global 500 company. The issue has been reported to the Product Security Response Team. Solving the issue took a half year. Cyber Eagle asked for permission to publish the vulnerability, however, this was only allowed if the post is fully anonymized.
Because the company itself does not publish reported vulnerabilities, Cyber Eagle has decided to transform this post into an educational post. And try to explain every step along the way. This post will cover the following subjects:
- Exploiting SSRF to scan the internal network
- Exploiting SSRF to obtain AWS Secret Access key
- Bypassing SSRF mitigations
- SSRF mitigation advice
Initial discovery started with trying to register an account. The registration page contained a couple of text boxes containing the terms of services defined as forms, which would load in the text with a slight delay. Indicating that the terms might be fetched from an external resource.
Opening developer tools in the browser and inspecting the network tab indicates a classic SSRF vulnerability. SSRF allows you to make requests originating from the server itself.
SSRF is easily found by keeping an eye open for external resources being included in the requests you make. This can be either in POST or GET. In GET requests SSRF is often found by looking for query parameters like: URL, target, URI
If you find an external resource linked in the request you make, fill in the burp collaborator URL and see if the server makes a request to your burp collaborator URL.
Expoiting SSRF to scan the internal network
Once you have confirmed that the vulnerability is indeed a SSRF vulnerability. It is time to look into ways to exploit the SSRF vulnerability. There is multiple ways of exploiting SSRF and this paragraph will focus on exploiting the internal network using SSRF.
With SSRF it is possible to make a request originating from the server, which means you can often make requests to the internal network or DMZ.
The easiest test to start with is SSRF on the localhost. This can often be done by targeting HTTP or HTTPS of the localhost. Most often this will show the website which you were already visiting. You can expand the localhost scan by using burp intruder and including a port number as shown in the screenshot below.
Once you finished scanning the localhost, you can continue testing the internal network. This might be a bit more difficult because the private IPv4 range is quite big. In some cases, you might have found the internal IP by looking around for other vulnerabilities. However not in this specific case.
Using burp intruder you can brute-force the private IP range, to narrow down the range you can perform a brute-force on for example 10.y.x.1 or 10.y.x.254. Where you brute-force both x and y, and hope that there is a server on 1 or 254. Performing this brute-force resulted in the discovery of an exposed Elastic Search cluster. Digging around in the Elastic Search cluster revealed logging containing refresh tokens, which most likely could lead to the compromise of certain applications.
SSRF can also be used to exploit certain URL schemes, these weren’t successful in this case. You can read more about that here.
Exploiting SSRF to obtain AWS Secret Access key
When you are dealing with SSRF, it is important to know where the server is hosted. This can be easily checked by doing a whois lookup on the IP address of the server involved. In this case, it was an AWS server, however other cloud instances are interesting as well. Read this for more information on SSRF regarding cloud instances.
AWS Secret Access keys can be easily found by going to the following URL:
Exposing these keys does not always result in compromise of the server. The keys can be protected by using least privileges principal. If you find AWS Secret Access keys and want to test them Cyber Eagle recommends using pacu.
Bypassing SSRF mitigations
After finding the AWS Secret Access keys, Cyber Eagle has sent a responsible disclosure report to the company involved. It took quite a while, but eventually, mitigating measures were taken. These however were proven to be ineffective.
The mitigation consisted of simply checking if the correct domain was present in the URL. For example, this would be valid:
Changing example into something else would result in a white page. The mitigation can be bypassed in multiple ways:
For more bypasses read this.
SSRF mitigation advice
As shown in the paragraph before, simply checking for the presence of a string might not be enough. The first piece of advice would be to not trust user input at all. The terms don’t need to be loaded through user input and could’ve easily been fetched from a static URL defined on the server-side. If user input is needed then it is advised to parse the complete URL and compare it to a list of whitelisted domains.
When it comes to AWS, IMDSv2 should’ve been used. IMDSv2 requires the user to provide an extra header containing a token. Most often it is not possible to add extra headers when abusing SSRF, which would mitigate this vulnerability.
I hope you liked this educational write-up of a pretty severe SSRF I’ve discovered. It is a classic example of SSRF, containing almost every aspect which can be explored in SSRF exploitation. Even though it didn’t lead to full compromise I feel that there was enough to do some damage. For example, the Elastic Search logging and refresh tokens can definitely be exploited. I was unable to exploit the AWS Secret Access key, even after consulting a senior SRE for advice.