Rhino Security Labs

Attacking AWS Cognito with Pacu (p2)

In Part 2 of this post, we walk through our two new Cognito modules for Pacu, our open-source AWS exploitation framework. If you’re not familiar with accessing AWS Cognito, feel free to check out Part 1: Accessing AWS Cognito Security with Pacu.

Cognito Enumeration: Pacu "Cognito__enum"

This module uses the Pacu session’s credentials to find Cognito resources in the AWS account.

The following arguments can be used: 

  • regions
  • user_pools
  • user_pool_clients
  • identity_pools
  • users

If no arguments are specified, the module uses them all and looks for all resources. 

After using “set_keys” to add IAM keys, we can run the module with “run cognito__enum”.

  1. “User Pool” Enumeration

The module enumerates and saves all “user pool” data and issues alerts for:

  • Weak password policies
  • Lack of MFA enforcement

2. “Identity Pool” Enumeration

The module enumerates and saves all “identity pool” data and issues alerts for:

  • Underlying “identity IDs”
  • “Identity ID” IAM credentials

3. “Client” Enumeration

The module enumerates and saves all “client” data and issues alerts for:

  • User-modifiable attributes (“mutable” true, “write” true, “DeveloperOnly” false)
  • User-modifiable attributes used for RBAC by user pools and identity pools
  • “Email” and “phone_number” attributes whose changes go into effect immediately

All resulting SQLite data can be reviewed using Pacu’s “data cognito” function:

Attacking Cognito: Pacu "Cognito__attack"

This module uses the Pacu session’s credentials, which do not require any permissions with the target, and automates attacks.

The following arguments can be used:

  • email
  • regions
  • user_pools
  • user_pool_clients
  • identity_pools
  • username
  • password

The module uses a default username of “testuser” and a default password of “TesPas808@!”

Below is a sample attack path based upon recent Rhino engagements.

  1. “Unauthenticated” Identity ID IAM Credentials:

We discover a web app with a login portal. The page source exposes Cognito resource IDs:

Var poolData = {UserPoolId: us-east-2_0aXXXXXXX
	              ClientId: 59f6tuhfXXXXXXXXXXXXXXXXXX   
	              IdentityPoolId: us-east-2:a06XXXXX-c9XX-4aXX-9aXX-9ceXXXXXXXXX};

We attack the “client” and “identity pool” IDs, with “client” ID in the format ClientID@UserPoolID:

run cognito__attack --username randomuser --email XX+sdfs2@gmail.com --identity_pools 
us-east-2:a06XXXXX-c9XX-4aXX-9a33-9ceXXXXXXXXX --user_pool_clients 
59f6tuhfXXXXXXXXXXXXXXXXXX@us-east-2_0aXXXXXXX   

The module attempts to retrieve the following:

  • Underlying “identity IDs”“
  • Identity ID” IAM credentials

2. User Registration or Login

The module begins registration and a verification code is sent, which we enter when prompted.  The module then detects that MFA is needed and saves a QR code, which we then scan:

We enter the new code that appears, then one more, and the module gives us our login tokens:

3. “Authenticated” IAM Credentials

The module sends our new “id” token to the identity pool and attempts to retrieve the following:

  • “Authenticated” IAM credentials

4. Privilege Escalation via User-Modifiable Attributes:

The module checks for attributes attached to our user and prompts us to change their values if desired, and then it prompts us to log in again to check for successful escalation:

5. Privilege Escalation via Assumable Roles:

The module decodes the “id” JWT and lists the following:

  • IAM roles we can assume via the API
  • Resulting IAM credentials

We use these results to assume “Pacutestrole” directly:

All resulting SQLite data can be reviewed using Pacu’s “data cognito” function (which accepts subcategories). All data has “Attack_” prepended to distinguish it from cognito__enum data.

Conclusion

We hope that you find these modules useful in identifying misconfigurations in AWS Cognito.

For questions, comments and updates, follow us on X /Twitter  (@RhinoSecurity@davidkutzmarks), and chat with us on Discord.