Hi Guys,

Back with an interesting hack that I was eagerly waiting to get the writeup to publish. This hack is about a chain of vulnerabilities which includes multiple bypasses in a various different layer which finally lead to access of AWS credentials in India’s biggest stock broker company. Below I’ll explain how I was able to access AWS credentials by first bypassing Web application firewall (WAF) and then leveraged it to SSRF via bypassing Web cache mechanism and finally gets hold of AWS account credentials.

(This was done with the explicit permission of the concerned company)

During the first phase of testing, I found an endpoint which was interacting with some file system so I went ahead to check for LFI (local file inclusion) vulnerability and found that application was behind the Cloudflare firewall —

Cloudflare WAF

Now to basically bypass the firewall, I had to directly send my request to the origin server hoping that they don’t have whitelisting of IPs request coming to their servers or load balancers —

Scenario of usual request call

In order to find the origin server IP, I simply ran “dig www.readacted.com” and I had the origin server IP —

Following article can help understand by digging the domain gave the origin server ip — https://support.cloudflare.com/hc/en-us/articles/115003687931-Warning-about-exposing-your-origin-IP-address-via-DNS-records

and then I simply made the entry in the host file and tried the LFI to read /etc/passwd and below is what I got as the response —

Sample Redacted Image

So, I managed to bypass the firewall and able to execute LFI vulnerability. When I searched the IP for the whois information, I found that the IP belongs to AWS. Now the next target was to read AWS account credentials by exploiting SSRF vulnerability which I was hoping it would definitely be there because of the designated functionality of the page/URL so without wasting any time, I proceeded to make the API call to read AWS instance metadata (http://169.254.169.254/latest/meta-data/ )—

HTTP Request to read AWS instance metadata

HTTP/1.1 200 OK

Server: nginx

Date: Fri, 06 Apr 2019 14:32:48 GMT

Content-Type: text/css;charset=UTF-8

Connection: close

Vary: Accept-Encoding

Strict-Transport-Security: max-age=15552000

X-Frame-Options: DENY

X-Content-Type-Options: nosniff

X-XSS-Protection: 1; mode=block

X-Proxy-Cache : HIT

Content-Length: 0

But the response was empty with 200 OK response which meant that it surely interacted with the API and then returned the empty response. But why the response was empty? If you look at the above image, you will find the server header as a “ Nginx ” and response header “ X-Proxy-Cache ” which was set by Nginx cache layer whose value was set as “HIT” which meant that when the client tried to access the AWS metadata API, it first hit the Nginx cache layer and gave the response from the cache which was empty.

Now basically to get the response from the server, I had to bypass the cache layer for which firstly I needed to understand how URL caching paging rule are made in the nginx caching system.

What I understood is that general caching is done on the URL route path basis so if the URL is https://somewebsite.com/a.html and if it matches the route path (which it will because of caching rule) then it would hit the cache but if the URL is https://somewebsite.com/a.html? then the URL route path will not get matched with the caching rule hence it would miss the cache and get the response from the server. So I proceeded to make the call to read AWS instance metadata API ending with ? or any other special character, not matching the URL route path set in the caching rule(http://169.254.169.254/latest/meta-data?) and below is the response I got —

Web Cache Bypass HTTP Request to access AWS instance metadata

HTTP/1.1 200 OK

Server: nginx

Date: Fri, 06 Apr 2019 14:32:48 GMT

Content-Type: text/css;charset=UTF-8

Connection: close

Vary: Accept-Encoding

Strict-Transport-Security: max-age=15552000

X-Frame-Options: DENY

X-Content-Type-Options: nosniff

X-XSS-Protection: 1; mode=block

X-Proxy-Cache : MISS

Content-Length: 315 ami-id

ami-launch-index

ami-manifest-path

block-device-mapping/

events/

hostname

identity-credentials/

instance-action

instance-id

instance-type

local-hostname

local-ipv4

mac

metrics/

network/

placement/

product-codes

profile

public-hostname

public-ipv4

public-keys/

reservation-id

security-groups

services/

If you see the “ X-Proxy-Cache ” cache header value, it is now set to “MISS” which meant that now the API call doesn’t hit the caching layer and it fetches the response directly from the server.

So I was able to successfully bypass the caching layer to exploit SSRF. Now to read AWS account credentials, I had to make the call to AWS instance metadata security credentials API (http://169.254.169.254/latest/meta-data/identity-credentials/ec2/security-credentials/ec2-instance?) and as I expected, I was able to get hold of it —

I got the AWS access ID, secret Access key and the token and using which I was able to login into their AWS account and was able to access plenty of critical stuff. So having first bypassed the Cloudflare firewall, I exploited LFI then escalated it to SSRF by bypassing web cache mechanism and finally I got hold of AWS account credentials by exploiting SSRF vulnerability.

So, that’s it about this interesting finding!:)