Cognito User Pools
Reading time: 15 minutes
tip
Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Вивчайте та практикуйте Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Підтримка HackTricks
- Перевірте плани підписки!
- Приєднуйтесь до 💬 групи Discord або групи Telegram або слідкуйте за нами в Twitter 🐦 @hacktricks_live.
- Діліться хакерськими трюками, надсилаючи PR до HackTricks та HackTricks Cloud репозиторіїв на GitHub.
Основна інформація
User pool - це каталог користувачів в Amazon Cognito. За допомогою user pool ваші користувачі можуть увійти до вашого веб- або мобільного додатку через Amazon Cognito, або федеративно через постачальника ідентичності (IdP). Незалежно від того, чи входять ваші користувачі безпосередньо або через третю сторону, всі члени user pool мають профіль каталогу, до якого ви можете отримати доступ через SDK.
User pools надають:
- Послуги реєстрації та входу.
- Вбудований, налаштовуваний веб-інтерфейс для входу користувачів.
- Соціальний вхід через Facebook, Google, Login with Amazon, Sign in with Apple, а також через постачальників ідентичності SAML та OIDC з вашого user pool.
- Управління каталогом користувачів та профілями користувачів.
- Функції безпеки, такі як багатофакторна аутентифікація (MFA), перевірки на компрометовані облікові дані, захист від захоплення облікового запису, а також перевірка телефону та електронної пошти.
- Налаштовані робочі процеси та міграція користувачів через тригери AWS Lambda.
Код джерела додатків зазвичай також міститиме ID user pool та ID клієнтського додатку, (а іноді і секрет додатку?), які потрібні для входу користувача до Cognito User Pool.
Потенційні атаки
- Реєстрація: За замовчуванням користувач може зареєструватися самостійно, тому він може створити обліковий запис для себе.
- Перерахування користувачів: Функціональність реєстрації може бути використана для знаходження імен користувачів, які вже існують. Ця інформація може бути корисною для атаки методом грубої сили.
- Брутфорс входу: У розділі Аутентифікація ви маєте всі методи, які користувач має для входу, ви можете спробувати атакувати їх методом грубої сили, щоб знайти дійсні облікові дані.
Інструменти для пентестингу
- 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, включаючи небажане створення облікових записів та обліковий оракул. Перевірте this link для отримання додаткової інформації.
# 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
note
Зверніть увагу в попередній команді, як кастомні атрибути починаються з "custom:".
Також знайте, що при реєстрації ви не можете створити нові кастомні атрибути для користувача. Ви можете лише надати значення за замовчуванням атрибутам (навіть якщо вони не є обов'язковими) та кастомним атрибутам, що вказані.
Або просто для перевірки, чи існує ідентифікатор клієнта. Це помилка, якщо client-id не існує:
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
warning
Навіть якщо здається, що ви можете використовувати ту ж електронну пошту та номер телефону, коли вам потрібно перевірити створеного користувача, Cognito буде скаржитися на використання тієї ж інформації і не дозволить вам підтвердити обліковий запис.
Підвищення привілеїв / Оновлення атрибутів
За замовчуванням користувач може змінювати значення своїх атрибутів за допомогою чогось на зразок:
aws cognito-idp update-user-attributes \
--region us-east-1 --no-sign-request \
--user-attributes Name=address,Value=street \
--access-token <access token>
Привілейоване підвищення через користувацькі атрибути
caution
Ви можете знайти кастомні атрибути (такі як isAdmin
), оскільки за замовчуванням ви можете змінювати значення своїх власних атрибутів, ви можете підвищити привілеї, змінивши значення самостійно!
Привілейоване підвищення через модифікацію електронної пошти/імені користувача
Ви можете використовувати це, щоб змінити електронну пошту та номер телефону користувача, але навіть якщо обліковий запис залишається перевіреним, ці атрибути встановлюються в статус неперевіреного (вам потрібно перевірити їх знову).
warning
Ви не зможете увійти за електронною поштою або номером телефону, поки не перевірите їх, але ви зможете увійти з іменем користувача.
Зверніть увагу, що навіть якщо електронна пошта була змінена і не перевірена, вона з'явиться в ID Token у полі email
і поле email_verified
буде false, але якщо додаток не перевіряє це, ви можете видавати себе за інших користувачів.
Більше того, зверніть увагу, що ви можете ввести будь-що в поле
name
, просто змінивши атрибут name. Якщо додаток перевіряє це поле з якоїсь причини замість
У будь-якому випадку, якщо з якоїсь причини ви змінили свою електронну пошту, наприклад, на нову, до якої маєте доступ, ви можете підтвердити електронну пошту за кодом, який ви отримали на цю електронну адресу:
aws cognito-idp verify-user-attribute \
--access-token <access_token> \
--attribute-name email --code <code> \
--region <region> --no-sign-request
Використовуйте phone_number
замість email
для зміни/перевірки нового номера телефону.
note
Адміністратор також може активувати опцію входу з бажаним ім'ям користувача. Зверніть увагу, що ви не зможете змінити це значення на будь-яке ім'я користувача або бажане_ім'я, яке вже використовується для видавання себе за іншого користувача.
Відновлення/Зміна пароля
Можливо відновити пароль, просто знаючи ім'я користувача (або приймаються email або телефон), і маючи доступ до нього, оскільки код буде надіслано туди:
aws cognito-idp forgot-password \
--client-id <client_id> \
--username <username/email/phone> --region <region>
note
Відповідь сервера завжди буде позитивною, ніби ім'я користувача існує. Ви не можете використовувати цей метод для перерахунку користувачів
З кодом ви можете змінити пароль за допомогою:
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 клієнта
- ім'я користувача
- пароль
- секрет клієнта (тільки якщо додаток налаштовано на використання секрету)
note
Щоб мати можливість увійти за допомогою цього методу, цей додаток повинен дозволяти вхід з 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
Код для входу
import boto3
import botocore
import hmac
import hashlib
import base64
client_id = "<client-id>"
user_pool_id = "<user-pool-id>"
client_secret = "<client-secret>"
username = "<username>"
password = "<pwd>"
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))
USER_PASSWORD_AUTH
Цей метод є ще одним простим і традиційним методом аутентифікації користувача та пароля. Рекомендується мігрувати традиційний метод аутентифікації до Cognito і рекомендується потім відключити його та використовувати метод ALLOW_USER_SRP_AUTH замість цього (оскільки цей метод ніколи не надсилає пароль через мережу).
Цей метод НЕ активовано за замовчуванням.
Основна різниця з попереднім методом аутентифікації в коді полягає в тому, що вам не потрібно знати ID пулу користувачів і що вам не потрібні додаткові дозволи в Cognito User Pool.
Щоб увійти, вам потрібно знати:
- client id
- username
- password
- client secret (тільки якщо додаток налаштовано на використання секрету)
note
Щоб мати можливість увійти за допомогою цього методу, цей додаток повинен дозволяти вхід за допомогою ALLOW_USER_PASSWORD_AUTH.
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
Python код для входу
import boto3
import botocore
import hmac
import hashlib
import base64
client_id = "<client-id>"
user_pool_id = "<user-pool-id>"
client_secret = "<client-secret>"
username = "<username>"
password = "<pwd>"
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.initiate_auth(
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))
USER_SRP_AUTH
Цей сценарій подібний до попереднього, але замість того, щоб надсилати пароль через мережу для входу, виконується аутентифікація за допомогою виклику (тобто жоден пароль не передається, навіть зашифрований через мережу).
Цей метод увімкнено за замовчуванням.
Щоб увійти, вам потрібно знати:
- ідентифікатор пулу користувачів
- ідентифікатор клієнта
- ім'я користувача
- пароль
- секрет клієнта (тільки якщо додаток налаштовано на використання секрету)
Код для входу
from warrant.aws_srp import AWSSRP
import os
USERNAME='xxx'
PASSWORD='yyy'
POOL_ID='us-east-1_zzzzz'
CLIENT_ID = '12xxxxxxxxxxxxxxxxxxxxxxx'
CLIENT_SECRET = 'secreeeeet'
os.environ["AWS_DEFAULT_REGION"] = "<region>"
aws = AWSSRP(username=USERNAME, password=PASSWORD, pool_id=POOL_ID,
client_id=CLIENT_ID, client_secret=CLIENT_SECRET)
tokens = aws.authenticate_user()
id_token = tokens['AuthenticationResult']['IdToken']
refresh_token = tokens['AuthenticationResult']['RefreshToken']
access_token = tokens['AuthenticationResult']['AccessToken']
token_type = tokens['AuthenticationResult']['TokenType']
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>'
Код для оновлення
import boto3
import botocore
import hmac
import hashlib
import base64
client_id = "<client-id>"
token = '<token>'
boto_client = boto3.client('cognito-idp', region_name='<region>')
def refresh(client_id, refresh_token):
try:
return boto_client.initiate_auth(
ClientId=client_id,
AuthFlow='REFRESH_TOKEN_AUTH',
AuthParameters={
'REFRESH_TOKEN': refresh_token
}
)
except botocore.exceptions.ClientError as e:
return e.response
print(refresh(client_id, token))
CUSTOM_AUTH
У цьому випадку автентифікація буде виконуватися через виконання функції lambda.
Додаткова безпека
Розширена безпека
За замовчуванням вона вимкнена, але якщо її увімкнути, Cognito може виявити викрадення облікових записів. Щоб зменшити ймовірність, ви повинні увійти з мережі в межах одного міста, використовуючи той же агент користувача (і IP, якщо це можливо).
MFA Запам'ятати пристрій
Якщо користувач входить з того ж пристрою, MFA може бути обійдено, тому спробуйте увійти з того ж браузера з тими ж метаданими (IP?), щоб спробувати обійти захист MFA.
Ролі IAM груп користувачів
Можна додавати користувачів до групи User Pool, які пов'язані з однією IAM роллю.
Більше того, користувачі можуть бути призначені більше ніж до 1 групи з різними прикріпленими IAM ролями.
Зверніть увагу, що навіть якщо група знаходиться всередині групи з прикріпленою IAM роллю, для того щоб мати доступ до IAM облікових даних цієї групи, потрібно, щоб User Pool був довірений Identity Pool (і знати деталі цього Identity Pool).
Ще одна вимога для отримання IAM ролі, вказаної в IdToken, коли користувач автентифікований у User Pool (aws cognito-idp initiate-auth...
), полягає в тому, що постачальник автентифікації Identity Provider повинен вказати, що роль повинна бути вибрана з токена.
.png)
Ролі, до яких має доступ користувач, знаходяться всередині IdToken
, і користувач може вибрати, для якої ролі він хотів би отримати облікові дані з --custom-role-arn
з aws cognito-identity get-credentials-for-identity
.
Однак, якщо опція за замовчуванням є тією, що сконфігурована (використовувати роль за замовчуванням
), і ви намагаєтеся отримати доступ до ролі з IdToken, ви отримаєте помилку (ось чому потрібна попередня конфігурація):
An error occurred (InvalidParameterException) when calling the GetCredentialsForIdentity operation: Only SAML providers and providers with RoleMappings support custom role ARN.
warning
Зверніть увагу, що роль, призначена для Групи користувачів повинна бути доступною для Постачальника ідентичності, який довіряє Групі користувачів (оскільки облікові дані сесії IAM ролі будуть отримані з неї).
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "cognito-identity.amazonaws.com"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"cognito-identity.amazonaws.com:aud": "us-east-1:2361092e-9db6-a876-1027-10387c9de439"
},
"ForAnyValue:StringLike": {
"cognito-identity.amazonaws.com:amr": "authenticated"
}
}
}
]
}js
tip
Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Вивчайте та практикуйте Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Підтримка HackTricks
- Перевірте плани підписки!
- Приєднуйтесь до 💬 групи Discord або групи Telegram або слідкуйте за нами в Twitter 🐦 @hacktricks_live.
- Діліться хакерськими трюками, надсилаючи PR до HackTricks та HackTricks Cloud репозиторіїв на GitHub.