Cognito User Pools

Вивчайте хакінг AWS від нуля до героя з htARTE (HackTricks AWS Red Team Expert)!

Інші способи підтримки HackTricks:

Основна інформація

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

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

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

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

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

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

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

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

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

Потенційні атаки

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

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

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

Інструменти для пентесту

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

Для опису функцій модулів див. частину 2 посту блогу. Інструкції щодо установки див. на головній сторінці Pacu.

Використання

Приклад використання атаки cognito__attack для спроби створення користувача та всіх векторів підвищення привілеїв проти заданого пулу ідентичності та клієнтського додатка пулу користувачів:

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.sh --user-pools
cognito__enum.sh --user-pool-clients
cognito__enum.sh --identity-pools
cognito__enum.sh --users
Pacu (new:test) > run cognito__enum
  • Cognito Scanner - це інструмент командного рядка на python, який реалізує різні атаки на Cognito, включаючи небажане створення облікового запису та обліковий оракул.

Встановлення

$ pip install cognito-scanner

Використання

$ cognito-scanner --help

Для отримання додаткової інформації перевірте https://github.com/padok-team/cognito-scanner

Реєстрація

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

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

Підтвердження реєстрації

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 у полі 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 для зміни/підтвердження нового номера телефону.

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

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

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

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, Токен доступу та Токен оновлення.

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

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

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

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

ADMIN_NO_SRP_AUTH & ADMIN_USER_PASSWORD_AUTH

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

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

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

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

Для входу вам потрібно знати:

  • ідентифікатор пулу користувачів

  • ідентифікатор клієнта

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

  • пароль

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

Для того, щоб здати можливість входу за цим методом, додаток повинен дозволяти вхід за допомогою 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** замість (оскільки він ніколи не відправляє пароль по мережі).\
Цей **метод НЕ активований** за замовчуванням.

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

Для **входу** вам потрібно знати:

* ідентифікатор клієнта
* ім'я користувача
* пароль
* секрет клієнта (тільки якщо додаток налаштований на використання секрету)

<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

ОНОВЛЕННЯ_ТОКЕНУ_АУТ & ОНОВЛЕННЯ_ТОКЕН

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

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

Last updated