Hunts for stolen-session and OAuth/PRT token replay (T1550.001) by correlating Microsoft Entra ID SigninLogs SessionId/UniqueTokenIdentifier fields and Okta System Log sso/session events to spot impossible travel, refresh-token reuse, and token use from anomalous ASNs. Use when hunting MFA-bypass via stolen cookies/tokens, investigating impossible-travel alerts, or scoping SaaS lateral movement after phishing.
Installer avec Codex ou Claude Copiez ce prompt, collez-le dans Codex, Claude ou un autre assistant, puis laissez-le vérifier la page du skill et l'installer pour vous.
Une commande directe contourne le prompt de vérification. Examinez la source avant de l'exécuter.
Hunts for stolen-session and OAuth/PRT token replay (T1550.001) by correlating Microsoft Entra ID SigninLogs SessionId/UniqueTokenIdentifier fields and Okta System Log sso/session events to spot impossible travel, refresh-token reuse, and token use from anomalous ASNs. Use when hunting MFA-bypass via stolen cookies/tokens, investigating impossible-travel alerts, or scoping SaaS lateral movement after phishing.
Adversaries increasingly bypass MFA not by defeating it but by stealing the artifacts issued after a successful authentication — session cookies, OAuth access/refresh tokens, and Primary Refresh Tokens (PRTs). With a stolen token an attacker replays the existing session ("pass-the-cookie" / token replay), inheriting the victim's authenticated state across federated SaaS without ever prompting for credentials or MFA. Mandiant's M-Trends reporting and Microsoft/Okta incident data both highlight token theft as a dominant cloud lateral-movement technique, mapped to MITRE ATT&CK T1550.001 Use Alternate Authentication Material: Application Access Token.
Detection relies on correlating identity telemetry rather than watching for failed logins. In Microsoft Entra ID the key tables are SigninLogs (interactive), AADNonInteractiveUserSignInLogs (where replayed cookies/refresh tokens commonly surface), and AADServicePrincipalSignInLogs. Entra now exposes linkable identifiers — SessionId and UniqueTokenIdentifier — that let a hunter stitch every artifact derived from one root authentication event together and spot a single session being used from multiple IPs, ASNs, or device fingerprints. In Okta the System Log carries authentication.sso, policy.evaluate_sign_on, and user.session.start events with a deviceToken/session context; the same session token appearing from divergent IPs/user-agents is the tell. Okta Identity Threat Protection (ITP) can natively flag "suspected session hijacking."
This skill provides a hypothesis-driven hunt: baseline normal session behavior, then look for impossible travel within a single session, refresh-token reuse, token use from anomalous infrastructure (hosting/VPS ASNs), and SaaS access patterns inconsistent with the user's device. Source: MITRE ATT&CK T1550.001; Microsoft Entra ID sign-in log documentation; Okta System Log reference; Mandiant M-Trends.
When to Use
Threat hunting for MFA-bypass via stolen tokens/cookies across Entra ID and SaaS
Investigating an alert for impossible travel, anomalous OAuth grant, or token reuse
Validating detection coverage for T1550.001 after a phishing/AiTM incident
Building Sentinel/Splunk/Okta detections for session-token replay
Post-incident hunting to scope SaaS lateral movement from a compromised identity
Prerequisites
Entra ID sign-in logs flowing to a queryable store (Microsoft Sentinel / Log Analytics):
az monitor diagnostic-settings list --resource \
/providers/Microsoft.aadiam/diagnosticSettings -o table
# Confirm the diagnostic settings export SigninLogs + non-interactive logs to a workspace
Stitch interactive, non-interactive, and SP sign-ins for one session to see the full chain.
union SigninLogs, AADNonInteractiveUserSignInLogs
| where TimeGenerated > ago(7d)
| where isnotempty(SessionId)
| summarize IPs=make_set(IPAddress), Apps=make_set(AppDisplayName),
Locations=make_set(tostring(LocationDetails.countryOrRegion)),
Count=count() by SessionId, UserPrincipalName
| where array_length(IPs) > 1
2. Detect a single session used from multiple ASNs (token replay)
AADNonInteractiveUserSignInLogs
| where TimeGenerated > ago(24h)
| extend ASN = tostring(parse_json(tostring(NetworkLocationDetails))[0].networkType)
| summarize distinctIPs = dcount(IPAddress),
ipset = make_set(IPAddress) by SessionId, UserPrincipalName
| where distinctIPs >= 2
3. Detect impossible travel within one authenticated session
SigninLogs
| where TimeGenerated > ago(7d)
| project TimeGenerated, UserPrincipalName, IPAddress,
City=tostring(LocationDetails.city),
Country=tostring(LocationDetails.countryOrRegion), SessionId
| order by UserPrincipalName, TimeGenerated asc
| serialize
| extend prevCountry = prev(Country), prevTime = prev(TimeGenerated),
prevUser = prev(UserPrincipalName)
| where UserPrincipalName == prevUser and Country != prevCountry
and datetime_diff('minute', TimeGenerated, prevTime) < 60
4. Detect token use from hosting/VPS infrastructure
Replayed tokens are frequently used from datacenter ASNs, unlike the user's residential/corporate ranges.
AADNonInteractiveUserSignInLogs
| where TimeGenerated > ago(24h)
| where ResultType == 0
| extend asnOrg = tostring(parse_json(tostring(AutonomousSystemNumber)))
| where IPAddress in (toscalar(externaldata(ip:string)["<hosting-asn-iplist>"]))
| project TimeGenerated, UserPrincipalName, AppDisplayName, IPAddress
index=okta eventType="policy.evaluate_sign_on"
| stats dc(client.ipAddress) as ip_count
values(client.ipAddress) as ips
values(client.userAgent.rawUserAgent) as agents
by authenticationContext.externalSessionId actor.alternateId
| where ip_count > 1
8. Triage and respond
For confirmed token abuse, revoke sessions and rotate, then promote the hunt to a rule.
# Revoke all refresh tokens / sessions for the user in Entra
az rest --method POST \
--url "https://graph.microsoft.com/v1.0/users/<userId>/revokeSignInSessions"
See scripts/agent.py to pull Okta logs and flag reused session tokens automatically.