detecting-oauth-token-theft について
Microsoft Entra ID と Azure/M365 環境で OAuth トークンの盗難を調査・防止する、アイデンティティセキュリティおよびインシデント対応向けのスキルです。リスク検知、トークン保護、ログ分析、対応手順を扱います。
主な機能
- 01一般的なトークン窃取手法の特定
- 02リスク検知と条件付きアクセスの設定
- 03KQL によるトークンリプレイの調査
- 04セッション無効化と対応手順の実施
- 05継続的アクセス評価とセッションポリシーの有効化
活用シーン
- 01異常なサインインや不可能な移動のアラート調査
- 02セッションハイジャックやトークンリプレイの疑いへの対応
- 03MFA を回避するデバイスコードフィッシングへの防御
- 04Entra ID のトークン保護ポリシーの設定
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ mukul975/ anthropic-cybersecurity-skills --skill detecting-oauth-token-theftインストール後、Claude Code で/detecting-oauth-token-theftを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
LICENSEreferences/api-reference.mdscripts/agent.py詳細
OAuth トークン窃取の検出
使用する場面
- Microsoft Entra ID で不可能な移動や異常なトークン使用に関するアラートを調査する場合
- セッションハイジャックやパス・ザ・クッキー攻撃が疑われる場合に対応する場合
- Azure/M365 環境で OAuth トークン窃取に対する事前防御を設定する場合
- MFA を回避する OAuth デバイスコードフィッシングキャンペーンを検出する場合
- トークンリプレイの兆候についてサインインログを分析する場合
- トークンをデバイスに紐付ける Token Protection 条件付きアクセス ポリシーを実装する場合
使用しないでください。オンプレミスの Kerberos チケット攻撃(パス・ザ・チケット、ゴールデンチケット)には使用しないでください。これらのシナリオでは、Active Directory 固有の調査手法を使用してください。
前提条件
- Microsoft Entra ID P2 ライセンス(Identity Protection のリスク検出と条件付きアクセスに必要)
- Entra 管理センターのグローバル管理者またはセキュリティ管理者ロール
- セッション異常検出用の Microsoft Defender for Cloud Apps(MDCA)ライセンス
- Entra ID のサインインログと監査ログへのアクセス(Log Analytics または Sentinel にログを送信するよう診断設定が構成されている必要があります)
- OAuth 2.0 認可フロー(認可コード、デバイスコード、クライアント資格情報)の知識
- Entra ID のサインインログと監査ログを取り込む Microsoft Sentinel または同等の SIEM
ワークフロー
ステップ 1:トークン窃取の攻撃対象領域を理解する
リスクのあるトークンの種類と、その窃取方法を特定します。
Token Type | Lifetime | Theft Vector | Impact
----------------------|-------------|----------------------------------|------------------
Access Token | 60-90 min | Memory dump, proxy interception | API access for token lifetime
Refresh Token | Up to 90 days| Browser cookie theft, malware | Persistent access, new access tokens
Primary Refresh Token | Session-based| Mimikatz, AADInternals, malware | Full SSO to all M365/Azure apps
Session Cookie | Varies | XSS, browser exploit, AitM proxy | Full session hijacking
Device Code Token | 15 min auth | Phishing (device code flow abuse)| Attacker gets refresh token via social engineering
一般的な攻撃手法:
- AitM フィッシング(中間者攻撃):攻撃者は Evilginx2 などのツールを使って正規のログインページをプロキシし、ユーザーが MFA を完了した後にセッション Cookie とトークンを取得します
- デバイスコードフィッシング:攻撃者がデバイスコードを生成してメールや Teams で被害者に送り、被害者が認証すると、攻撃者がトークンを受け取ります
- PRT 抽出:デバイスのローカル管理者権限を持つ攻撃者が、Mimikatz(
sekurlsa::cloudap)または AADInternals を使用してプライマリ更新トークンを抽出します - ブラウザー Cookie の窃取:マルウェアまたはインフォスティーラーが、セッショントークンを含むブラウザー Cookie を外部に持ち出します
ステップ 2:Entra ID のサインインリスク検出を構成する
Identity Protection を有効にして、異常なトークン使用にフラグを付けます。
Entra Admin Center > Protection > Identity Protection > Risk Detections
Key risk detections for token theft:
- Anomalous Token : Token has unusual characteristics (claim anomalies)
- Token Issuer Anomaly : Token issued by an unusual token issuer
- Unfamiliar Sign-in : Sign-in from a location not seen before for the user
- Impossible Travel : Sign-ins from geographically distant locations in impossible time
- Malicious IP Address : Sign-in from a known malicious IP
- Suspicious Browser : Sign-in from a suspicious or attacker-controlled browser
リスクベースの条件付きアクセスを構成します。
Entra Admin Center > Protection > Conditional Access > New Policy
Policy Name: "Block High-Risk Sign-ins - Token Theft Protection"
Assignments:
Users: All users (exclude break-glass accounts)
Cloud Apps: All cloud apps
Conditions:
Sign-in Risk: High
Grant:
Block access
Policy Name: "Require MFA for Medium-Risk Sign-ins"
Assignments:
Users: All users
Cloud Apps: All cloud apps
Conditions:
Sign-in Risk: Medium
Grant:
Require multifactor authentication
Require password change
ステップ 3:Token Protection を有効にする(プレビュー)
Token Protection を構成し、サインインセッションのトークンをデバイスに紐付けます。
Entra Admin Center > Protection > Conditional Access > New Policy
Policy Name: "Enforce Token Protection for Desktop Sessions"
Assignments:
Users: All users (start with a pilot group)
Cloud Apps: Office 365 Exchange Online, Office 365 SharePoint Online
Conditions:
Device Platforms: Windows
Session:
Require token protection for sign-in sessions (Preview): Enabled
Grant:
Require device to be marked as compliant
OR Require Hybrid Azure AD joined device
Token Protection は、アクセス トークンをデバイスのトラステッド プラットフォーム モジュール(TPM)に暗号学的に紐付けます。攻撃者がトークンを窃取し、別のデバイスからリプレイした場合、所有証明キーが一致しないため、トークンは拒否されます。
ステップ 4:サインインログでトークンリプレイを検出する
トークン窃取の兆候について Entra のサインインログをクエリします。
// KQL query for Microsoft Sentinel or Log Analytics
// Detect sign-ins where the token was issued in one location and used in another
SigninLogs
| where TimeGenerated > ago(7d)
| where RiskDetail contains "token" or RiskEventTypes_V2 has "anomalousToken"
| project TimeGenerated, UserPrincipalName, IPAddress, Location,
RiskDetail, RiskLevelDuringSignIn, AppDisplayName,
DeviceDetail, ClientAppUsed, TokenIssuerType
| sort by TimeGenerated desc
// Detect impossible travel with token reuse
SigninLogs
| where TimeGenerated > ago(7d)
| where ResultType == 0 // Successful sign-ins only
| summarize Locations=make_set(Location), IPs=make_set(IPAddress),
Count=count() by UserPrincipalName, bin(TimeGenerated, 1h)
| where array_length(Locations) > 1
| sort by TimeGenerated desc
// Detect device code flow abuse (often used in phishing)
SigninLogs
| where TimeGenerated > ago(7d)
| where AuthenticationProtocol == "deviceCode"
| project TimeGenerated, UserPrincipalName, IPAddress, Location,
AppDisplayName, DeviceDetail, ResultType
| sort by TimeGenerated desc
// Detect token replay: same token used from multiple IPs
AADNonInteractiveUserSignInLogs
| where TimeGenerated > ago(7d)
| where ResultType == 0
| summarize IPs=make_set(IPAddress), IPCount=dcount(IPAddress)
by UserPrincipalName, CorrelationId
| where IPCount > 1
| sort by IPCount desc
ステップ 5:トークン窃取を調査して対応する
トークン窃取イベントが検出されたら、次の対応手順に従います。
# Step 5a: Revoke all refresh tokens for the compromised user
# Microsoft Graph PowerShell
Connect-MgGraph -Scopes "User.ReadWrite.All"
Revoke-MgUserSignInSession -UserId "[email protected]"
# Step 5b: Force password reset
Update-MgUser -UserId "[email protected]" -PasswordProfile @{
ForceChangePasswordNextSignIn = $true
}
# Step 5c: Review and revoke OAuth app consent grants
# Check for malicious app consent (common post-compromise persistence)
Get-MgUserOauth2PermissionGrant -UserId "[email protected]" |
Select-Object ClientId, ConsentType, Scope
# Remove suspicious OAuth grants
Remove-MgOauth2PermissionGrant -OAuth2PermissionGrantId "<grant-id>"
# Step 5d: Review enterprise app registrations for rogue apps
Get-MgServicePrincipal -Filter "displayName eq 'Suspicious App'" |
Select-Object AppId, DisplayName, SignInAudience
# Step 5e: Check for mail forwarding rules (common post-compromise action)
Get-MgUserMailFolderRule -UserId "[email protected]" -MailFolderId "Inbox" |
Where-Object { $_.Actions.ForwardTo -ne $null -or $_.Actions.RedirectTo -ne $null }
ステップ 6:継続的アクセス評価(CAE)を実装する
条件が変化した際にほぼリアルタイムでトークンを失効させるため、CAE を有効にします。
Entra Admin Center > Protection > Conditional Access > Continuous Access Evaluation
Settings:
Strictly enforce location policies: Enabled
CAE ensures that when you revoke a user's session or change their
risk level, the enforcement happens within minutes rather than waiting
for the access token to naturally expire (60-90 minutes).
Critical events that trigger immediate token revocation with CAE:
- User account disabled or deleted
- Password changed or reset
- MFA enabled for the user
- Admin explicitly revokes refresh tokens
- Azure AD Identity Protection detects elevated user risk
- Network location change violates conditional access policy
ステップ 7:Defender for Cloud Apps のセッションポリシーを構成する
疑わしいトークン使用を検出してブロックするため、リアルタイムのセッション監視を設定します。
Microsoft Defender for Cloud Apps > Policies > Session Policies
Policy: "Block download from unmanaged device with stolen token"
Session Control Type: Monitor and block activities
Activity Source: App = Office 365, SharePoint Online
Activity Filter: Device tag does not equal "Compliant"
Activity Type: Download
Action: Block
Policy: "Alert on mass file download (exfiltration via stolen token)"
Session Control Type: Monitor only
Activity Source: App = Office 365
Activity Filter: Repeated activity > 10 downloads in 5 minutes
Action: Alert administrators
主な概念
| 用語 | 定義 |
|---|---|
| Primary Refresh Token(PRT) | 登録済みデバイスに発行される長期間有効なトークンです。デバイスの TPM に暗号学的に結び付けられており、Azure AD と統合されたすべてのアプリケーションでシングルサインオン(SSO)を提供します |
| Token Protection | サインインセッショントークンをデバイスに結び付け、他のデバイスからのリプレイを防ぐ Entra ID の条件付きアクセス機能です |
| Continuous Access Evaluation(CAE) | リソースプロバイダーが Entra ID の重要なイベントをサブスクライブできるようにすることで、セキュリティポリシーをほぼリアルタイムで適用するプロトコルです |
| AitM(Adversary-in-the-Middle) | 攻撃者が正規の認証フローをプロキシし、被害者が MFA を完了した後にセッション Cookie を取得するフィッシング手法です |
| Device Code Flow | 入力制約のあるデバイス向けの OAuth 2.0 認可グラントです。攻撃者はフィッシングを通じて被害者にデバイスコードを送信し、これを悪用します |
| Proof of Possession(PoP) | トークンにデバイスキーと結び付いたクレームを含める暗号学的メカニズムです。これにより、トークンを取得したデバイスだけがそのトークンを使用できます |
| Refresh Token | 再認証なしで新しいアクセストークンを取得するために使用する、長期間有効な OAuth トークン(最長 90 日)です。永続的なアクセスを狙う主な標的です |
検証
- Identity Protection のリスク検出が有効になっており、異常なトークンアクティビティに対するアラートが生成されている
- 条件付きアクセス ポリシーが高リスクのサインインをブロックし、中リスクの場合に MFA を要求する
- Token Protection ポリシーがパイロットグループに適用され、正常に機能することが確認されている(未登録デバイスからのテストが失敗する)
- Sentinel の KQL クエリが、合成したトークン異常イベントに対するテストで結果を返す
- Continuous Access Evaluation が有効で、検証済みである(セッションを取り消し、数分以内にアクセスがブロックされることを確認する)
- Defender for Cloud Apps のセッションポリシーが有効で、ダウンロードアクティビティを監視している
- 条件付きアクセスを通じて Device Code Flow が制限されている(ブロックするか、準拠デバイスを要求する)
- インシデント対応ランブックに、トークンの取り消し、パスワードのリセット、OAuth 同意の確認手順が含まれている
- メール転送ルールと OAuth アプリの付与が、侵害されたアカウントについて監査されている