Cognito User Pools

Support HackTricks

Basic Information

Пул користувачів - це каталог користувачів в Amazon Cognito. За допомогою пулу користувачів ваші користувачі можуть увійти до вашого веб- або мобільного додатку через Amazon Cognito, або федеративно через постачальника ідентичності (IdP). Незалежно від того, чи входять ваші користувачі безпосередньо або через третю сторону, всі члени пулу користувачів мають профіль каталогу, до якого ви можете отримати доступ через SDK.

Пули користувачів надають:

  • Послуги реєстрації та входу.

  • Вбудований, налаштовуваний веб-інтерфейс для входу користувачів.

  • Соціальний вхід через Facebook, Google, Login with Amazon та Sign in with Apple, а також через постачальників ідентичності SAML та OIDC з вашого пулу користувачів.

  • Управління каталогом користувачів та профілями користувачів.

  • Функції безпеки, такі як багатофакторна аутентифікація (MFA), перевірки на компрометовані облікові дані, захист від захоплення облікового запису та перевірка телефону та електронної пошти.

  • Налаштовані робочі процеси та міграція користувачів через тригери AWS Lambda.

Код додатків зазвичай також міститиме ID пулу користувачів та ID клієнтського додатку, (а іноді і секрет додатку?), які потрібні для входу користувача до пулу користувачів Cognito.

Potential attacks

  • Реєстрація: За замовчуванням користувач може зареєструватися самостійно, тому він може створити користувача для себе.

  • Перерахування користувачів: Функціональність реєстрації може бути використана для знаходження імен користувачів, які вже існують. Ця інформація може бути корисною для атаки методом грубої сили.

  • Атака методом грубої сили на вхід: У розділі Аутентифікація ви маєте всі методи, які користувач має для входу, ви можете спробувати атакувати їх методом грубої сили, щоб знайти дійсні облікові дані.

Tools for pentesting

  • Pacu, тепер включає модулі cognito__enum та cognito__attack, які автоматизують перерахування всіх активів Cognito в обліковому записі та позначають слабкі конфігурації, атрибути користувачів, що використовуються для контролю доступу тощо, а також автоматизують створення користувачів (включаючи підтримку MFA) та ескалацію привілеїв на основі змінних атрибутів, використовуваних облікових даних пулу ідентичності, ролей, які можна прийняти в токенах ідентифікації тощо. Для опису функцій модулів дивіться частину 2 блог-посту. Для інструкцій з установки дивіться основну сторінку Pacu.

# Run 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__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
  • Cognito Scanner - це інструмент CLI на python, який реалізує різні атаки на Cognito, включаючи небажане створення облікових записів та обліковий оракул. Перегляньте це посилання для отримання додаткової інформації.

# Install
pip install cognito-scanner
# Run
cognito-scanner --help
  • CognitoAttributeEnum: Цей скрипт дозволяє перераховувати дійсні атрибути для користувачів.

python cognito-attribute-enu.py -client_id 16f1g98bfuj9i0g3f8be36kkrl

Реєстрація

User Pools дозволяє за замовчуванням реєструвати нових користувачів.

aws cognito-idp sign-up --client-id <client-id> \
--username <username> --password <password> \
--region <region> --no-sign-request

Якщо будь-хто може зареєструватися

Ви можете знайти помилку, яка вказує на те, що вам потрібно надати більше деталей про користувача:

An error occurred (InvalidParameterException) when calling the SignUp operation: Attributes did not conform to the schema: address: The attribute is required

Ви можете надати необхідні деталі у форматі JSON, наприклад:

--user-attributes '[{"Name": "email", "Value": "carlospolop@gmail.com"}, {"Name":"gender", "Value": "M"}, {"Name": "address", "Value": "street"}, {"Name": "custom:custom_name", "Value":"supername&\"*$"}]'

Ви також можете використовувати цю функціональність для перерахунку існуючих користувачів. Ось повідомлення про помилку, коли користувач вже існує з таким ім'ям:

An error occurred (UsernameExistsException) when calling the SignUp operation: User already exists

Зверніть увагу в попередній команді, як кастомні атрибути починаються з "custom:". Також знайте, що при реєстрації ви не можете створити нові кастомні атрибути для користувача. Ви можете лише надати значення за замовчуванням атрибутам (навіть якщо вони не є обов'язковими) та кастомним атрибутам, що вказані.

Або просто, щоб перевірити, чи існує ідентифікатор клієнта. Це помилка, якщо ідентифікатор клієнта не існує:

An error occurred (ResourceNotFoundException) when calling the SignUp operation: User pool client 3ig612gjm56p1ljls1prq2miut does not exist.

Якщо лише адміністратор може реєструвати користувачів

Ви знайдете цю помилку і не зможете зареєструвати або перерахувати користувачів:

An error occurred (NotAuthorizedException) when calling the SignUp operation: SignUp is not permitted for this user pool

Verifying Registration

Cognito дозволяє перевірити нового користувача, підтвердивши його електронну пошту або номер телефону. Тому, при створенні користувача, зазвичай вам буде потрібно принаймні ім'я користувача та пароль, а також електронна пошта та/або номер телефону. Просто вкажіть один який ви контролюєте, щоб ви отримали код для підтвердження вашого новоствореного користувача акаунту ось так:

aws cognito-idp confirm-sign-up --client-id <cliet_id> \
--username aasdasd2 --confirmation-code <conf_code> \
--no-sign-request --region us-east-1

Навіть якщо здається, що ви можете використовувати ту ж електронну пошту та номер телефону, коли вам потрібно підтвердити створеного користувача, Cognito буде скаржитися на використання тієї ж інформації і не дозволить вам підтвердити обліковий запис.

Підвищення привілеїв / Оновлення атрибутів

За замовчуванням користувач може змінювати значення своїх атрибутів за допомогою чогось на зразок:

aws cognito-idp update-user-attributes \
--region us-east-1 --no-sign-request \
--user-attributes Name=address,Value=street \
--access-token <access token>

Привілейоване підвищення через користувацькі атрибути

Ви можете знайти кастомні атрибути (такі як isAdmin), оскільки за замовчуванням ви можете змінювати значення своїх власних атрибутів, ви можете підвищити привілеї, змінивши значення самостійно!

Привілейоване підвищення через модифікацію електронної пошти/імені користувача

Ви можете використовувати це, щоб змінити електронну пошту та номер телефону користувача, але навіть якщо обліковий запис залишається перевіреним, ці атрибути встановлені в статус неперевіреного (вам потрібно перевірити їх знову).

Ви не зможете увійти за електронною поштою або номером телефону, поки не перевірите їх, але ви зможете увійти з іменем користувача. Зверніть увагу, що навіть якщо електронна пошта була змінена і не перевірена, вона з'явиться в ID Token у полі email і поле email_verified буде false, але якщо додаток не перевіряє це, ви можете видавати себе за інших користувачів.

Більше того, зверніть увагу, що ви можете ввести будь-що в поле name, просто змінивши атрибут імені. Якщо додаток перевіряє це поле з якоїсь причини замість email (або будь-якого іншого атрибута), ви можете видавати себе за інших користувачів.

У будь-якому випадку, якщо з якоїсь причини ви змінили свою електронну пошту, наприклад, на нову, до якої маєте доступ, ви можете підтвердити електронну пошту за кодом, який ви отримали на цю електронну адресу:

aws cognito-idp verify-user-attribute \
--access-token <access_token> \
--attribute-name email --code <code> \
--region <region> --no-sign-request

Використовуйте phone_number замість email для зміни/перевірки нового номера телефону.

Адміністратор також може активувати опцію входу з бажаним ім'ям користувача. Зверніть увагу, що ви не зможете змінити це значення на будь-яке ім'я користувача або бажане_ім'я, яке вже використовується для видавання себе за іншого користувача.

Відновлення/Зміна пароля

Можливо відновити пароль, просто знаючи ім'я користувача (або приймається email або телефон), і маючи доступ до нього, оскільки код буде надіслано туди:

aws cognito-idp forgot-password \
--client-id <client_id> \
--username <username/email/phone> --region <region>

Відповідь сервера завжди буде позитивною, ніби ім'я користувача існує. Ви не можете використовувати цей метод для перерахунку користувачів

З кодом ви можете змінити пароль за допомогою:

aws cognito-idp confirm-forgot-password \
--client-id <client_id> \
--username <username> \
--confirmation-code <conf_code> \
--password <pwd> --region <region>

Щоб змінити пароль, вам потрібно знати попередній пароль:

aws cognito-idp change-password \
--previous-password <value> \
--proposed-password <value> \
--access-token <value>

Аутентифікація

Пул користувачів підтримує різні способи аутентифікації. Якщо у вас є ім'я користувача та пароль, також підтримуються різні методи для входу. Більше того, коли користувач аутентифікований у Пулі, надаються 3 типи токенів: ID токен, Access токен та Refresh токен.

  • ID токен: Він містить заяви про особу аутентифікованого користувача, такі як name, email та phone_number. ID токен також можна використовувати для аутентифікації користувачів на ваших ресурсних серверах або серверних додатках. Ви повинні перевірити підпис ID токена, перш ніж довіряти будь-яким заявам всередині ID токена, якщо ви використовуєте його в зовнішніх додатках.

  • ID токен — це токен, який містить значення атрибутів користувача, навіть кастомних.

  • Access токен: Він містить заяви про аутентифікованого користувача, список груп користувача та список обсягів. Мета Access токена — авторизувати API операції в контексті користувача в пулі користувачів. Наприклад, ви можете використовувати Access токен, щоб надати вашому користувачу доступ до додавання, зміни або видалення атрибутів користувача.

  • Refresh токен: За допомогою Refresh токенів ви можете отримувати нові ID токени та Access токени для користувача, поки Refresh токен недійсний. За замовчуванням Refresh токен закінчує термін дії через 30 днів після того, як ваш користувач увійшов у ваш пул користувачів. Коли ви створюєте додаток для вашого пулу користувачів, ви можете встановити термін дії Refresh токена додатка на будь-яке значення від 60 хвилин до 10 років.

ADMIN_NO_SRP_AUTH & ADMIN_USER_PASSWORD_AUTH

Це потік аутентифікації на стороні сервера:

  • Додаток на стороні сервера викликає AdminInitiateAuth API операцію (замість InitiateAuth). Ця операція вимагає облікові дані AWS з дозволами, які включають cognito-idp:AdminInitiateAuth та cognito-idp:AdminRespondToAuthChallenge. Операція повертає необхідні параметри аутентифікації.

  • Після того, як додаток на стороні сервера отримав параметри аутентифікації, він викликає AdminRespondToAuthChallenge API операцію. API операція AdminRespondToAuthChallenge успішно виконується лише тоді, коли ви надаєте облікові дані AWS.

Цей метод НЕ активований за замовчуванням.

Щоб увійти, вам потрібно знати:

  • id пулу користувачів

  • id клієнта

  • ім'я користувача

  • пароль

  • секрет клієнта (тільки якщо додаток налаштовано на використання секрету)

Щоб мати можливість увійти за цим методом, цей додаток повинен дозволяти вхід з ALLOW_ADMIN_USER_PASSWORD_AUTH. Більше того, для виконання цієї дії вам потрібні облікові дані з дозволами cognito-idp:AdminInitiateAuth та cognito-idp:AdminRespondToAuthChallenge

aws cognito-idp admin-initiate-auth \
--client-id <client-id> \
--auth-flow ADMIN_USER_PASSWORD_AUTH \
--region <region> \
--auth-parameters 'USERNAME=<username>,PASSWORD=<password>,SECRET_HASH=<hash_if_needed>'
--user-pool-id "<pool-id>"

# Check the python code to learn how to generate the hsecret_hash
Код для входу

```python import boto3 import botocore import hmac import hashlib import base64

client_id = "" user_pool_id = "" client_secret = "" username = "" password = ""

boto_client = boto3.client('cognito-idp', region_name='us-east-1')

def get_secret_hash(username, client_id, client_secret): key = bytes(client_secret, 'utf-8') message = bytes(f'{username}{client_id}', 'utf-8') return base64.b64encode(hmac.new(key, message, digestmod=hashlib.sha256).digest()).decode()

If the Client App isn't configured to use a secret

just delete the line setting the SECRET_HASH

def login_user(username_or_alias, password, client_id, client_secret, user_pool_id): try: return boto_client.admin_initiate_auth( UserPoolId=user_pool_id, ClientId=client_id, AuthFlow='ADMIN_USER_PASSWORD_AUTH', AuthParameters={ 'USERNAME': username_or_alias, 'PASSWORD': password, 'SECRET_HASH': get_secret_hash(username_or_alias, client_id, client_secret) } ) except botocore.exceptions.ClientError as e: return e.response

print(login_user(username, password, client_id, client_secret, user_pool_id))

</details>

### USER\_PASSWORD\_AUTH

Цей метод є ще одним простим і **традиційним методом аутентифікації користувача та пароля**. Рекомендується **мігрувати традиційний** метод аутентифікації **до Cognito** і **рекомендується** потім **відключити** його та **використовувати** метод **ALLOW\_USER\_SRP\_AUTH** замість цього (оскільки він ніколи не передає пароль через мережу).\
Цей **метод НЕ активований** за замовчуванням.

Основна **різниця** з **попереднім методом аутентифікації** в коді полягає в тому, що вам **не потрібно знати ID пулу користувачів** і що вам **не потрібні додаткові дозволи** в Cognito User Pool.

Щоб **увійти**, вам **потрібно** знати:

* client id
* username
* password
* client secret (тільки якщо додаток налаштований на використання секрету)

<div data-gb-custom-block data-tag="hint" data-style='info'>

Щоб **мати можливість увійти за допомогою цього методу**, цей додаток повинен дозволяти вхід з ALLOW\_USER\_PASSWORD\_AUTH.

</div>

```python
aws cognito-idp initiate-auth  --client-id <client-id> \
--auth-flow USER_PASSWORD_AUTH --region <region> \
--auth-parameters 'USERNAME=<username>,PASSWORD=<password>,SECRET_HASH=<hash_if_needed>'

# Check the python code to learn how to generate the secret_hash

REFRESH_TOKEN_AUTH & REFRESH_TOKEN

Цей метод завжди буде дійсним (його не можна вимкнути), але вам потрібен дійсний токен оновлення.

aws cognito-idp initiate-auth \
--client-id 3ig6h5gjm56p1ljls1prq2miut \
--auth-flow REFRESH_TOKEN_AUTH \
--region us-east-1 \
--auth-parameters 'REFRESH_TOKEN=<token>'

Last updated