SSRF to fetch AWS credentials with full access to multiple services

This is a post about how I found a simple yet really critical vulnerability in a bug bounty program. It was the most critical bug I have ever found.

All started after I found a path in a subdomain that was almost a blank page with no functionality at all.

It had a few parameters that were all vulnerable to XSS so I reported the issue, it was triaged by Hackerone but at the end (yeah I have bad luck) it was closed as “internal dupe”.

The path was in https://host/payment/? so it was looking really promising that I was able to access this endpoint while being unauthenticated although the page was almost blank.

I didn’t give up and started fuzzing this endpoint as well as trying to find new ones to see if more unauthenticated stuff would show up. After some time I finally got something, a callback to our server.

After identifying the vulnerable parameter urlLogo (I changed the parameter name a bit because I have to redact everything), I started to think it would be a blind SSRF because the response of the url I was providing was not in the response.


After detecting the vulnerable parameter I started to test for SSRF as I usually do. Because I thought it was a Blind SSRF, I started to look into discrepancies in the response when providing a valid domain ( and when providing a host that doesn’t exist (asdqwd.asdq), providing port 80 and then 555, etc. to check if the server would timeout, give an error response or anything that we can certainly know when the server hit a valid host or not. The server was giving a timeout when providing a host like

I started burp suite pro, send a new tab to burp intruder and started fuzzing it with SSRF payloads I have gathered from public sources and personal experience.

When analyzing the responses from burp intruder I noticed that the responses were different from each other. There was a img tag with a base64 value, and when providing different urls, it would have different responses because the base64 value would store the responses of the requests we were making.

<img src="data:image/png;base64, base64encodedvalue.." onerror="path-to-same-blank-image" />

So I asked a friend I hacked a lot with in the past (neema) if he would give me a hand exploiting the issue as I previously validated it was probably a valid ssrf.

My mind was sure this endpoint would not fetch non-image endpoints so I didn’t decode the base64 value and started to think what default image to get in localhost so I could make a clear poc or to dig further into port enum, etc.

I took a break and started to play Warzone and in the middle of the game neema sent me a message telling me it was full read SSRF. The server was base64 encoding the response of the url we were providing in urlLogo parameter, no matter the content-type or anything and not only images (this is really unusual).

Awesome news since this was a full-read SSRF now.

we tried

Decoded the base64 value and yes, there was the response with the AWS credentials:

"Code" : "Success",
"LastUpdated" : "2021-01-26T23:02:52Z",
"Type" : "AWS-HMAC",
"AccessKeyId" : "REDACTED",
"SecretAccessKey" : "REDACTED",
"Token" : "REDACTED==",
"Expiration" : "2021-01-27T05:06:28Z"

This endpoint allow us to generate temporary credentials to access aws resources, so then we exported the AWS keys:


Tested them out and they were working!

The keys could have restricted privileges, minimizing the impact of the issue, so we checked to what we were having access, and we were surprised:

aws s3 ls

listed over 200 internal s3 buckets of the company.

aws ec2 describe-security-groups --region eu-west-2
aws ec2 describe-instances --region eu-west-2
aws ec2 describe-vpcs --region eu-west-2
aws ec2 describe-images --region eu-west-2

listed ec2 instances. The other commands were used to check if we had write access to ec2 instances without compromising the information inside the instances.

Overall the keys appear to have full privilege over the AWS services so the impact is just insane. Reading/deleting +200 buckets containing private information, messing up with the ec2 instances, creating and/or using other services, etc.

Without going further, I wrote the report and sent it.

It was then triaged as max impact possible and a few days later a bounty was rewarded:

I was expecting a massive bounty, bigger that the usual bounty for a critical vulnerability in this program (not sure why I was expecting that, probably because of the massive impact of the issue) but at the end it was rewarded max bounty + a bonus, still pretty good.

That’s all for the write-up. Follow me on twitter (not here) if you want to read my next write-up, because if I feel with time, I make the post directly at my site and not in, just doing it here because it is fast to do.

If you feel like buying me a coffee because whatever, you can do it here:

Hope you liked it, zonduu.




Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

How to Bring the Vacation Vibe Home

Encryption Using Rotate Operations Assembly Solution

Cisco 210–260 certifications are globally accepted and add significant value to any IT…

Nations & Cyberwarfare: What Lies Behind Computer Screens

Introduction to Personal Data

EARNING is a Simple Accomplishment with VSTMEX

Can you trust your medical billing partner to protect your data?

Data Protection Regulation

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store


More from Medium

Intigriti’s February XSS Challenge Walkthrough

XSS Vulnerability Part 2

Stored XSS into HTML