Cognito User Pools

Erlernen Sie AWS-Hacking von Null auf Held mit htARTE (HackTricks AWS Red Team Expert)!

Andere Möglichkeiten, HackTricks zu unterstützen:

Grundlegende Informationen

Ein Benutzerpool ist ein Benutzerverzeichnis in Amazon Cognito. Mit einem Benutzerpool können sich Ihre Benutzer über Amazon Cognito bei Ihrer Web- oder mobilen App anmelden oder sich über einen Drittanbieter-Identitätsanbieter (IdP) föderieren. Ob Ihre Benutzer sich direkt anmelden oder über einen Drittanbieter, alle Mitglieder des Benutzerpools haben ein Verzeichnisprofil, auf das Sie über ein SDK zugreifen können.

Benutzerpools bieten:

  • Anmelde- und Anmeldedienste.

  • Eine integrierte, anpassbare Web-Benutzeroberfläche zur Anmeldung von Benutzern.

  • Soziale Anmeldung mit Facebook, Google, Anmeldung bei Amazon und Anmeldung bei Apple sowie über SAML- und OIDC-Identitätsanbieter aus Ihrem Benutzerpool.

  • Benutzerverzeichnisverwaltung und Benutzerprofile.

  • Sicherheitsfunktionen wie Multi-Faktor-Authentifizierung (MFA), Überprüfung auf kompromittierte Anmeldeinformationen, Schutz vor Accountübernahme sowie Telefon- und E-Mail-Verifizierung.

  • Angepasste Workflows und Benutzermigration über AWS Lambda-Triggers.

Der Quellcode von Anwendungen enthält in der Regel auch die Benutzerpool-ID und die Client-Anwendungs-ID (und manchmal das Anwendungspasswort?), die für einen **Benutzer erforderlich sind, um sich bei einem Cognito-Benutzerpool anzumelden.

Mögliche Angriffe

  • Registrierung: Standardmäßig kann sich ein Benutzer selbst registrieren und somit einen Benutzer für sich selbst erstellen.

  • Benutzerenumeration: Die Registrierungsfunktionalität kann verwendet werden, um Benutzernamen zu finden, die bereits existieren. Diese Informationen können für den Brute-Force-Angriff nützlich sein.

  • Login-Brute-Force: Im Abschnitt Authentifizierung finden Sie alle Methoden, die ein Benutzer zum Anmelden haben muss. Sie könnten versuchen, sie per Brute-Force anzugreifen, um gültige Anmeldeinformationen zu finden.

Tools für Pentests

  • Pacu, das AWS-Exploitation-Framework, enthält jetzt die Module "cognito__enum" und "cognito__attack", die die Enumeration aller Cognito-Ressourcen in einem Konto automatisieren und schwache Konfigurationen, für den Zugriffskontrolle verwendete Benutzerattribute usw. kennzeichnen, sowie die automatisierte Benutzererstellung (einschließlich MFA-Unterstützung) und Privilegieneskalation basierend auf änderbaren benutzerdefinierten Attributen, verwendbaren Identitätspool-Anmeldeinformationen, übernehmbaren Rollen in ID-Token usw.

Für eine Beschreibung der Funktionsweise der Module siehe Teil 2 des Blog-Beitrags. Für Installationsanweisungen siehe die Hauptseite von Pacu.

Verwendung

Beispielhafte Verwendung von cognito__attack, um die Benutzererstellung zu versuchen und alle Privilegieneskalationsvektoren gegen einen bestimmten Identitätspool und Benutzerpool-Client zu testen:

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

Beispiel für die Verwendung von cognito__enum, um alle Benutzerpools, Benutzerpool-Clients, Identitätspools, Benutzer usw. zu sammeln, die im aktuellen AWS-Konto sichtbar sind:

Pacu (new:test) > run cognito__enum
  • Cognito Scanner ist ein CLI-Tool in Python, das verschiedene Angriffe auf Cognito implementiert, einschließlich unerwünschter Kontenerstellung und Konten-Orakel.

Installation

$ pip install cognito-scanner

Verwendung

$ cognito-scanner --help

Für weitere Informationen siehe https://github.com/padok-team/cognito-scanner

Registrierung

Benutzerpools ermöglichen es standardmäßig, neue Benutzer zu registrieren.

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

Wenn sich jeder registrieren kann

Es könnte ein Fehler auftreten, der besagt, dass Sie mehr Details über den Benutzer angeben müssen:

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

Sie können die erforderlichen Details mit einem JSON wie folgt bereitstellen:

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

Du könntest diese Funktionalität auch verwenden, um vorhandene Benutzer aufzulisten. Dies ist die Fehlermeldung, die angezeigt wird, wenn bereits ein Benutzer mit diesem Namen existiert:

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

Beachten Sie im vorherigen Befehl, wie die benutzerdefinierten Attribute mit "custom:" beginnen. Beachten Sie auch, dass Sie bei der Registrierung keine neuen benutzerdefinierten Attribute für den Benutzer erstellen können. Sie können nur Werte für Standardattribute (auch wenn sie nicht erforderlich sind) und spezifizierte benutzerdefinierte Attribute angeben.

Oder einfach um zu testen, ob eine Client-ID existiert. Dies ist der Fehler, wenn die Client-ID nicht existiert:

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

Wenn nur der Administrator Benutzer registrieren kann

Sie werden diesen Fehler finden und Sie werden nicht in der Lage sein, Benutzer zu registrieren oder aufzulisten:

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

Überprüfung der Registrierung

Cognito ermöglicht es, einen neuen Benutzer zu überprüfen, indem seine E-Mail-Adresse oder Telefonnummer überprüft wird. Daher werden bei der Erstellung eines Benutzers in der Regel mindestens der Benutzername und das Passwort sowie die E-Mail-Adresse und/oder Telefonnummer benötigt. Legen Sie einfach eine fest, die Sie kontrollieren, damit Sie den Code zur Überprüfung Ihres neu erstellten Benutzerkontos erhalten, wie folgt:

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

Auch wenn es so aussieht, als ob du dieselbe E-Mail-Adresse und Telefonnummer verwenden kannst, wenn du den erstellten Benutzer verifizieren musst, wird Cognito sich beschweren, dass dieselben Informationen verwendet werden, und wird dir nicht erlauben, das Konto zu verifizieren.

Privilege Escalation / Aktualisierung von Attributen

Standardmäßig kann ein Benutzer den Wert seiner Attribute mit etwas wie:

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

Benutzerdefinierte Attribut-Privesc

Es könnte sein, dass benutzerdefinierte Attribute verwendet werden (wie z.B. isAdmin). Da Sie standardmäßig die Werte Ihrer eigenen Attribute ändern können, könnten Sie in der Lage sein, Berechtigungen zu eskalieren, indem Sie den Wert selbst ändern!

E-Mail/Benutzername-Modifikations-Privesc

Sie können dies verwenden, um die E-Mail-Adresse und Telefonnummer eines Benutzers zu ändern, aber selbst wenn das Konto als verifiziert bleibt, werden diese Attribute im nicht verifizierten Status festgelegt (Sie müssen sie erneut verifizieren).

Sie können sich nicht mit der E-Mail-Adresse oder Telefonnummer anmelden, bis Sie sie verifiziert haben, aber Sie werden sich mit dem Benutzernamen anmelden können. Beachten Sie, dass selbst wenn die E-Mail-Adresse geändert, aber nicht verifiziert wurde, sie im ID-Token im email-Feld erscheinen wird und das Feld email_verified auf false gesetzt wird, aber wenn die App das nicht überprüft, könnten Sie andere Benutzer imitieren.

Außerdem können Sie beliebige Inhalte im name-Feld platzieren, indem Sie einfach das Namensattribut ändern. Wenn eine App aus irgendeinem Grund dieses Feld anstelle der E-Mail (oder eines anderen Attributs) überprüft, könnten Sie in der Lage sein, andere Benutzer zu imitieren.

Wie auch immer, wenn Sie aus irgendeinem Grund Ihre E-Mail-Adresse beispielsweise in eine neue geändert haben, können Sie auf diese zugreifen, indem Sie die E-Mail mit dem Code bestätigen, den Sie an diese E-Mail-Adresse erhalten haben:

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

Verwenden Sie phone_number anstelle von email, um eine neue Telefonnummer zu ändern/zu überprüfen.

Der Administrator könnte auch die Option aktivieren, sich mit einem vom Benutzer bevorzugten Benutzernamen anzumelden. Beachten Sie, dass Sie diesen Wert nicht in einen Benutzernamen oder preferred_username ändern können, der bereits verwendet wird, um sich als anderer Benutzer auszugeben.

Passwort wiederherstellen/ändern

Es ist möglich, ein Passwort wiederherzustellen, indem Sie nur den Benutzernamen kennen (oder E-Mail oder Telefon akzeptiert werden) und Zugriff darauf haben, da ein Code dorthin gesendet wird:

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

Die Antwort des Servers wird immer positiv sein, als ob der Benutzername existieren würde. Sie können diese Methode nicht verwenden, um Benutzer zu enumerieren.

Mit dem Code können Sie das Passwort ändern:

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

Um das Passwort zu ändern, musst du das vorherige Passwort kennen:

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

Authentifizierung

Ein Benutzerpool unterstützt verschiedene Möglichkeiten zur Authentifizierung. Wenn Sie einen Benutzernamen und ein Passwort haben, gibt es auch verschiedene unterstützte Methoden zum Einloggen. Darüber hinaus werden einem authentifizierten Benutzer im Pool 3 Arten von Tokens gegeben: Das ID-Token, das Zugriffstoken und das Auffrischungstoken.

  • ID-Token: Es enthält Ansprüche über die Identität des authentifizierten Benutzers, wie Name, E-Mail und Telefonnummer. Das ID-Token kann auch verwendet werden, um Benutzer für Ihre Ressourcenserver oder Serveranwendungen zu authentifizieren. Sie müssen die Signatur des ID-Tokens überprüfen, bevor Sie irgendwelchen Ansprüchen im ID-Token vertrauen können, wenn Sie es in externen Anwendungen verwenden.

  • Das ID-Token ist das Token, das die Attributwerte des Benutzers enthält, auch die benutzerdefinierten.

  • Zugriffstoken: Es enthält Ansprüche über den authentifizierten Benutzer, eine Liste der Benutzergruppen und eine Liste von Berechtigungen. Der Zweck des Zugriffstokens besteht darin, API-Operationen zu autorisieren im Kontext des Benutzers im Benutzerpool. Sie können beispielsweise das Zugriffstoken verwenden, um Ihrem Benutzer Zugriff zu gewähren, um Benutzerattribute hinzuzufügen, zu ändern oder zu löschen.

  • Auffrischungstoken: Mit Auffrischungstoken können Sie neue ID-Tokens und Zugriffstoken für den Benutzer erhalten, bis das Auffrischungstoken ungültig ist. Standardmäßig läuft das Auffrischungstoken 30 Tage nach der Anmeldung Ihres Anwendungsbenutzers in Ihrem Benutzerpool ab. Wenn Sie eine Anwendung für Ihren Benutzerpool erstellen, können Sie das Ablaufdatum des Auffrischungstokens der Anwendung auf einen Wert zwischen 60 Minuten und 10 Jahren setzen.

ADMIN_NO_SRP_AUTH & ADMIN_USER_PASSWORD_AUTH

Dies ist der Authentifizierungsfluss auf der Serverseite:

  • Die Server-App ruft die AdminInitiateAuth API-Operation (anstelle von InitiateAuth) auf. Diese Operation erfordert AWS-Anmeldeinformationen mit Berechtigungen, die cognito-idp:AdminInitiateAuth und cognito-idp:AdminRespondToAuthChallenge enthalten. Die Operation gibt die erforderlichen Authentifizierungsparameter zurück.

  • Nachdem die Server-App die Authentifizierungsparameter erhalten hat, ruft sie die AdminRespondToAuthChallenge API-Operation auf. Die AdminRespondToAuthChallenge API-Operation ist nur erfolgreich, wenn Sie AWS-Anmeldeinformationen bereitstellen.

Diese Methode ist standardmäßig NICHT aktiviert.

Um sich anzumelden, müssen Sie wissen:

  • Benutzerpool-ID

  • Client-ID

  • Benutzername

  • Passwort

  • Client-Geheimnis (nur wenn die App so konfiguriert ist, dass sie ein Geheimnis verwendet)

Um sich mit dieser Methode anmelden zu können, muss die Anwendung das Anmelden mit ALLOW_ADMIN_USER_PASSWORD_AUTH erlauben. Darüber hinaus benötigen Sie Berechtigungen mit den Berechtigungen cognito-idp:AdminInitiateAuth und cognito-idp:AdminRespondToAuthChallenge, um diese Aktion auszuführen.

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
Code zum Einloggen

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

Diese Methode ist ein weiterer einfacher und **traditioneller Benutzer- und Passwort-Authentifizierungs**-Ablauf. Es wird empfohlen, eine **traditionelle Authentifizierungsmethode auf Cognito zu migrieren** und dann **zu deaktivieren** und stattdessen die Methode **ALLOW\_USER\_SRP\_AUTH** zu verwenden (da diese das Passwort niemals über das Netzwerk sendet).\
Diese Methode ist **standardmäßig NICHT aktiviert**.

Der Hauptunterschied zur **vorherigen Authentifizierungsmethode** im Code besteht darin, dass Sie **die Benutzerpool-ID nicht kennen müssen** und dass Sie **keine zusätzlichen Berechtigungen** im Cognito-Benutzerpool benötigen.

Um sich **anzumelden**, müssen Sie folgendes wissen:

* Client-ID
* Benutzername
* Passwort
* Client-Geheimnis (nur wenn die App so konfiguriert ist, dass sie ein Geheimnis verwendet)

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

Um sich **mit dieser Methode anmelden zu können**, muss die Anwendung die Anmeldung mit ALLOW\_USER\_PASSWORD\_AUTH zulassen.

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

Diese Methode ist immer gültig (kann nicht deaktiviert werden), aber Sie benötigen einen gültigen 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