SOP-96: Primary Refresh Token (PRT) Theft & Token Replay Response | CyberHawk Threat Intel

·

A Primary Refresh Token (PRT) is the master SSO credential Entra ID issues to a joined or registered Windows device. It bundles the user's identity, the device identity, and — critically — the MFA claim, so once a device holds a valid PRT, the user rides single sign-on into Microsoft 365, Azure, and every federated app without re-authenticating. If an attacker steals that PRT (or the derived session keys) from a compromised endpoint, they can replay it from their own machine and inherit the victim's fully-authenticated, MFA-satisfied session — Pass-the-PRT. Password resets and even blocking sign-in do not, on their own, kill an already-issued PRT or the access tokens minted from it.

This SOP treats a confirmed PRT/CloudAP credential extraction or a Pass-the-PRT replay as a SEV1 identity compromise. The response is two-front: contain the endpoint that leaked the token and contain the identity by revoking every refresh token and rotating the device. Key data sources: DeviceProcessEvents / DeviceEvents (CloudAP/LSASS access, BrowserCore abuse, forge tooling), SigninLogs & AADNonInteractiveUserSignInLogs (trusted-device token replay, deviceDetail vs Location mismatch, AuthenticationProtocol), and AADUserRiskEvents (anomalousToken, tokenIssuerAnomaly, unfamiliarFeatures).

☰ Table of Contents

01 Background 02 Identification 03 Containment 04 Eradication 05 Escalation
🛠

01 — BACKGROUND

TECHNIQUE OVERVIEW
01
Technique Overview — PRT Theft & Pass-the-PRT
MITRE T1550.001

The PRT is issued to Entra-joined, hybrid-joined, and Entra-registered Windows 10/11 devices and is held by the CloudAP (Cloud Authentication Provider) plug-in inside the LSASS process. It is protected by two device-bound keys — a device key (dkey) and a session transport key (tkey) — which live in the TPM where one is present. An attacker with local SYSTEM/admin on the endpoint has several paths to abuse it: extract the PRT and its keys directly from LSASS/CloudAP, or ask the local BrowserCore.exe broker to mint a fresh PRT cookie (x-ms-RefreshTokenCredential) they can then replay from anywhere. Because the PRT carries the MFA claim, the replayed session is treated as already strong-authenticated.

FieldValue
MITRE TechniqueT1550.001 — Use Alternate Authentication Material: Application Access Token (Pass-the-PRT)
T1528 — Steal Application Access Token
T1003 — OS Credential Dumping (CloudAP/LSASS extraction)
Kill-chain PhaseCredential Access → Lateral Movement → Defense Evasion (MFA bypass)
Primary Log SourceDeviceProcessEvents, DeviceEvents (LSASS access), SigninLogs, AADNonInteractiveUserSignInLogs, AADUserRiskEvents
Secondary Log SourcesCloudAppEvents (post-replay app activity), AuditLogs (device / method registration follow-on), IdentityInfo (device-user binding)
Common ToolingMimikatz (sekurlsa::cloudap, dpapi::cloudapkd), ROADtoken, AADInternals (Get-AADIntUserPRTToken), requestaadrefreshtoken via BrowserCore.exe, Pass-the-PRT in a controlled browser
Default SeveritySEV1 — token theft grants MFA-satisfied SSO to all federated apps
Detection WindowEndpoint queries last 24h; sign-in replay hunting last 7–14 days (refresh tokens are long-lived)

A stolen PRT is not killed by a password reset. It must be neutralised by revoking the user's refresh tokens (revokeSignInSessions) AND disabling/re-registering the leaking device so its device key can no longer sign PRT requests. Reset-only responses leave the attacker's session live.

02
Attack Paths, Log Sources & Severity Model
CONTEXT

Five concrete scenarios drive this playbook. The first three are the dominant real-world paths; the last two anchor the false-positive edges an analyst must rule out before escalating.

#Attack PathWhat the SOC sees
A1CloudAP / LSASS extraction — Mimikatz sekurlsa::cloudap or dpapi::cloudapkd pulls the PRT + derived keys from LSASS after local admin/SYSTEM is obtainedDeviceProcessEvents cred-tool command lines; DeviceEvents LSASS handle-open from an unusual process
A2PRT-cookie minting — attacker drives BrowserCore.exe (ROADtoken / requestaadrefreshtoken) to issue a fresh x-ms-RefreshTokenCredential without touching LSASS memoryBrowserCore.exe spawned by a non-browser parent (cmd/powershell/rundll32) with a nonce argument
A3Pass-the-PRT replay — stolen PRT/cookie injected into the attacker's browser; sign-in appears from the victim's device identity but a new IP / ASN / geoSigninLogs: compliant/managed device + impossible travel; MFA shows "previously satisfied" via token
A4Token anomaly detection — Entra flags anomalousToken / tokenIssuerAnomaly when a token's characteristics (lifetime, device binding) don't match the sign-in contextAADUserRiskEvents risk detection; often the first and only signal when the endpoint is unmanaged
A5Benign SSO / red-team (FP edge) — legitimate roaming, VPN egress change, or an authorised identity-attack simulation replaying test tokensTrusted device + new IP but a matching change/engagement record, known tester account, corporate ASN

Severity model. Grade by evidence of key/token theft and blast radius:

SignalSeverity
CloudAP/LSASS extraction tool confirmed on endpoint, or Pass-the-PRT replay to a privileged accountSEV1 / CRITICAL
BrowserCore/ROADtoken PRT-cookie mint, or trusted-device sign-in from anomalous IP with anomalousToken riskSEV1
Single Entra token-risk detection, endpoint telemetry inconclusive, no confirmed replay yetSEV2
Trusted device + new IP fully explained by documented roaming/VPN/red-teamFP

PRT theft is the "why did MFA not fire?" answer to an impossible-travel alert on a managed device. If a Conditional Access impossible-travel or unfamiliar-location sign-in shows the session as already MFA-satisfied from a compliant device, suspect a replayed PRT before you write it off as a VPN quirk.

🔍

02 — IDENTIFICATION

6 INDICATORS + TRIAGE
▶ Investigation Workflow
T0
Alert Triage Checklist
TRIAGE
WHY CHECK

Five yes/no questions decide whether this jumps the queue. Any single YES on Q1–Q3 makes it live-incident SEV1 — a stolen PRT is actively usable and every minute of dwell buys the attacker more federated-app reach.

  • 1Is there LSASS/CloudAP access or a credential-dump tool on the endpoint? (I1) — YES = confirmed key theft attempt, isolate now.
  • 2Did BrowserCore.exe spawn from a non-browser parent with a nonce? (I2) — YES = PRT-cookie minting, isolate now.
  • 3Is there a sign-in from a trusted/compliant device but a new IP/ASN/country? (I3) — YES = probable Pass-the-PRT replay.
  • 4Is the affected account privileged (Global Admin, PIM-eligible, or with app-secret access)? — YES = raise one severity tier regardless of other answers.
  • 5Is there a matching change ticket, travel notice, or authorised red-team engagement? (A5) — a documented YES points toward FP; an unverified "probably" does not.

Do not downgrade on "the device is compliant." Compliant/managed device is exactly what a replayed PRT looks like — the device identity is the victim's; only the network origin and behaviour betray the attacker.

I1
CloudAP / LSASS Extraction of the PRT & Keys
MANUAL + KQL
WHY CHECK

The most direct theft path: with SYSTEM/admin, an attacker reads the PRT and its derived session keys straight out of the CloudAP plug-in inside LSASS. Any non-security process opening a handle to lsass.exe, or a Mimikatz cloudap/dpapi::cloudapkd command line, is a confirmed key-theft attempt.

📍 Portal Navigation — Microsoft Defender XDR
security.microsoft.com› Hunting› Advanced Hunting
  • 1Open Hunting → Advanced Hunting and paste the KQL below. Set Time range to Last 24 hours.
  • 2For each hit, open the Device Timeline from the DeviceName link and confirm the initiating process and the account that ran it.
  • 3Note the DeviceName, AccountName, and timestamp — this is the leaking endpoint and the compromised identity for Containment.
  • 4Pivot to Incidents & alerts and check for a co-incident "Possible credential theft from LSASS" or Mimikatz detection.
IndicatorMeaningSeverity
sekurlsa::cloudapMimikatz dumps the CloudAP cached PRT + session key from LSASSCRITICAL
dpapi::cloudapkdDerives the CloudAP key to decrypt the protected PRT materialCRITICAL
token::elevate / privilege::debugSeDebugPrivilege acquired to read LSASS memoryHIGH
LSASS handle-open (0x1010/0x1410) from non-security procRead/query access to lsass.exe by an unexpected processCRITICAL
DETECTS: Mimikatz CloudAP/DPAPI command lines and abnormal LSASS handle-opens indicating PRT/session-key extraction from the CloudAP plug-in.
KQL — Microsoft Sentinel / Defender XDR Advanced Hunting
// CloudAP / DPAPI credential-tool command lines targeting the PRT DeviceProcessEvents | where Timestamp > ago(24h) | where ProcessCommandLine has_any ( "sekurlsa::cloudap","dpapi::cloudapkd","cloudap","::logonpasswords", "sekurlsa::dpapi","token::elevate","privilege::debug") | project Timestamp, DeviceName, AccountName, FileName, ProcessCommandLine, InitiatingProcessFileName, InitiatingProcessCommandLine, InitiatingProcessParentFileName | order by Timestamp desc
DETECTS: Abnormal read/query handle-opens against lsass.exe by non-security processes — the memory access underpinning CloudAP PRT extraction.
KQL — LSASS Access (CloudAP memory read)
// Non-security processes opening lsass.exe for read/query DeviceEvents | where Timestamp > ago(24h) | where ActionType == "OpenProcessApiCall" | where FileName =~ "lsass.exe" | where InitiatingProcessFileName !in~ ( "MsMpEng.exe","MsSense.exe","SenseIR.exe","csrss.exe","wininit.exe","services.exe") | project Timestamp, DeviceName, InitiatingProcessAccountName, InitiatingProcessFileName, InitiatingProcessCommandLine, InitiatingProcessParentFileName | order by Timestamp desc
SPL — Splunk
index=mde (sourcetype=DeviceProcessEvents OR sourcetype=DeviceEvents) | eval susp=case( like(ProcessCommandLine,"%cloudap%"),"cloudap-tool", like(ProcessCommandLine,"%dpapi::cloudapkd%"),"cloudapkd", (ActionType="OpenProcessApiCall" AND FileName="lsass.exe" AND NOT match(InitiatingProcessFileName,"(?i)^(MsMpEng|MsSense|SenseIR|csrss|wininit|services)\.exe$")),"lsass-access") | where isnotnull(susp) | table _time DeviceName InitiatingProcessAccountName FileName ProcessCommandLine InitiatingProcessFileName InitiatingProcessParentFileName susp | sort -_time

On TPM-backed devices the raw keys cannot be exported off-box, so attackers pivot to I2 (BrowserCore cookie minting) instead — they mint tokens while on the machine. Absence of an LSASS hit does not clear the host; check I2 next.

I2
BrowserCore / ROADtoken PRT-Cookie Minting
MANUAL + KQL
WHY CHECK

BrowserCore.exe is the legitimate local broker that hands the browser a signed PRT cookie (x-ms-RefreshTokenCredential). Tools such as ROADtoken and requestaadrefreshtoken drive it directly to mint a fresh cookie the attacker can replay — no LSASS memory read required, so it evades TPM protection. A BrowserCore.exe launched by cmd/powershell/rundll32 rather than the browser is the tell.

📍 Portal Navigation — Microsoft Defender XDR
security.microsoft.com› Hunting› Advanced Hunting
  • 1Run the KQL below and inspect InitiatingProcessFileName — a browser parent (msedge/chrome) is normal; a shell or unknown parent is suspicious.
  • 2Check the command line for a nonce argument or piped JSON request — ROADtoken/requestaadrefreshtoken pass a server nonce to sign the cookie.
  • 3Correlate the timestamp with any I3 sign-in from a new IP within minutes — a mint immediately followed by an off-host replay is a confirmed chain.
  • 4Hunt for the tool binaries themselves (ROADtoken.exe, roadtx, AADInternals import) in the same session.
IndicatorMeaningSeverity
BrowserCore.exe (non-browser parent)Broker driven by a shell/tool to mint a PRT cookieCRITICAL
x-ms-RefreshTokenCredentialThe PRT cookie header value being requested/replayedCRITICAL
ROADtoken / roadtx / requestaadrefreshtokenKnown PRT-cookie minting toolingCRITICAL
Get-AADIntUserPRTTokenAADInternals cmdlet that returns a usable PRT tokenCRITICAL
DETECTS: BrowserCore.exe launched by a non-browser parent and known PRT-cookie tooling — the memory-safe path to mint a replayable PRT cookie.
KQL — BrowserCore abuse & PRT tooling
// PRT-cookie minting via BrowserCore or known tooling DeviceProcessEvents | where Timestamp > ago(24h) | where (FileName =~ "BrowserCore.exe" and InitiatingProcessFileName !in~ ("msedge.exe","chrome.exe","msedgewebview2.exe","explorer.exe")) or ProcessCommandLine has_any ( "requestaadrefreshtoken","x-ms-RefreshTokenCredential","ROADtoken", "roadtx","Get-AADIntUserPRTToken","AADInternals") | project Timestamp, DeviceName, AccountName, FileName, ProcessCommandLine, InitiatingProcessFileName, InitiatingProcessCommandLine | order by Timestamp desc
SPL — Splunk
index=mde sourcetype=DeviceProcessEvents | where (FileName="BrowserCore.exe" AND NOT match(InitiatingProcessFileName,"(?i)^(msedge|chrome|msedgewebview2|explorer)\.exe$")) OR like(ProcessCommandLine,"%requestaadrefreshtoken%") OR like(ProcessCommandLine,"%x-ms-RefreshTokenCredential%") OR like(ProcessCommandLine,"%ROADtoken%") OR like(ProcessCommandLine,"%roadtx%") OR like(ProcessCommandLine,"%Get-AADIntUserPRTToken%") OR like(ProcessCommandLine,"%AADInternals%") | table _time DeviceName AccountName FileName ProcessCommandLine InitiatingProcessFileName | sort -_time
I3
Pass-the-PRT Token Replay — Trusted Device, New Origin
MANUAL + KQL
WHY CHECK

This is the payoff signal. When the stolen PRT is replayed, the sign-in carries the victim's device identity (managed / Entra-joined / compliant) but originates from the attacker's IP, ASN and geo. Because the MFA claim rides inside the PRT, the sign-in shows strong auth as already satisfied — an impossible-travel event with no MFA prompt on a "trusted" device is the classic Pass-the-PRT footprint.

📍 Portal Navigation — Microsoft Sentinel / Entra
portal.azure.com› Microsoft Entra ID› Users› [UPN]› Sign-in logs
  • 1Open the user's Sign-in logs and add columns for Device / Managed, Location, IP address, and Authentication requirement.
  • 2Look for the same DeviceId / DeviceName appearing from two irreconcilable locations inside a short window, with MFA shown as previously satisfied.
  • 3Run the KQL below in Sentinel to auto-surface trusted-device sign-ins from a new IP/country against the device's baseline.
  • 4Record the attacker IP, ASN, user agent, and the DeviceDetail.deviceId — these feed the IOC list (I6) and Containment blocks.
Field / ValueMeaningAnalyst Action
DeviceDetail.trustType = "Azure AD joined"Sign-in claims a managed device identityVerify origin matches that device's baseline
AuthenticationRequirement = singleFactor (MFA satisfied via token)No interactive MFA — claim carried by the PRTOn a new IP = suspect replay
ResultType 0 + new ASN/CountrySuccessful sign-in from an unfamiliar networkCorrelate with device baseline & I4 risk
Impossible travel / atypical location riskTwo locations too far apart in timeOn a compliant device = strong replay signal
DETECTS: A single device identity signing in from a new IP/country versus its own recent baseline — the network-origin mismatch that exposes a replayed PRT on a managed device.
KQL — Trusted-device sign-in from anomalous origin
// Same DeviceId, new IP/country vs its 14-day baseline let lookback = 14d; let baseline = SigninLogs | where TimeGenerated between (ago(lookback) .. ago(1h)) | extend DeviceId = tostring(DeviceDetail.deviceId) | where isnotempty(DeviceId) | summarize KnownIPs = make_set(IPAddress), KnownCountries = make_set(Location) by DeviceId; SigninLogs | where TimeGenerated > ago(1h) | extend DeviceId = tostring(DeviceDetail.deviceId), TrustType = tostring(DeviceDetail.trustType) | where isnotempty(DeviceId) and ResultType == 0 | where TrustType in ("Azure AD joined","Hybrid Azure AD joined","Azure AD registered") | join kind=inner baseline on DeviceId | where IPAddress !in (KnownIPs) and Location !in (KnownCountries) | project TimeGenerated, UserPrincipalName, DeviceId, TrustType, IPAddress, Location, AuthenticationRequirement, AppDisplayName, UserAgent = tostring(DeviceDetail.browser) | order by TimeGenerated desc
SPL — Splunk
index=azure sourcetype="azure:aad:signin" resultType=0 | eval DeviceId=coalesce('deviceDetail.deviceId',DeviceId), TrustType='deviceDetail.trustType' | where isnotnull(DeviceId) AND DeviceId!="" | search TrustType IN ("Azure AD joined","Hybrid Azure AD joined","Azure AD registered") | eventstats values(ipAddress) as knownIPs values(location.countryOrRegion) as knownCountries by DeviceId earliest=-14d@d latest=-1h | where NOT (ipAddress IN (knownIPs)) AND NOT ('location.countryOrRegion' IN (knownCountries)) | table _time userPrincipalName DeviceId TrustType ipAddress location.countryOrRegion authenticationRequirement appDisplayName | sort -_time

The device identity being "yours" is not exculpatory — it is the whole point of Pass-the-PRT. Correlate on network origin and behaviour (I4/I5), never on device trust alone.

I4
Entra Risk Detections — anomalousToken / tokenIssuerAnomaly
MANUAL + KQL
WHY CHECK

Entra ID Protection scores token characteristics and flags anomalousToken when a token's lifetime or replay pattern is unusual, and tokenIssuerAnomaly when issuer claims don't match. When the leaking endpoint is unmanaged (no MDE telemetry), these risk detections are frequently the only signal a replay happened — treat them as first-class evidence, not background noise.

📍 Portal Navigation — Entra ID Protection
entra.microsoft.com› Protection› Identity Protection› Risk detections
  • 1Open Risk detections and filter Detection type to Anomalous Token and Token Issuer Anomaly.
  • 2For the flagged user, open Risky users → [user] → Recent risk detections and note the linked sign-in and correlationId.
  • 3Pivot each detection to its sign-in and cross-check against I3 (new IP/device mismatch) and I5 (non-interactive replay).
  • 4Run the KQL below to join risk events to their sign-ins in Sentinel for a full picture.
RiskEventTypeMeaningAnalyst Action
anomalousTokenToken shows abnormal lifetime / replay characteristicsTreat as probable replay; confirm device binding
tokenIssuerAnomalyIssuer claims inconsistent with expected token issuerInvestigate for forged/replayed token
unfamiliarFeaturesSign-in properties deviate from user baselineCorrelate with I3 origin mismatch
unlikelyTravelImpossible-travel between two sign-insOn a compliant device = strong PRT-replay signal
DETECTS: Entra token-anomaly risk detections joined to their originating sign-ins — the primary evidence path when endpoint telemetry is absent.
KQL — Token risk detections + sign-in join
// Token-anomaly risk detections and their sign-ins AADUserRiskEvents | where TimeGenerated > ago(14d) | where RiskEventType in ("anomalousToken","tokenIssuerAnomaly","unfamiliarFeatures","unlikelyTravel") | project TimeGenerated, UserPrincipalName, RiskEventType, RiskLevel, RiskState, IpAddress, Location, CorrelationId | join kind=leftouter ( SigninLogs | project CorrelationId, AppDisplayName, DeviceId = tostring(DeviceDetail.deviceId), TrustType = tostring(DeviceDetail.trustType), SignInIP = IPAddress ) on CorrelationId | order by TimeGenerated desc
SPL — Splunk
index=azure sourcetype="azure:aad:riskdetection" riskEventType IN ("anomalousToken","tokenIssuerAnomaly","unfamiliarFeatures","unlikelyTravel") | join type=left correlationId [ search index=azure sourcetype="azure:aad:signin" | rename deviceDetail.deviceId as DeviceId deviceDetail.trustType as TrustType ipAddress as SignInIP | fields correlationId appDisplayName DeviceId TrustType SignInIP ] | table _time userPrincipalName riskEventType riskLevel ipAddress location appDisplayName DeviceId TrustType | sort -_time
I5
Non-Interactive Token Replay & Post-Access App Activity
MANUAL + KQL
WHY CHECK

Once a PRT yields access/refresh tokens, the attacker's follow-on calls to Graph, Exchange, and SharePoint are non-interactive — they never re-authenticate, so the activity lands in AADNonInteractiveUserSignInLogs and CloudAppEvents, not the interactive sign-in blade. A burst of non-interactive token use from a new ASN, or sudden mailbox/file access right after I3, confirms the session is being actively used.

📍 Portal Navigation — Entra Non-Interactive Sign-ins
entra.microsoft.com› Identity› Monitoring & health› Sign-in logs› Non-interactive user sign-ins
  • 1Switch the Sign-in logs tab to Non-interactive user sign-ins and filter to the affected UPN.
  • 2Look for token use from the attacker IP/ASN identified in I3, targeting Microsoft Graph, Office 365 Exchange Online, or SharePoint.
  • 3Pivot to CloudAppEvents to see the actual actions taken (mail read, file download, inbox-rule creation) from that session.
  • 4Any inbox-rule or OAuth-grant follow-on means the compromise is expanding — cross-reference SOP-85 (mailbox rules) and SOP-21 (OAuth consent).
DETECTS: Non-interactive token replay from the attacker origin against Graph/Exchange/SharePoint — proof the stolen session is being actively used post-theft.
KQL — Non-interactive replay from attacker origin
// Non-interactive token use from a new IP against high-value resources AADNonInteractiveUserSignInLogs | where TimeGenerated > ago(7d) | where ResultType == 0 | where AppDisplayName has_any ("Microsoft Graph","Office 365 Exchange Online","SharePoint","Azure Portal") | extend DeviceId = tostring(DeviceDetail.deviceId) | summarize Count = count(), Apps = make_set(AppDisplayName), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated) by UserPrincipalName, IPAddress, Location, DeviceId | where Count > 0 | order by LastSeen desc
SPL — Splunk
index=azure sourcetype="azure:aad:signin:noninteractive" resultType=0 appDisplayName IN ("Microsoft Graph","Office 365 Exchange Online","SharePoint","Azure Portal") | rename deviceDetail.deviceId as DeviceId | stats count as Count values(appDisplayName) as Apps min(_time) as FirstSeen max(_time) as LastSeen by userPrincipalName ipAddress location DeviceId | sort -LastSeen

Refresh tokens minted from a PRT are long-lived (default ~90 days of sliding activity). Hunt back at least 7–14 days, not just the alert hour — the initial replay may predate the alert that finally tripped I4.

I6
IOC Extraction & FP / TP Decision Gate
VERDICT
WHY CHECK

Before Containment, consolidate the artifacts and make an explicit call. PRT theft has a real false-positive edge (roaming, VPN egress, authorised red-team) — but "probably the user travelled" is a hypothesis, not a verdict. Confirm with a record that names the user, device, origin and window.

Extract and record:

  • 1Leaking DeviceName / DeviceId and the local account that ran the extraction/mint (I1/I2).
  • 2Compromised UserPrincipalName and whether it holds privileged roles.
  • 3Attacker IP address(es), ASN, geo, user agent from I3/I5.
  • 4Tooling artifacts — binary names/hashes, command lines, and any x-ms-RefreshTokenCredential nonce.
  • 5Timeline: mint/extraction time → first replay → post-access actions (mail/file/OAuth).
True Positive SignalsFalse Positive Signals
CloudAP/LSASS extraction tool or LSASS read on the endpoint (I1)No endpoint theft artifact; single risk detection later fully explained
BrowserCore.exe minting a PRT cookie from a shell parent (I2)BrowserCore spawned by msedge/chrome during normal SSO
Trusted device sign-in from new ASN/country with MFA pre-satisfied (I3)New IP matches a documented VPN egress / corporate roaming pattern
anomalousToken / tokenIssuerAnomaly plus non-interactive replay (I4/I5)Risk detection dismissed by ID Protection after benign confirmation
Post-access mail/file/OAuth actions from the attacker originNamed red-team engagement with matching account, IP and time window

If any I1/I2 endpoint artifact OR an I3 replay to a privileged account is present, declare TP and go straight to Containment. Do not wait for all six indicators to line up — a live PRT is being spent while you deliberate.

🚫

03 — CONTAINMENT

STOP IT
C1
Verdict & Containment Decision
DECISION GATE
▶ Based on Identification Findings — Select One
Confirmed Endpoint theft artifact (I1/I2) OR trusted-device replay from a new origin (I3), with or without token-risk (I4) — execute C2–C4 immediately, escalate to L2/IR. If the account is privileged, page CISO.
Uncertain Single token-risk detection (I4) with no endpoint artifact and no confirmed replay origin — revoke sessions as a precaution (C3), complete I3/I5, hold isolation pending device attribution.
False Pos. New origin fully matched to documented VPN/roaming or an authorised red-team record naming user + IP + window — document justification, dismiss risk in ID Protection, tune, close.

Order matters: revoke tokens (C3) BEFORE or alongside device isolation. Isolating the host stops new mints but does not kill tokens already exfiltrated — those die only on refresh-token revocation.

C2
Isolate the Leaking Endpoint & Preserve Evidence
MDE ISOLATION
📍 Portal Navigation — MDE Device Isolation
security.microsoft.com› Assets› Devices› [Device]› Isolate Device
  • 1Before isolation, start a Live Response session and collect a memory image + running-process list — CloudAP state and tooling are volatile.
  • 2Click Actions (⋮) → Isolate Device and choose Full Isolation to cut the host off from further token minting.
  • 3Collect the investigation package (Actions → Collect investigation package) for offline forensics.
  • 4Query other devices in the same subnet/user scope for the same I1/I2 activity — PRT theft is often part of a broader hands-on-keyboard intrusion.

Do not power off the endpoint — CloudAP keys and the attacker's in-memory tooling are lost on shutdown. Network isolation preserves the memory-resident evidence.

C3
Revoke Tokens & Contain the Identity
ENTRA CONTAINMENT
📍 Portal Navigation — Entra User Containment
entra.microsoft.com› Identity› Users› [UPN]› Revoke sessions
  • 1Revoke all refresh tokens — user profile → Revoke sessions (or Graph POST /users/{id}/revokeSignInSessions). This invalidates every token minted from the PRT.
  • 2Reset the user's password and require change at next sign-in — needed to stop re-authentication, but on its own it does NOT kill the PRT (revocation in step 1 does).
  • 3Block sign-in temporarily (Account enabled = No) for privileged accounts until the device is cleared.
  • 4Re-evaluate MFA methods — confirm no attacker-registered method was added post-replay (Authentication methods blade); remove any rogue method and cross-reference SOP-80.
  • 5Confirm the user as compromised in ID Protection so risk-based Conditional Access enforces re-auth on next attempt.

Graph one-liner to revoke: Invoke-MgInvalidateUserRefreshToken -UserId <UPN> (or the REST revokeSignInSessions action). Verify the response is true before moving on.

C4
Contain the Device Identity & Block Attacker Origin
DEVICE + NETWORK
📍 Portal Navigation — Entra Devices
entra.microsoft.com› Identity› Devices› All devices› [Device] → Disable
  • 1Disable the compromised device object in Entra — this stops its device key from signing new PRT requests. Plan a full re-registration/re-image before re-enabling.
  • 2Block the attacker IP/ASN via a Conditional Access named location (block policy) and add it as an MDE network indicator (Settings → Endpoints → Indicators → IP addresses).
  • 3Tighten Conditional Access for the user: require compliant device + phishing-resistant MFA, and enable token protection (bind sessions to the device) where licensed.
  • 4For any app the attacker touched (I5), review and revoke suspicious OAuth grants (Enterprise applications → Permissions) — cross-reference SOP-21.
🗑

04 — ERADICATION

CLEAN UP
E1
Remove Foothold, Rebuild Device & Close the Vector
ERADICATION
  • 1From the I1/I2 initiating-process chain, trace back to initial access (phishing, malicious download, lateral movement) and remove it — kill malicious processes via Live Response, delete dropped tooling, quarantine confirmed in MDE.
  • 2Hunt for and remove persistence created by the same account/process around the theft window — scheduled tasks, run keys, WMI subscriptions (cross-reference SOP-26 / SOP-30).
  • 3Re-image or re-register the compromised device. Because CloudAP key material may have been touched, do not trust an in-place clean for a confirmed extraction — rebuild and re-join, then re-enable the device object.
  • 4Rotate secrets the session could reach — any app secrets, keys, or tokens the user/session had access to during the dwell window.
  • 5Close the vector: enforce Credential Guard / LSASS protection (RunAsPPL) to blunt CloudAP extraction, require TPM-backed device keys, and enable token protection Conditional Access so future tokens are cryptographically bound to the device.
  • 6Verify clean state — re-run I1, I2, I3 and I5 expecting 0 hits; confirm ID Protection shows the user risk remediated and no new non-interactive replay from the attacker origin.
Eradication Complete When
  • All refresh tokens revoked and password reset confirmed (C3 response = true)
  • Leaking device disabled and re-imaged/re-registered; device object re-enabled only after rebuild
  • Attacker IP/ASN blocked in Conditional Access and MDE indicators
  • No rogue MFA method, inbox rule, or OAuth grant remains on the account
  • I1/I2/I3/I5 queries return 0 hits over the incident window
  • Timeline reconstructed: extraction/mint → first replay → post-access actions
  • Token protection / Credential Guard / RunAsPPL enforced to prevent recurrence

Do not close on a password reset alone. Until refresh tokens are revoked and the device key is invalidated (disable + rebuild), the attacker's replayed session and any long-lived refresh tokens remain valid.

📢

05 — ESCALATION

TIERS
ES1
Escalation Matrix & Notification
ESCALATION
TierTrigger ConditionWho to NotifyAction
L1 → L2Cannot confirm TP vs FP within 30 min; token-risk detection with no clear device attribution; any privileged account involvedSOC L2 / Identity LeadHand off with IOC pack; L2 drives Sentinel correlation (I3–I5)
L2 → IRConfirmed endpoint extraction (I1/I2) or Pass-the-PRT replay (I3); active non-interactive replay (I5); >1 device/user affectedIncident Response TeamFull IR: isolate, revoke, rebuild device, hunt lateral spread
IR → CISOPrivileged/Global Admin token replayed; mailbox/file exfiltration confirmed; multiple identities compromisedCISO / Security ManagementDeclare major incident; assess breach-notification obligations
CISO → Exec / LegalCustomer/regulated data accessed via the replayed session; tenant-wide admin compromiseCISO → CEO → Legal / DPOGDPR 72h clock; regulator & affected-party notification
ExternalNation-state / sophisticated actor indicators; incident exceeds internal capacityMSSP / DFIR vendor / law enforcementEngage forensics retainer; preserve evidence chain of custody

Bring to every escalation:

  • 1Incident / alert ID and current confidence (TP confirmed / suspected / unverified).
  • 2Affected user(s), device(s), and whether any hold privileged roles.
  • 3Timeline: extraction/mint time → first replay → post-access actions.
  • 4Attacker IOCs: IP/ASN, user agent, tooling artifacts, DeviceId.
  • 5Containment already executed: tokens revoked? device disabled? IP blocked?

A single confirmed replay to a Global Admin or PIM-eligible account is a potential tenant-takeover — escalate straight to IR + CISO regardless of how few sign-in events appear. One replayed privileged token is enough.


Stay Threat-Ready

Follow CyberHawk Threat Intel for daily SOC analyst playbooks, detection engineering guides, and threat intelligence.

📺 YouTube 🎤 TikTok 🐦 X / Twitter 📡 Telegram
All SOPs Blog Web App (Free)
They can't exploit you if you are the Exploit.