at the time of writing this is all patched, dont come to me asking if it still works and how you can do it.
so, recently i was looking into a microsoft partner called gamersafer which promotes facial recognition KYC to log into games (fun stuff) and also notably runs the official minecraft serverlist which is riddled with servers that are against mojangs own rules
the start
im in some cringy "minecraft server owner" or "minecraft influencer" discord server where people like to shit on mojang (for no real reason) on, and i saw this message chain on one:
this reminded me of the fact that gamersafer exists and that they are a microsoft partner, which got me to poke around their service!
initial recon
so, as i do i was just looking at their subdomains to see if theres anything interesting on them, and one stuck out: admin.gamersafer.com
.
opening the domain in a browser displayed a login prompt that looked a little like this:
upon opening firefox devtools, i discovered that this page actually had JS sourcemaps on, which was going to be useful for reversing stuff.
the first thing i do is to try to look for api calls, and as i did so, something stuck out with the api client, it seemed to be referencing something called REACT_APP_AWS_ACCESS_KEY
and REACT_APP_AWS_SECRET_KEY
while i dont know about aws that much, this looked a little funky.
it was supposed to be in the process.env but obviously we arent in node so that doesnt exist so i decided to just search for it in the non-sourcemapped js:
so, i cleaned this up and took a better look at it:
{
"NODE_ENV": "production",
"PUBLIC_URL": "",
"WDS_SOCKET_HOST": null,
"WDS_SOCKET_PATH": null,
"WDS_SOCKET_PORT": null,
"FAST_REFRESH": true,
"REACT_APP_API_HOST": "apiv2.gamersafer.com",
"REACT_APP_AWS_SECRET_KEY": "redacted+redacted",
"REACT_APP_CHECKOUT_API_URL": "https://redacted.execute-api.us-east-1.amazonaws.com/prod/",
"REACT_APP_AWS_ACCESS_KEY": "redacted",
"REACT_APP_AUTH_SECRET_KEY": "redacted"
}
chaos begins
at first i thought that the AWS secret key being exposed was fine because it had very limited permissions, so to confirm that i quickly looked at the AWS rest api to see how it worked, the module that seemed the simplest and juiciest to me was IAM, and long story short, the account/key we had access to, had full administrator access:
<Path>/</Path>
<AttachedManagedPolicies>
<member>
<PolicyArn>arn:aws:iam::aws:policy/AmazonAPIGatewayAdministrator</PolicyArn>
<PolicyName>AmazonAPIGatewayAdministrator</PolicyName>
</member>
<member>
<PolicyArn>arn:aws:iam::aws:policy/service-role/AmazonAPIGatewayPushToCloudWatchLogs</PolicyArn>
<PolicyName>AmazonAPIGatewayPushToCloudWatchLogs</PolicyName>
</member>
<member>
<PolicyArn>arn:aws:iam::aws:policy/AdministratorAccess</PolicyArn>
<PolicyName>AdministratorAccess</PolicyName>
</member>
<member>
<PolicyArn>arn:aws:iam::aws:policy/AmazonSESFullAccess</PolicyArn>
<PolicyName>AmazonSESFullAccess</PolicyName>
</member>
<member>
<PolicyArn>arn:aws:iam::aws:policy/AmazonSQSFullAccess</PolicyArn>
<PolicyName>AmazonSQSFullAccess</PolicyName>
</member>
<member>
<PolicyArn>arn:aws:iam::aws:policy/AmazonAPIGatewayInvokeFullAccess</PolicyArn>
<PolicyName>AmazonAPIGatewayInvokeFullAccess</PolicyName>
</member>
<member>
<PolicyArn>arn:aws:iam::aws:policy/AmazonS3FullAccess</PolicyArn>
<PolicyName>AmazonS3FullAccess</PolicyName>
</member>
<member>
<PolicyArn>arn:aws:iam::aws:policy/AWSLambda_FullAccess</PolicyArn>
<PolicyName>AWSLambda_FullAccess</PolicyName>
</member>
<member>
<PolicyArn>arn:aws:iam::aws:policy/service-role/AmazonS3ObjectLambdaExecutionRolePolicy</PolicyArn>
<PolicyName>AmazonS3ObjectLambdaExecutionRolePolicy</PolicyName>
</member>
</AttachedManagedPolicies>
<GroupList />
<UserName>redacted</UserName>
<Arn>arn:aws:iam::redacted:user/redacted</Arn>
<UserId>redacted</UserId>
<CreateDate>redatced</CreateDate>
<Tags />
which means that if i wanted to, i could do anything like exfiltrate all their data and delete everything.
disclosure
so first i tried the gamersafer.com contact form, which didnt seem like it did anything.
then i tried to get some contacts in gamersafer with the help of some friends. i was eventually able to get in contact with TheMisterEpic, which had previously talked to gamersafer before and he quickly created a groupchat with the product manager, who quickly responded to my inquiry.
from there, it was just taking down stuff and revoking the keys.
they said thanks but there was no bounty given (kinda expected)
lessons learned
dont use client environment variables for secrets, please.
this mistake couldve been avoided by delegating more things to serverside api calls from authorized clients.
oh fuck here we go again
it has been 72 hours since disclosure of this vulnerability to gamersafer, they have not disclosed the breach of all of their infrastructure to end users which (i believe) is highly illegal in the GDPR.
i also found another vulnerability in findmcserver which allowed me to approve my own server, give myself badges and approving my own server.
while this isnt as critical, they found the server and i started getting spam logged out (lol), i soon recieved a DM from the CEO.
i also got this email from the ceo saying they disclosed it (havent checked and it was literally past the disclosure time anyway, better then nothing)