Hello friend, I’ll talk about a SSRF vulnerability i got with my friend Ahmed Elmorsi in a private bug bounty program. I’ll have a quick introduction about SSRF itself from OWASP:
SSRF is an attack vector that abuses an application to interact with the internal/external network or the machine itself. One of the enablers for this vector is the mishandling of URLs, as showcased in the following examples:
1. Image on an external server (e.g. user enters image URL of their avatar for the application to download and use).
2. Custom WebHook (users have to specify Webhook handlers or Callback URLs).
3. Internal requests to interact with another service to serve a specific functionality. Most of the times, user data is sent along to be processed, and if poorly handled, can perform specific injection attacks.
The program was cloud banking platform that enables innovative banking providers to rapidly create, launch, and service loan and deposit products according to their description. The subdomain we’re testing had 2 permissions Admin&User which we found 2 more vulnerabilities in the privileges between the 2 permission but we’re more interested in the Process feature. As its name shows the feature allows users to create a task or set of tasks to be executed after it meet some condition the user can specify like do something after x is equal to y and so on. One of the tasks was called API Call and as the name suggests it was worth give it a shot for SSRF. Once you added the task to the process it allows you to specify the Host and the method:
So for a quick try with full of hope we tried the GET method with (http://169.254.169.254) to get the AWS instance metadata but we got 403 response:
We tried several bypasses like IP obfuscation with tool like (https://github.com/vysecurity/IPFuscator), getting a redirect to 169.254.169.254 with (http://nicob.net/redir6a) and IPv6 but none of them worked. We remembered DNS Rebinding attack and its online tool (https://lock.cmpxchg8b.com/rebinder.html). A DNS Rebinding attack is a way to manipulate the resolution of domain names, so the same domain name can be resolved between 2 IPs in short time which is called TTL(time-to-live). We used google IP with 169.254.169.254 in the tool(https://lock.cmpxchg8b.com/rebinder.html) and got our domain name that will be resolved between the 2 IPs and used it in the API Call task, and after multiple tries we got our first different response:
We’re like:
We didn’t understand why we’re getting the 401 but the response header (server: EC2ws) was an indication for us that we hit the internal AWS instance then we reported as Blind-SSRF and the team rejected it:
We tried with the team again and after 3 days we figured out according to the documentation here(https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-identity-documents.html) that we need to add the header (X-aws-ec2-metadata-token-ttl-seconds: 21600
) to get a token then we use the returned token with the header (X-aws-ec2-metadata-token: TOKEN
). The API Call task allowed us to add custom header( thankfully ):
Once we tried the new header with domain name from rebinder after some tries we got our savior response:
Then used the returned token with the header (X-aws-ec2-metadata-token
):
We finally did it after trying 3 days to get it done:
We updated the report with the final findings with detailed steps to get the same results as we did, and here’s the team response after 3 days of discussing the vulnerability:
After arguing more with the team they decided to reward us with 500$ for the confusion and the troubles
That’s everything and i hope you enjoyed it. Peace.