Cognito User Pools
Last updated
Last updated
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Un pool d'utilisateurs est un annuaire d'utilisateurs dans Amazon Cognito. Avec un pool d'utilisateurs, vos utilisateurs peuvent se connecter à votre application web ou mobile via Amazon Cognito, ou se fédérer via un fournisseur d'identité tiers (IdP). Que vos utilisateurs se connectent directement ou via un tiers, tous les membres du pool d'utilisateurs ont un profil d'annuaire auquel vous pouvez accéder via un SDK.
Les pools d'utilisateurs fournissent :
Des services d'inscription et de connexion.
Une interface utilisateur web intégrée et personnalisable pour connecter les utilisateurs.
Connexion sociale avec Facebook, Google, Login with Amazon, et Sign in with Apple, ainsi que via des fournisseurs d'identité SAML et OIDC de votre pool d'utilisateurs.
Gestion de l'annuaire des utilisateurs et des profils d'utilisateurs.
Fonctionnalités de sécurité telles que l'authentification multi-facteurs (MFA), des vérifications pour des identifiants compromis, la protection contre la prise de contrôle de compte, et la vérification par téléphone et par email.
Flux de travail personnalisés et migration des utilisateurs via des déclencheurs AWS Lambda.
Le code source des applications contiendra généralement également l'ID du pool d'utilisateurs et l'ID de l'application cliente, (et parfois le secret de l'application ?) qui sont nécessaires pour qu'un utilisateur se connecte à un pool d'utilisateurs Cognito.
Inscription : Par défaut, un utilisateur peut s'inscrire lui-même, il pourrait donc créer un utilisateur pour lui-même.
Énumération des utilisateurs : La fonctionnalité d'inscription peut être utilisée pour trouver des noms d'utilisateur qui existent déjà. Cette information peut être utile pour l'attaque par force brute.
Force brute de connexion : Dans la section Authentication, vous avez toutes les méthodes qu'un utilisateur doit utiliser pour se connecter, vous pourriez essayer de les forcer pour trouver des identifiants valides.
Pacu, inclut maintenant les modules cognito__enum
et cognito__attack
qui automatisent l'énumération de tous les actifs Cognito dans un compte et signalent les configurations faibles, les attributs d'utilisateur utilisés pour le contrôle d'accès, etc., et automatisent également la création d'utilisateurs (y compris le support MFA) et l'escalade de privilèges basée sur des attributs personnalisables modifiables, des identifiants de pool d'identité utilisables, des rôles assumables dans les jetons d'identité, etc.
Pour une description des fonctions des modules, voir la partie 2 du blog post. Pour des instructions d'installation, voir la page principale de Pacu.
Cognito Scanner est un outil CLI en python qui implémente différentes attaques sur Cognito, y compris la création de comptes non désirés et l'oracle de compte. Consultez ce lien pour plus d'infos.
CognitoAttributeEnum : Ce script permet d'énumérer les attributs valides pour les utilisateurs.
User Pools permet par défaut de s'inscrire de nouveaux utilisateurs.
Vous pourriez trouver une erreur indiquant que vous devez fournir plus de détails sur l'utilisateur :
Vous pouvez fournir les détails nécessaires avec un JSON tel que :
Vous pouvez également utiliser cette fonctionnalité pour énumérer les utilisateurs existants. Voici le message d'erreur lorsqu'un utilisateur existe déjà avec ce nom :
Notez dans la commande précédente comment les attributs personnalisés commencent par "custom:". Sachez également que lors de l'enregistrement, vous ne pouvez pas créer de nouveaux attributs personnalisés pour l'utilisateur. Vous ne pouvez donner de valeur qu'aux attributs par défaut (même s'ils ne sont pas requis) et aux attributs personnalisés spécifiés.
Ou juste pour tester si un identifiant client existe. Voici l'erreur si l'identifiant client n'existe pas :
Vous rencontrerez cette erreur et vous ne pourrez pas enregistrer ou énumérer des utilisateurs :
Cognito permet de vérifier un nouvel utilisateur en vérifiant son email ou son numéro de téléphone. Par conséquent, lors de la création d'un utilisateur, il vous sera généralement demandé au moins le nom d'utilisateur et le mot de passe ainsi que l'email et/ou le numéro de téléphone. Il suffit de définir un que vous contrôlez afin de recevoir le code pour vérifier votre compte d'utilisateur nouvellement créé comme ceci :
Même si il semble que vous pouvez utiliser le même email et numéro de téléphone, lorsque vous devez vérifier l'utilisateur créé, Cognito se plaindra d'utiliser les mêmes informations et ne vous permettra pas de vérifier le compte.
Par défaut, un utilisateur peut modifier la valeur de ses attributs avec quelque chose comme :
Vous pourriez trouver des attributs personnalisés utilisés (comme isAdmin
), car par défaut vous pouvez changer les valeurs de vos propres attributs, vous pourriez être en mesure d'escalader les privilèges en changeant la valeur vous-même !
Vous pouvez utiliser cela pour modifier l'email et le numéro de téléphone d'un utilisateur, mais ensuite, même si le compte reste vérifié, ces attributs sont définis en statut non vérifié (vous devez les vérifier à nouveau).
Vous ne pourrez pas vous connecter avec l'email ou le numéro de téléphone tant que vous ne les avez pas vérifiés, mais vous pourrez vous connecter avec le nom d'utilisateur.
Notez que même si l'email a été modifié et non vérifié, il apparaîtra dans le jeton ID à l'intérieur du champ email
et le champ email_verified
sera faux, mais si l'application ne vérifie pas cela, vous pourriez usurper l'identité d'autres utilisateurs.
De plus, notez que vous pouvez mettre n'importe quoi dans le champ name
en modifiant simplement l'attribut name. Si une application vérifie ce champ pour une raison quelconque au lieu de l'email
(ou tout autre attribut), vous pourriez être en mesure d'usurper l'identité d'autres utilisateurs.
Quoi qu'il en soit, si pour une raison quelconque vous avez changé votre email par exemple pour un nouveau auquel vous pouvez accéder, vous pouvez confirmer l'email avec le code que vous avez reçu à cette adresse email :
Utilisez phone_number
au lieu de email
pour changer/vérifier un nouveau numéro de téléphone.
L'administrateur peut également activer l'option de connexion avec un nom d'utilisateur préféré par l'utilisateur. Notez que vous ne pourrez pas changer cette valeur pour un nom d'utilisateur ou un preferred_username déjà utilisé pour usurper l'identité d'un autre utilisateur.
Il est possible de récupérer un mot de passe en connaissant le nom d'utilisateur (ou l'email ou le téléphone est accepté) et en y ayant accès car un code y sera envoyé :
La réponse du serveur sera toujours positive, comme si le nom d'utilisateur existait. Vous ne pouvez pas utiliser cette méthode pour énumérer les utilisateurs.
Avec le code, vous pouvez changer le mot de passe avec :
Pour changer le mot de passe, vous devez connaître le mot de passe précédent :
Un pool d'utilisateurs prend en charge différentes manières de s'authentifier. Si vous avez un nom d'utilisateur et un mot de passe, il existe également différentes méthodes prises en charge pour se connecter. De plus, lorsqu'un utilisateur est authentifié dans le Pool, 3 types de jetons sont fournis : Le jeton d'identité, le jeton d'accès et le jeton d'actualisation.
Jeton d'identité : Il contient des revendications sur l'identité de l'utilisateur authentifié, telles que name
, email
et phone_number
. Le jeton d'identité peut également être utilisé pour authentifier les utilisateurs auprès de vos serveurs de ressources ou applications serveur. Vous devez vérifier la signature du jeton d'identité avant de pouvoir faire confiance à des revendications à l'intérieur du jeton d'identité si vous l'utilisez dans des applications externes.
Le jeton d'identité est le jeton qui contient les valeurs des attributs de l'utilisateur, même les personnalisés.
Jeton d'accès : Il contient des revendications sur l'utilisateur authentifié, une liste des groupes de l'utilisateur et une liste de portées. Le but du jeton d'accès est de autoriser les opérations API dans le contexte de l'utilisateur dans le pool d'utilisateurs. Par exemple, vous pouvez utiliser le jeton d'accès pour accorder à votre utilisateur l'accès pour ajouter, modifier ou supprimer des attributs d'utilisateur.
Jeton d'actualisation : Avec les jetons d'actualisation, vous pouvez obtenir de nouveaux jetons d'identité et jetons d'accès pour l'utilisateur jusqu'à ce que le jeton d'actualisation soit invalide. Par défaut, le jeton d'actualisation expire 30 jours après que l'utilisateur de votre application se connecte à votre pool d'utilisateurs. Lorsque vous créez une application pour votre pool d'utilisateurs, vous pouvez définir l'expiration du jeton d'actualisation de l'application à n'importe quelle valeur entre 60 minutes et 10 ans.
Voici le flux d'authentification côté serveur :
L'application côté serveur appelle l'opération API AdminInitiateAuth
(au lieu de InitiateAuth
). Cette opération nécessite des identifiants AWS avec des autorisations qui incluent cognito-idp:AdminInitiateAuth
et cognito-idp:AdminRespondToAuthChallenge
. L'opération renvoie les paramètres d'authentification requis.
Après que l'application côté serveur a les paramètres d'authentification, elle appelle l'opération API AdminRespondToAuthChallenge
. L'opération API AdminRespondToAuthChallenge
ne réussit que si vous fournissez des identifiants AWS.
Cette méthode n'est PAS activée par défaut.
Pour se connecter, vous devez connaître :
l'identifiant du pool d'utilisateurs
l'identifiant du client
le nom d'utilisateur
le mot de passe
le secret du client (uniquement si l'application est configurée pour utiliser un secret)
Pour pouvoir se connecter avec cette méthode, cette application doit autoriser la connexion avec ALLOW_ADMIN_USER_PASSWORD_AUTH
.
De plus, pour effectuer cette action, vous avez besoin d'identifiants avec les autorisations cognito-idp:AdminInitiateAuth
et cognito-idp:AdminRespondToAuthChallenge