27 KiB
OAuth vers la prise de contrôle de compte
☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥
- Travaillez-vous dans une entreprise de cybersécurité ? Voulez-vous voir votre entreprise annoncée dans HackTricks ? ou voulez-vous avoir accès à la dernière version de PEASS ou télécharger HackTricks en PDF ? Consultez les PLANS D'ABONNEMENT !
- Découvrez The PEASS Family, notre collection exclusive de NFTs
- Obtenez le swag officiel PEASS & HackTricks
- Rejoignez le 💬 groupe Discord ou le groupe telegram ou suivez moi sur Twitter 🐦@carlospolopm.
- Partagez vos astuces de piratage en soumettant des PR au repo hacktricks et au repo hacktricks-cloud.
Informations de base
Il existe plusieurs versions d'OAuth, vous pouvez lire https://oauth.net/2/ pour avoir une compréhension de base.
Dans cet article, nous nous concentrerons sur le flux le plus courant que vous rencontrerez aujourd'hui, qui est le type de subvention de code d'autorisation OAuth 2.0. En substance, OAuth fournit aux développeurs un mécanisme d'autorisation pour permettre à une application d'accéder à des données ou d'effectuer certaines actions contre votre compte, à partir d'une autre application (le serveur d'autorisation).
Par exemple, supposons que le site web https://yourtweetreader.com ait une fonctionnalité pour afficher tous les tweets que vous avez jamais envoyés, y compris les tweets privés. Pour ce faire, OAuth 2.0 est introduit. https://yourtweetreader.com vous demandera d'autoriser leur application Twitter à accéder à tous vos tweets. Une page de consentement apparaîtra sur https://twitter.com affichant les autorisations demandées, et qui est le développeur qui le demande. Une fois que vous avez autorisé la demande, https://yourtweetreader.com sera en mesure d'accéder à vos tweets en votre nom.
Les éléments importants à comprendre dans un contexte OAuth 2.0 :
- propriétaire de la ressource : Le
propriétaire de la ressource
est l'utilisateur/entité accordant l'accès à sa ressource protégée, telle que ses tweets de compte Twitter. Dans cet exemple, ce serait vous. - serveur de ressources : Le
serveur de ressources
est le serveur qui gère les demandes authentifiées après que l'application a obtenu unjeton d'accès
au nom dupropriétaire de la ressource
. Dans cet exemple, ce serait https://twitter.com - application cliente : L'
application cliente
est l'application qui demande l'autorisation dupropriétaire de la ressource
. Dans cet exemple, ce serait https://yourtweetreader.com. - serveur d'autorisation : Le
serveur d'autorisation
est le serveur qui émet desjetons d'accès
à l'application cliente
après avoir authentifié avec succès lepropriétaire de la ressource
et obtenu l'autorisation. Dans l'exemple ci-dessus, ce serait https://twitter.com - client_id : Le
client_id
est l'identifiant de l'application. Il s'agit d'un identifiant unique public, non secret. - client_secret : Le
client_secret
est un secret connu uniquement de l'application et du serveur d'autorisation. Cela est utilisé pour générer desjetons d'accès
. - response_type : Le
response_type
est une valeur pour détailler quel type de jeton est demandé, tel quecode
- scope : Le
scope
est le niveau d'accès demandé que l'application cliente
demande dupropriétaire de la ressource
- redirect_uri : Le
redirect_uri
est l'URL vers laquelle l'utilisateur est redirigé après la fin de l'autorisation. Cela doit généralement correspondre à l'URL de redirection que vous avez précédemment enregistrée auprès du service - state : Le paramètre
state
peut persister les données entre la redirection de l'utilisateur vers le serveur d'autorisation et le retour. Il est important que cela soit une valeur unique car il sert de mécanisme de protection CSRF s'il contient une valeur unique ou aléatoire par demande - grant_type : Le paramètre
grant_type
explique quel est le type de subvention, et quel jeton va être retourné - code : Ce
code
est le code d'autorisation reçu duserveur d'autorisation
qui sera dans le paramètre de chaîne de requête "code" dans cette demande. Ce code est utilisé conjointement avec leclient_id
et leclient_secret
par l'application cliente pour récupérer unjeton d'accès
- access_token : Le
access_token
est le jeton que l'application cliente utilise pour effectuer des demandes API au nom d'unpropriétaire de la ressource
- refresh_token : Le
refresh_token
permet à une application d'obtenir un nouveaujeton d'accès
sans demander à l'utilisateur
Exemple réel
En mettant tout cela ensemble, voici à quoi ressemble un flux OAuth réel :
- Vous visitez https://yourtweetreader.com et cliquez sur le bouton "Intégrer avec Twitter".
- https://yourtweetreader.com envoie une demande à https://twitter.com vous demandant, le propriétaire de la ressource, d'autoriser l'application Twitter de https://yourtweetreader.com à accéder à vos tweets. La demande ressemblera à :
https://twitter.com/auth
?response_type=code
&client_id=yourtweetreader_clientId
&redirect_uri=https%3A%2F%2Fyourtweetreader.com%2Fcallback
&scope=readTweets
&state=kasodk9d1jd992k9klaskdh123
3. Vous serez invité à une page de consentement :
4. Une fois accepté, Twitter enverra une demande de retour à l'redirect_uri
avec les paramètres code
et state
:
https://yourtweetreader.com?code=asd91j3jd91j92j1j9d1&state=kasodk9d1jd992k9klaskdh123
5. Ensuite, https://yourtweetreader.com prendra ce code
et, en utilisant l'client_id
et le client_secret
de leur application, fera une demande depuis le serveur pour récupérer un access_token
en votre nom, ce qui leur permettra d'accéder aux autorisations auxquelles vous avez consenti :
POST /oauth/access_token
Host: twitter.com
...{"client_id": "yourtweetreader_clientId", "client_secret": "yourtweetreader_clientSecret", "code": "asd91j3jd91j92j1j9d1", "grant_type": "authorization_code"}
6. Enfin, le flux est complet et https://yourtweetreader.com fera un appel API à Twitter avec votre access_token
pour accéder à vos Tweets.
Découvertes de Bug Bounty
Maintenant, la partie intéressante ! Il y a de nombreuses choses qui peuvent mal tourner dans une implémentation OAuth, voici les différentes catégories de bugs que je vois fréquemment :
Configuration de redirect_uri
faible
Le redirect_uri
est très important car des données sensibles, telles que le code
, sont ajoutées à cette URL après l'autorisation. Si le redirect_uri
peut être redirigé vers un serveur contrôlé par un attaquant, cela signifie que l'attaquant peut potentiellement prendre le contrôle du compte d'une victime en utilisant le code
lui-même et en accédant aux données de la victime.
La façon dont cela va être exploité va varier en fonction du serveur d'autorisation. Certains n'accepteront que le même chemin exact de redirect_uri
spécifié dans l'application cliente, mais certains accepteront n'importe quoi dans le même domaine ou sous-répertoire de redirect_uri
.
En fonction de la logique gérée par le serveur, il existe plusieurs techniques pour contourner un redirect_uri
. Dans une situation où un redirect_uri
est https://yourtweetreader.com/callback, celles-ci incluent :
- Redirections ouvertes :
https://yourtweetreader.com
/callback?redirectUrl=https://evil.com
- Traversée de chemin :
https://yourtweetreader.com/callback/../redirect?url=https://evil.com
- Regexes de
redirect_uri
faibles :https://yourtweetreader.com.evil.com
- Injection HTML et vol de jetons via l'en-tête referer :
https://yourtweetreader.com/callback/home/attackerimg.jpg
D'autres paramètres qui peuvent être vulnérables aux redirections ouvertes sont :
- client_uri - URL de la page d'accueil de l'application cliente
- policy_uri - URL que l'application cliente Relying Party fournit afin que l'utilisateur final puisse lire comment ses données de profil seront utilisées.
- tos_uri - URL que le client Relying Party fournit afin que l'utilisateur final puisse lire les conditions d'utilisation de la Relying Party.
- initiate_login_uri - URI utilisant le schéma https qu'un tiers peut utiliser pour initier une connexion par le RP. Doit également être utilisé pour la redirection côté client.
Tous ces paramètres sont optionnels selon les spécifications OAuth et OpenID et ne sont pas toujours pris en charge sur un serveur particulier, il est donc toujours utile d'identifier quels paramètres sont pris en charge sur votre serveur.
Si vous ciblez un serveur OpenID, le point de découverte à **.well-known/openid-configuration
** contient parfois des paramètres tels que "registration_endpoint", "request_uri_parameter_supported", et "require_request_uri_registration". Cela peut vous aider à trouver le point de terminaison d'enregistrement et d'autres valeurs de configuration de serveur.
XSS dans l'implémentation de redirection
Comme mentionné dans ce rapport de bug bounty https://blog.dixitaditya.com/2021/11/19/account-takeover-chain.html, il est possible que l'URL de redirection soit reflétée dans la réponse du serveur après l'authentification de l'utilisateur, étant vulnérable à XSS. Charge utile possible à tester :
https://app.victim.com/login?redirectUrl=https://app.victim.com/dashboard</script><h1>test</h1>
CSRF - Mauvaise gestion du paramètre d'état
Très souvent, le paramètre state
est complètement omis ou utilisé de manière incorrecte. Si un paramètre d'état est inexistant, ou une valeur statique qui ne change jamais, le flux OAuth sera très probablement vulnérable aux attaques CSRF. Parfois, même s'il y a un paramètre state
, l'application pourrait ne pas valider le paramètre et une attaque réussira. La façon d'exploiter cela serait de passer par le processus d'autorisation sur votre propre compte, et de faire une pause juste après l'autorisation. Vous rencontrerez alors une demande telle que:
https://yourtweetreader.com?code=asd91j3jd91j92j1j9d1
Une fois que vous avez reçu cette demande, vous pouvez abandonner la demande car ces codes sont généralement à usage unique. Vous pouvez ensuite envoyer cette URL à un utilisateur connecté, et cela ajoutera votre compte à leur compte. Au début, cela peut ne pas sembler très sensible car vous ajoutez simplement votre compte au compte d'une victime. Cependant, de nombreuses implémentations OAuth sont destinées à des fins de connexion, donc si vous pouvez ajouter votre compte Google qui est utilisé pour vous connecter, vous pourriez potentiellement effectuer une prise de contrôle de compte en un seul clic, car vous connecter avec votre compte Google vous donnerait accès au compte de la victime.
Vous pouvez trouver un exemple à ce sujet dans ce write-up CTF et dans la boîte HTB appelée Oouch.
J'ai également vu le paramètre d'état utilisé comme une valeur de redirection supplémentaire plusieurs fois. L'application utilisera redirect_uri
pour la redirection initiale, mais ensuite le paramètre state
comme une deuxième redirection qui pourrait contenir le code
dans les paramètres de requête, ou le header referer.
Une chose importante à noter est que cela ne s'applique pas seulement aux situations de connexion et de prise de contrôle de compte. J'ai vu des erreurs de configuration dans :
- Les intégrations Slack permettant à un attaquant d'ajouter son compte Slack en tant que destinataire de toutes les notifications/messages
- Les intégrations Stripe permettant à un attaquant de remplacer les informations de paiement et d'accepter des paiements des clients de la victime
- Les intégrations PayPal permettant à un attaquant d'ajouter son compte PayPal au compte de la victime, ce qui déposerait de l'argent sur le compte PayPal de l'attaquant
Pré-prise de contrôle de compte
L'un des autres problèmes les plus courants que je vois est lorsque les applications permettent de "Se connecter avec X" mais aussi un nom d'utilisateur/mot de passe. Il y a 2 façons différentes d'attaquer cela :
- Si l'application ne nécessite pas de vérification d'e-mail lors de la création de compte, essayez de créer un compte avec l'adresse e-mail de la victime et un mot de passe d'attaquant avant que la victime ne se soit inscrite. Si la victime essaie ensuite de s'inscrire ou de se connecter avec un tiers, comme Google, il est possible que l'application fasse une recherche, voie que l'e-mail est déjà enregistré, puis lie leur compte Google au compte créé par l'attaquant. C'est une "prise de contrôle de compte préalable" où un attaquant aura accès au compte de la victime s'il l'a créé avant que la victime ne s'inscrive.
- Si une application OAuth ne nécessite pas de vérification d'e-mail, essayez de vous inscrire avec cette application OAuth avec l'adresse e-mail de la victime. Le même problème que ci-dessus pourrait exister, mais vous attaqueriez dans l'autre sens et accéderiez au compte de la victime pour une prise de contrôle de compte.
Divulgation de secrets
Il est très important de reconnaître lesquels des nombreux paramètres OAuth sont secrets, et de les protéger. Par exemple, divulguer le client_id
est parfaitement acceptable et nécessaire, mais divulguer le client_secret
est dangereux. Si cela est divulgué, l'attaquant peut potentiellement abuser de la confiance et de l'identité de l'application client de confiance pour voler les access_tokens
des utilisateurs et les informations/accès privés pour leurs comptes intégrés. Revenons à notre exemple précédent, un problème que j'ai vu est de réaliser cette étape depuis le client, au lieu du serveur :
5. https://yourtweetreader.com prendra ensuite ce code
, et en utilisant l'client_id
et le client_secret
de leur application, fera une demande depuis le serveur pour récupérer un access_token
en votre nom, ce qui leur permettra d'accéder aux autorisations auxquelles vous avez consenti.
Si cela est fait depuis le client, le client_secret
sera divulgué et les utilisateurs pourront générer des access_tokens
au nom de l'application. Avec un peu d'ingénierie sociale, ils peuvent également ajouter plus de portées à l'autorisation OAuth et tout cela semblera légitime car la demande viendra de l'application client de confiance.
Bruteforce du secret client
Vous pouvez essayer de bruteforcer le secret client d'un fournisseur de services avec le fournisseur d'identité afin d'essayer de voler des comptes.
La demande de BF peut ressembler à :
POST /token HTTP/1.1
content-type: application/x-www-form-urlencoded
host: 10.10.10.10:3000
content-length: 135
Connection: close
code=77515&redirect_uri=http%3A%2F%2F10.10.10.10%3A3000%2Fcallback&grant_type=authorization_code&client_id=public_client_id&client_secret=[bruteforce]
Fuite de l'en-tête Referer avec le code + l'état
Une fois que le client a le code et l'état, s'il est réfléchi dans l'en-tête Referer lorsqu'il navigue vers une autre page, alors il est vulnérable.
Jeton d'accès stocké dans l'historique du navigateur
Accédez à l'historique du navigateur et vérifiez si le jeton d'accès est enregistré.
Code d'autorisation éternel
Le code d'autorisation ne doit vivre que pendant un certain temps pour limiter la fenêtre de temps pendant laquelle un attaquant peut le voler et l'utiliser.
Jeton d'autorisation/rafraîchissement non lié au client
Si vous pouvez obtenir le code d'autorisation et l'utiliser avec un client différent, vous pouvez prendre le contrôle d'autres comptes.
Chemins heureux, XSS, Iframes et messages postaux pour divulguer les valeurs de code et d'état
AWS Cognito
Dans ce rapport de prime de bug: https://security.lauritz-holtmann.de/advisories/flickr-account-takeover/, vous pouvez voir que le jeton que AWS Cognito renvoie à l'utilisateur peut avoir suffisamment de permissions pour écraser les données utilisateur. Par conséquent, si vous pouvez changer l'e-mail de l'utilisateur pour un e-mail d'utilisateur différent, vous pourriez être en mesure de prendre le contrôle d'autres comptes.
# Read info of the user
aws cognito-idp get-user --region us-east-1 --access-token eyJraWQiOiJPVj[...]
# Change email address
aws cognito-idp update-user-attributes --region us-east-1 --access-token eyJraWQ[...] --user-attributes Name=email,Value=imaginary@flickr.com
{
"CodeDeliveryDetailsList": [
{
"Destination": "i***@f***.com",
"DeliveryMedium": "EMAIL",
"AttributeName": "email"
}
]
}
Pour plus d'informations détaillées sur la façon d'abuser d'AWS Cognito, consultez :
{% embed url="https://cloud.hacktricks.xyz/pentesting-cloud/aws-pentesting/aws-unauthenticated-enum-access/aws-cognito-unauthenticated-enum" %}
Paramètres SSRF
L'un des URL cachés que vous pourriez manquer est le point d'extrémité d'enregistrement de client dynamique. Afin d'authentifier avec succès les utilisateurs, les serveurs OAuth ont besoin de connaître les détails de l'application cliente, tels que le "client_name", "client_secret", "redirect_uris", et ainsi de suite. Ces détails peuvent être fournis via une configuration locale, mais les serveurs d'autorisation OAuth peuvent également avoir un point d'extrémité d'enregistrement spécial. Cet endpoint est normalement mappé sur "/register" et accepte des requêtes POST avec le format suivant :
POST /connect/register HTTP/1.1
Content-Type: application/json
Host: server.example.com
Authorization: Bearer eyJhbGciOiJSUzI1NiJ9.eyJ ...
{
"application_type": "web",
"redirect_uris": ["https://client.example.org/callback"],
"client_name": "My Example",
"logo_uri": "https://client.example.org/logo.png",
"subject_type": "pairwise",
"sector_identifier_uri": "https://example.org/rdrct_uris.json",
"token_endpoint_auth_method": "client_secret_basic",
"jwks_uri": "https://client.example.org/public_keys.jwks",
"contacts": ["ve7jtb@example.org"],
"request_uris": ["https://client.example.org/rf.txt"]
}
Il y a deux spécifications qui définissent les paramètres de cette requête: RFC7591 pour OAuth et Openid Connect Registration 1.0.
Comme vous pouvez le voir ici, un certain nombre de ces valeurs sont transmises via des références d'URL et ressemblent à des cibles potentielles pour Server Side Request Forgery. En même temps, la plupart des serveurs que nous avons testés ne résolvent pas immédiatement ces URL lorsqu'ils reçoivent une demande d'enregistrement. Au lieu de cela, ils enregistrent simplement ces paramètres et les utilisent plus tard pendant le flux d'autorisation OAuth. En d'autres termes, il s'agit plutôt d'une SSRF de deuxième ordre, ce qui rend la détection en boîte noire plus difficile.
Les paramètres suivants sont particulièrement intéressants pour les attaques SSRF:
-
logo_uri - URL qui fait référence à un logo pour l'application cliente. Après avoir enregistré un client, vous pouvez essayer d'appeler le point de terminaison d'autorisation OAuth ("/authorize") en utilisant votre nouveau "client_id". Après la connexion, le serveur vous demandera d'approuver la demande et peut afficher l'image de "logo_uri". Si le serveur récupère l'image par lui-même, la SSRF devrait être déclenchée à cette étape. Alternativement, le serveur peut simplement inclure le logo via une balise "<img>" côté client. Bien que cela ne conduise pas à une SSRF, cela peut conduire à une XSS si l'URL n'est pas échappée.
-
jwks_uri - URL pour le document JSON Web Key Set [JWK] du client. Ce jeu de clés est nécessaire sur le serveur pour valider les demandes signées effectuées vers le point de terminaison de jeton lors de l'utilisation de JWT pour l'authentification du client [RFC7523]. Pour tester la SSRF dans ce paramètre, enregistrez une nouvelle application cliente avec un "jwks_uri" malveillant, effectuez le processus d'autorisation pour obtenir un code d'autorisation pour n'importe quel utilisateur, puis récupérez le point de terminaison "/token" avec le corps suivant:
POST /oauth/token HTTP/1.1
...
``
grant_type=authorization_code&code=n0esc3NRze7LTCu7iYzS6a5acc3f0ogp4&client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer&client_assertion=eyJhbGci...
Si vulnérable, le serveur devrait effectuer une requête HTTP serveur à serveur vers le "jwks_uri" fourni car il a besoin de cette clé pour vérifier la validité du paramètre "client_assertion" dans votre demande. Ce sera probablement seulement une vulnérabilité SSRF aveugle cependant, car le serveur s'attend à une réponse JSON appropriée.
-
sector_identifier_uri - Cette URL fait référence à un fichier avec un seul tableau JSON de valeurs redirect_uri. Si pris en charge, le serveur peut récupérer cette valeur dès que vous soumettez la demande d'enregistrement dynamique. Si cela n'est pas récupéré immédiatement, essayez d'effectuer une autorisation pour ce client sur le serveur. Comme il doit connaître les redirect_uris pour terminer le flux d'autorisation, cela forcera le serveur à effectuer une demande à votre sector_identifier_uri malveillant.
-
request_uris - Un tableau des request_uris autorisées pour ce client. Le paramètre "request_uri" peut être pris en charge sur le point de terminaison d'autorisation pour fournir une URL qui contient un JWT avec les informations de demande (voir https://openid.net/specs/openid-connect-core-1_0.html#rfc.section.6.2).
Même si l'enregistrement dynamique du client n'est pas activé, ou s'il nécessite une authentification, nous pouvons essayer de réaliser une SSRF sur le point de terminaison d'autorisation simplement en utilisant "request_uri":\
GET /authorize?response_type=code%20id_token&client_id=sclient1&request_uri=https://ybd1rc7ylpbqzygoahtjh6v0frlh96.burpcollaborator.net/request.jwt
Note: ne confondez pas ce paramètre avec "redirect_uri". Le "redirect_uri" est utilisé pour la redirection après l'autorisation, tandis que "request_uri" est récupéré par le serveur au début du processus d'autorisation.
En même temps, de nombreux serveurs que nous avons vus n'autorisent pas des valeurs "request_uri" arbitraires: ils n'autorisent que des URL figurant sur une liste blanche qui ont été pré-enregistrées lors du processus d'enregistrement du client. C'est pourquoi nous devons fournir "request_uris": "https://ybd1rc7ylpbqzygoahtjh6v0frlh96.burpcollaborator.net/request.jwt" au préalable.
Conditions de course des fournisseurs OAuth
Si la plateforme que vous testez est un fournisseur OAuth, lisez ceci pour tester les conditions de course possibles.
Références
- https://medium.com/a-bugz-life/the-wondeful-world-of-oauth-bug-bounty-edition-af3073b354c1
- https://portswigger.net/research/hidden-oauth-attack-vectors
☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥
- Travaillez-vous dans une entreprise de cybersécurité? Voulez-vous voir votre entreprise annoncée dans HackTricks? ou voulez-vous avoir accès à la dernière version de PEASS ou télécharger HackTricks en PDF? Consultez les PLANS D'ABONNEMENT!
- Découvrez The PEASS Family, notre collection exclusive de NFTs
- Obtenez le swag officiel PEASS & HackTricks
- Rejoignez le 💬 groupe Discord ou le groupe telegram ou suivez moi sur Twitter 🐦@carlospolopm.
- Partagez vos astuces de piratage en soumettant des PR au repo hacktricks et au repo hacktricks-cloud.