PRACTITIONER GUIDE | THREAT DETECTION
Practitioner GuideUpdated 14 min read

Detecting Entra ID Token Theft and Lateral Movement in Microsoft Sentinel

93%
of Microsoft cloud attacks in 2025 involved identity-based techniques rather than endpoint compromise, per Microsoft Digital Defense Report
AiTM
adversary-in-the-middle phishing bypasses MFA by stealing session cookies after authentication completes, not passwords, no failed sign-in events are generated
PRT
Primary Refresh Token extraction gives an attacker seamless SSO to all Entra-integrated applications, equivalent to domain admin in a cloud-first environment

SponsoredRetool

Retool's new app builder is where AI-generated code ships safely

Building apps with AI is easy. Getting them to production safely is another story.

Start building for free today

The sign-in event for a stolen OAuth token is a successful authentication. MFA is marked as satisfied. The user agent and IP address may differ from normal, but in a cloud environment where users travel and use multiple devices, those signals alone generate too many false positives to act on. Detecting Entra ID token theft and lateral movement requires correlating multiple signals: the authentication method, token lifetime anomalies, resource access patterns, and timing relationships between events that individually appear legitimate.

Attack 1: AiTM Phishing, Stolen Session Cookies

Adversary-in-the-middle phishing works by placing an attacker-controlled proxy between the user and the legitimate Microsoft login page. The user authenticates normally, satisfies MFA, and receives a session cookie. The proxy captures that cookie and replays it from a different IP address, giving the attacker an authenticated session without triggering another MFA prompt.

The detection signal is not a failed authentication, it is an impossible travel or token replay anomaly. The attacker's session uses the same session token but from a different IP, often within seconds of the legitimate user's successful sign-in.

Sentinel KQL, AiTM session replay detection:

SigninLogs
| where TimeGenerated > ago(1h)
| where ResultType == 0  // Successful sign-in
| where AuthenticationDetails contains "MFA"
| summarize
    Sessions = make_set(SessionId),
    IPs = make_set(IPAddress),
    Locations = make_set(LocationDetails.city),
    FirstSeen = min(TimeGenerated),
    LastSeen = max(TimeGenerated)
    by UserPrincipalName, AppDisplayName
| where array_length(IPs) > 1
    and datetime_diff('minute', LastSeen, FirstSeen) < 10
| project UserPrincipalName, AppDisplayName, IPs, Locations, FirstSeen, LastSeen

This surfaces users with successful MFA-satisfied sign-ins from multiple IPs within 10 minutes, the window during which an AiTM attacker replays the stolen cookie.

Attack 2: Device Code Flow Abuse

The OAuth 2.0 device code flow was designed for input-constrained devices like smart TVs. An attacker sends a phishing email asking the victim to enter a device code at microsoft.com/devicelogin, a legitimate Microsoft URL. When the victim enters the code and approves the request, the attacker receives a full OAuth token with the victim's permissions and no MFA challenge, because the user already authenticated.

Device code flow sign-ins are identifiable in Entra ID logs by their authentication method. They are legitimate in some contexts (VSCode, Azure CLI, some MDM enrollment flows) but rare enough that unexplained device code authentications warrant investigation.

Sentinel KQL, Device code authentication anomalies:

SigninLogs
| where TimeGenerated > ago(7d)
| where AuthenticationProtocol == "deviceCode"
| where ResultType == 0
| summarize
    DeviceCodeSignIns = count(),
    Apps = make_set(AppDisplayName),
    IPs = make_set(IPAddress)
    by UserPrincipalName
| where DeviceCodeSignIns > 0
// Exclude known legitimate device code users (VSCode, Azure CLI)
| where not(Apps has "Visual Studio Code" or Apps has "Microsoft Azure CLI")
| sort by DeviceCodeSignIns desc
Free daily briefing

Briefings like this, every morning before 9am.

Threat intel, active CVEs, and campaign alerts, distilled for practitioners. 50,000+ subscribers. No noise.

Attack 3: Primary Refresh Token Extraction

The Primary Refresh Token (PRT) is a long-lived credential stored on Entra ID-joined or registered Windows devices that provides seamless SSO across all Microsoft services. An attacker with code execution on a developer machine can extract the PRT using tools like ROADtoken or AADInternals and use it from a different machine to authenticate as the victim to any Entra-integrated application without triggering MFA.

PRT theft is detected by looking for authentication from Entra-joined devices using a PRT where the device ID does not match the device normally used by that user, or where the same PRT claim appears in sign-ins from geographically inconsistent locations.

Sentinel KQL, PRT authentication from unexpected devices:

SigninLogs
| where TimeGenerated > ago(7d)
| where ResultType == 0
| where AuthenticationDetails has "PrimaryRefreshToken"
| summarize
    Devices = make_set(DeviceDetail.deviceId),
    IPs = make_set(IPAddress),
    OS = make_set(DeviceDetail.operatingSystem)
    by UserPrincipalName
| extend DeviceCount = array_length(Devices)
| where DeviceCount > 2  // Alert on PRT use from more than 2 devices
| project UserPrincipalName, DeviceCount, Devices, IPs
| sort by DeviceCount desc

Attack 4: OAuth App Consent Phishing

Consent phishing tricks users into granting a malicious OAuth application access to their mailbox, OneDrive, or calendar. The malicious app is registered in a different tenant but requests delegated permissions via the standard OAuth consent flow. After consent, the attacker has persistent access that survives password resets and MFA changes, because the token belongs to the app, not to the user's session.

Detect consent to applications from external tenants, especially applications requesting high-privilege permissions (Mail.ReadWrite, Files.ReadWrite.All, User.Read.All).

Sentinel KQL, High-privilege consent grants to external apps:

AuditLogs
| where TimeGenerated > ago(7d)
| where OperationName == "Consent to application"
| where Result == "success"
| extend
    AppName = tostring(TargetResources[0].displayName),
    AppId = tostring(TargetResources[0].id),
    GrantedPermissions = tostring(AdditionalDetails)
| where GrantedPermissions has_any (
    "Mail.ReadWrite", "Files.ReadWrite.All",
    "User.Read.All", "Calendars.ReadWrite"
  )
| project
    TimeGenerated,
    InitiatedBy = InitiatedBy.user.userPrincipalName,
    AppName,
    GrantedPermissions
| sort by TimeGenerated desc

Attack 5: Cross-Tenant Lateral Movement via B2B

Organizations that configure Entra ID B2B cross-tenant access to allow partner or customer access may inadvertently create lateral movement paths. An attacker who compromises a user in a partner tenant can access your tenant's resources via B2B trust, appearing in your logs as an external guest with a legitimate token from the partner tenant.

Detect unusual cross-tenant access patterns, external principals accessing resources they have not historically accessed, or accessing resources outside their normal business hours.

Sentinel KQL, External tenant access anomalies:

SigninLogs
| where TimeGenerated > ago(7d)
| where HomeTenantId != ResourceTenantId  // Cross-tenant sign-in
| where ResultType == 0
| summarize
    AccessCount = count(),
    Resources = make_set(ResourceDisplayName),
    FirstSeen = min(TimeGenerated)
    by UserPrincipalName, HomeTenantId
| where AccessCount > 10  // Active cross-tenant users
| join kind=leftouter (
    // Compare to 30-day historical baseline
    SigninLogs
    | where TimeGenerated between (ago(37d) .. ago(7d))
    | where HomeTenantId != ResourceTenantId
    | summarize HistoricalCount = count() by UserPrincipalName
) on UserPrincipalName
| where isempty(HistoricalCount)  // No historical cross-tenant activity
| project UserPrincipalName, HomeTenantId, AccessCount, Resources, FirstSeen

Building a Baseline and Reducing False Positives

The queries above will generate false positives in any environment with legitimate device code use, frequent travel, or active B2B partnerships. Reduce noise by:

Building named location exclusions: Add your corporate office IP ranges and known VPN exit IPs as Named Locations in Entra ID. Exclude these from impossible travel detections, the signal you want is authentication from residential IPs, cloud hosting ranges, or countries where you have no employees.

Allowlisting known-good device code apps: Maintain a list of legitimate device code applications in your environment (Azure CLI, VSCode, Intune enrollment). Exclude these from device code detection alerts. Alert on all others.

Correlating with risky sign-in events: Entra ID Identity Protection already flags some of these patterns as risky sign-ins. In Sentinel, join SigninLogs against AADRiskySignIns to avoid duplicating detection work:

SigninLogs
| join kind=inner AADRiskySignIns on $left.CorrelationId == $right.CorrelationId
| where RiskLevelDuringSignIn in ("high", "medium")

The bottom line

Entra ID token theft does not look like a brute-force attack in your logs, it looks like a successful sign-in from an unusual location. The detection requires correlating authentication method, device history, token replay timing, and permission scope across multiple log sources. The KQL queries in this guide surface the behavioral anomalies that distinguish legitimate cloud access from stolen credential use.

Frequently asked questions

What is the difference between a session token and a Primary Refresh Token in Entra ID?

A session token is a short-lived cookie that grants access to a specific application for a limited time (typically 1 hour). A Primary Refresh Token (PRT) is a long-lived credential (valid for up to 90 days, renewable) stored on an Entra-joined device that can be used to silently obtain new access tokens for any Entra-integrated application without re-authentication.

Does Conditional Access prevent token theft attacks?

Partially. Conditional Access Token Protection (in preview as of 2024) binds tokens to the specific device that obtained them, preventing replay from other devices. Without Token Protection, Conditional Access policies evaluate the initial authentication but cannot prevent a stolen token from being replayed within its validity window.

How do I detect AiTM phishing before the token is used?

The pre-use detection is in email security, AiTM phishing kits like Evilginx2 and Modlishka have known infrastructure patterns and phishing page structures. Microsoft Defender for Office 365 and third-party email security tools detect many AiTM lure emails. After the token is stolen, the only detection is the replay anomaly in sign-in logs.

What should I investigate first when an Entra ID token theft alert fires?

Check what the stolen token accessed: in Sentinel, query SigninLogs and AuditLogs for all activity by the affected user in the 4 hours after the anomalous sign-in. Look for mailbox rule creation (common for email exfiltration), OAuth app consent grants, role assignments, and access to sensitive SharePoint/OneDrive files.

Can I revoke a stolen OAuth token?

Yes. Use Revoke-AzureADUserAllRefreshToken (PowerShell) or the revokeSignInSessions Graph API endpoint. This invalidates all refresh tokens for the user, forcing re-authentication on all devices and applications. It does not immediately invalidate access tokens already issued, those remain valid until their expiry (typically 1 hour). Change the user's password and require MFA re-registration in parallel.

How do I tune the Sentinel KQL queries in this guide to reduce false positives from legitimate users who frequently travel or work across multiple devices?

Build a named entity table of high-travel users (executives, sales, field engineers) and join it into each query as an exclusion or a separate lower-severity alert tier. For device-count anomalies in the PRT detection query, calculate a per-user historical device count baseline from the prior 90 days and alert only when the current count exceeds that user's own baseline by more than one device -- this avoids flagging a developer who legitimately uses four machines. For impossible travel detection, add a speed-of-travel threshold calculation: divide the geographic distance between consecutive sign-in locations by the elapsed time, and alert only when the implied travel speed exceeds 900 km/h (roughly impossible without a private jet). Store the baseline data as a Sentinel watchlist updated weekly by a scheduled Logic App that queries SigninLogs, so the baselines automatically adapt to behavioral changes without manual tuning.

Sources & references

  1. Microsoft Sentinel Entra ID detection queries
  2. Microsoft identity attack documentation
  3. Token theft playbook, Microsoft

Free resources

25
Free download

Critical CVE Reference Card 2025–2026

25 actively exploited vulnerabilities with CVSS scores, exploit status, and patch availability. Print it, pin it, share it with your SOC team.

No spam. Unsubscribe anytime.

Free download

Ransomware Incident Response Playbook

Step-by-step 24-hour IR checklist covering detection, containment, eradication, and recovery. Built for SOC teams, IR leads, and CISOs.

No spam. Unsubscribe anytime.

Free newsletter

Get threat intel before your inbox does.

50,000+ security professionals read Decryption Digest for early warnings on zero-days, ransomware, and nation-state campaigns. Free, daily, no spam.

Unsubscribe anytime. We never sell your data.

Eric Bang
Author

Founder & Cybersecurity Evangelist, Decryption Digest

Cybersecurity professional with expertise in threat intelligence, vulnerability research, and enterprise security. Covers zero-days, ransomware, and nation-state operations for 50,000+ security professionals every morning.

Black Hat Giveaway

Win a $2,495 Black Hat pass.

Full-access to Black Hat USA 2026 in Las Vegas. Subscribe free to enter.

Joins Decryption Digest daily briefing. Unsubscribe anytime.

Giveaway: Black Hat USA 2026 Full-Access Pass ($2,495 value)

Details →
Daily Briefing

Subscribe to enter the giveaway

Every subscriber is automatically entered. You also get daily threat intel every morning: zero-days, ransomware, and nation-state campaigns. Free. No spam.

Already subscribed? You're already entered.

Giveaway

Win a $2,495 Black Hat USA 2026 pass.