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.
Exploitation
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 (zonduu.me) 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 zonduu.me:555.
I started Burp Suite Pro, sent 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 an 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 had 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 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 the 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:
http://169.254.169.254/latest/meta-data/iam/security-credentials/cko-ssm
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 allows us to generate temporary credentials to access AWS resources, so then we exported the AWS keys:
export AWS_ACCESS_KEY_ID="REDACTED"
export AWS_SECRET_ACCESS_KEY="REDACTED"
export AWS_SESSION_TOKEN="REDACTED"
Tested them out and they were working!
The keys could have restricted privileges, minimizing the impact of the issue, so we checked what we had access to, 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 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 than 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 @zonduu1 if you want to read my next write-up.
Hope you liked it, zonduu.