In this section
Token Replay Detection Beyond AiTM
DE4-003 caught a stolen session because the attacker reused it from another country. But geography is a weak hook — an attacker who replays a token from the same country, or through the user's own VPN, produces no impossible journey at all. This section detects the theft by what the token itself reveals, not where it is used, so the detection holds when the geographic signal disappears.
Scenario
The same c.richardson sign-in from the previous section carries a detail impossible travel never looked at. In the authentication record, the MFA step did not happen — Entra recorded it as "satisfied by a claim in the token." No push, no code, no prompt: the attacker presented a session that already carried a valid MFA claim, captured by the AiTM proxy. Now imagine that replay came not from Singapore but from a London IP inside NE's own range. Impossible travel sees nothing. The stolen session is identical; only the geography changed. This section detects the theft by the token's own fingerprint, so it fires either way.
DE3-004 detects AiTM token theft through the IP-and-device mismatch between interactive and non-interactive sign-ins. But AiTM is only one way to steal a token. Pass-the-cookie attacks lift session cookies from browser storage on a compromised endpoint. Primary Refresh Token (PRT) theft pulls the device-bound token from a Windows machine. Malware exfiltrates tokens from cache files. All of them end the same way — a valid token replayed from somewhere it was never issued — and none of them necessarily crosses a border. DE4-004 detects the replay by the property every one of these vectors shares: a session whose MFA was satisfied by a claim already inside it, presented from a device the tenant does not manage.
Beyond AiTM: the token theft vectors
Figure DE4.5. Every token-theft vector ends in the same replay fingerprint — MFA satisfied by a claim in the token, from an unmanaged device. DE4-004 keys on that; device-class mismatch is the complementary signal for same-IP replays.
The three vectors differ in where they steal the token, and the differences shape the response even though the replay fingerprint is shared. An AiTM proxy sits inside the live authentication flow and captures the session as it is issued — the user really did authenticate, through the attacker's relay, so the stolen session is fully formed, MFA claim included. Pass-the-cookie skips authentication entirely: malware on the endpoint reads the browser's session cookies from disk or memory and replays them, so there was no fresh sign-in to catch at theft time, only the later replay. PRT theft is the most dangerous of the three, because the Primary Refresh Token is the device-bound master key Windows uses to silently obtain tokens for every cloud app the user can reach — steal it and the attacker mints sessions across the whole tenant surface. What unites them is the endpoint: pass-the-cookie and PRT theft both require code execution on the user's machine, which is why this rule correlates so tightly with the LSASS dump in DE4.10 — the dump is frequently where the token material was taken in the first place.
The evidence: a replayed token
This is c.richardson's AiTM sign-in from SigninLogs, with the authentication detail expanded — the field impossible travel never read:
{
"TimeGenerated": "2026-02-27T06:47:00Z",
"UserPrincipalName": "c.richardson@ne.com",
"IPAddress": "185.234.72.18",
"AppDisplayName": "Exchange Online",
"DeviceDetail": "{\"deviceId\":\"\",\"isManaged\":false,\"isCompliant\":false}",
"AuthenticationDetails": "[{\"authenticationMethod\":\"SatisfiedByClaimInToken\",
\"authenticationMethodDetail\":\"MFA requirement satisfied by claim in the token\",
\"succeeded\":true}]",
"RiskLevelDuringSignIn": "high"
}
The tell is authenticationMethod: "SatisfiedByClaimInToken". In a normal sign-in the user satisfies MFA with a live factor — a push, a code, a key. Here Entra recorded no live factor at all: the presented session already carried a valid MFA claim, so the requirement was waved through. A legitimate session can satisfy MFA from a token too, on a device the tenant issued the token to — but this claim arrives from a device with isManaged: false, one Entra has no record of provisioning. A valid MFA claim on an unmanaged device is the signature of a token lifted from somewhere else and replayed.
Building DE4-004
The rule looks for the token-claim authentication from an unmanaged device. Note that it never references the IP or country — that independence from geography is the entire point:
// DE4-004: token replay. Hypothesis: a session whose MFA was satisfied by a claim
// already in the token, presented from an unmanaged device, is a replayed/stolen
// session — true regardless of where it is replayed from, so geography is not used.
SigninLogs
| where TimeGenerated > ago(7d)
| where ResultType == 0
| extend authMethod = tostring(parse_json(AuthenticationDetails)[0].authenticationMethod)
| where authMethod =~ "SatisfiedByClaimInToken"
| extend IsManaged = tobool(parse_json(DeviceDetail).isManaged)
| where IsManaged == false // a token claim from an unmanaged device is the replay signal
| project TimeGenerated, UserPrincipalName, IPAddress, City, Country,
AppDisplayName, authMethod, IsManaged, RiskLevelDuringSignIn
Against the corpus it returns the replayed session and nothing else:
TimeGenerated UserPrincipalName IPAddress City Country AppDisplayName authMethod IsManaged RiskLevelDuringSignIn
─────────────────── ─────────────────── ───────────── ───────── ─────── ─────────────── ─────────────────────── ───────── ─────────────────────
2026-02-27 06:47:00 c.richardson@ne.com 185.234.72.18 Singapore SG Exchange Online SatisfiedByClaimInToken false high
The same sign-in DE4-003 flagged, caught here on a completely different signal — and that redundancy is a feature, not waste. If c.richardson's attacker had replayed the token from a London IP, DE4-003 would have stayed silent and DE4-004 would have fired alone. Two rules, two independent hooks into one stolen session, so losing one does not lose the detection.
Why this rule earns a session-revocation response rather than a password reset is worth stating plainly, because it is the most common mistake teams make with token theft. A stolen token is valid material in its own right — it does not contain the password and is not invalidated by changing one. Access tokens live for roughly an hour, but the refresh token behind them can mint new access tokens for far longer, so an attacker holding a refresh token keeps working straight through a password change until the session itself is revoked. Revoking the user's sessions and refresh tokens is what actually severs the attacker's access; a password reset only closes a fresh login they were never relying on. Continuous Access Evaluation shortens the exposure by re-checking token validity on each resource access, but where CAE is not enforced — and it is not, universally — manual revocation is the only action that genuinely ends a replayed session. Build that into the playbook for this rule, because the instinct to "just reset the password" leaves the attacker fully active.
The 12-section specification
Write your hypothesis first: what makes a token-satisfied sign-in an attack rather than a normal cached session? The answer is the device, not the token — and the specification turns on that.
1. Rule name and ID: DE4-004-Token-Replay-Claim-Unmanaged. The name states the signal — token claim from an unmanaged device — so an analyst knows this is the geography-independent token rule, distinct from impossible travel.
2. Hypothesis: "A successful sign-in whose MFA was satisfied by a claim already in the token, from a device the tenant does not manage, indicates a replayed stolen session. The token-claim-plus-unmanaged-device pairing distinguishes theft from legitimate cached sessions, which present token claims only from enrolled devices."
3. MITRE ATT&CK: T1550.001 (Use Alternate Authentication Material: Application Access Token). The attacker authenticates with stolen material rather than credentials, which is why neither a password reset nor MFA alone closes the hole.
4. Data sources: SigninLogs (Entra ID P1). The signal lives in AuthenticationDetails and DeviceDetail, both standard fields — no premium licensing beyond P1.
5. KQL query: the annotated query above, as a scheduled analytics rule.
6. Entity mapping: Account → UserPrincipalName, IP → IPAddress. Account is what links this rule to DE3-004 (AiTM) and DE4-003 (impossible travel) when they fire on the same session.
7. Frequency and lookback: every 1 hour, 2-hour lookback. Token replays cluster, so the overlap catches sequences that span a boundary.
8. Severity and confidence: High. The token-claim-from-unmanaged-device pairing is specific enough that the false-positive rate is low, and a confirmed replay means an active session in attacker hands.
9. Trigger and grouping: results > 0, grouped by Account. Repeated replays of one stolen session collapse into one incident.
12. Tuning plan: Week 1 audit to confirm the FP rate. Add the BYOD allowlist if the estate needs it. Month 1, add the device-class-mismatch variant below as a second analytics rule so same-IP, different-OS replays are covered. The two rules together close the IP and OS blind spots.
Anti-Pattern
Treating impossible travel as your token-theft detection. It is the trap this whole section exists to close: impossible travel only fires when the attacker replays from a different country, so an adversary who replays a stolen token from the user's own city — or through the corporate VPN, or from a compromised host on the same network — produces no geographic anomaly and sails straight past it. Worse, teams that have a noisy impossible-travel rule often believe they have token-theft covered and never build a token-specific detection at all. Geography is a weak, evadable hook. The token's own authentication fingerprint — satisfied by a claim, from an unmanaged device — is the signal that holds when the attacker is standing next door.
The complementary vector: device-class mismatch
The token-claim rule catches replays from unmanaged devices, but a careful attacker may replay from a device that registers as managed-looking, or the token-claim field may be absent for some theft vectors. The complementary detection compares the operating-system family of the replay against the user's baseline. A Primary Refresh Token issued to a Windows 11 laptop, then replayed from a Linux host running an attack tool, shows OS = "Linux" against a baseline of Windows — a device-class mismatch. This matters because PRT theft is specifically dangerous: the token carries the device-compliance claim from the original compliant device, so a Conditional Access policy that checks the claim in the token rather than re-evaluating the current device lets the attacker's non-compliant machine through. Continuous Access Evaluation re-checks claims on each resource access and mitigates this, but CAE is not universally enforced and not every application supports it. The device-class rule catches the replay regardless of CA configuration, which is why it runs alongside the token-claim rule rather than instead of it.
Building the OS baseline is the work that makes this variant reliable. For each user, you summarise the operating-system families seen across roughly 30 days of sign-ins; most NE users show a single family — Windows — because the estate is managed and homogeneous. A sign-in from outside that baseline is the anomaly. The cross-OS user is the false-positive risk: a developer who legitimately works from both Windows and a Mac trips a naive rule, so the baseline must be built per user, not globally. At NE this is nearly free, because the estate is Windows-only and any non-Windows sign-in is suspect on its face. In a BYOD environment with mixed macOS and Windows, the rule needs that per-user baseline plus an allowlist of users known to work cross-platform — otherwise it becomes exactly the kind of noisy detection the SOC learns to mute, and a muted token-theft rule is the worst of both worlds.
When DE4-004 and DE3-004 both fire on one account at one time, that is two independent detections — IP-and-timing mismatch from DE3-004, token-claim-and-device from DE4-004 — confirming the same theft. Treat the dual fire as high-confidence and prioritise it: two unrelated detection methods agreeing on one user is almost never a false positive.
Troubleshooting
"parse_json(AuthenticationDetails)[0] returns empty." AuthenticationDetails is a JSON array; some sign-ins record multiple steps. Index [0] reads the first step, which is where the token-claim method appears for a replay. If a tenant records the claim in a later step, use mv-expand over the array and filter rather than hardcoding [0].
"The rule misses a replay I know happened." Check whether the replay device registered as managed. If isManaged was true, the token-claim rule will not fire by design — that is the case the device-class-mismatch variant exists to catch. No single signal covers every vector; the two together cover the IP, OS, and device-management blind spots.