RUNBOOK // Stolen Token & Cloud Session Hijacking Remediation
Token theft (Pass-the-Cookie / Pass-the-PRT) allows adversaries to hijack active authenticated sessions in Microsoft 365, Azure, and AWS without knowing the user’s password and completely bypassing Multi-Factor Authentication (MFA).
Tokens are typically harvested via:
- Infostealer Malware (Lumma, RedLine, Vidar) dumping browser SQLite cookie stores (
Cookiesfile in Chrome/Edge). - AiTM Phishing Proxies (Evilginx) intercepting
ESTSAUTHsession tokens during login. - Endpoint Memory Extraction: Extracting the Primary Refresh Token (PRT) or session cookies from
lsass.exeor browser process memory.
🛑 Step 1: Emergency Token Revocation Protocol (< 5 Minutes)
Section titled “🛑 Step 1: Emergency Token Revocation Protocol (< 5 Minutes)”Executing a standard password reset alone is NOT enough to stop token replay, because active access tokens remain valid until their expiration lifetime (typically 60-90 minutes) unless explicitly revoked.
The 3-Step PowerShell Invalidation Protocol:
Section titled “The 3-Step PowerShell Invalidation Protocol:”# Connect to Microsoft Graph with Directory Admin scopesConnect-MgGraph -Scopes "User.ReadWrite.All", "Directory.AccessAsUser.All"
$targetUser = "compromised.user@company.com"
# 1. Invalidate all active browser and desktop refresh tokens immediatelyRevoke-MgUserSignInSession -UserId $targetUserWrite-Host "[+] All active refresh tokens revoked for $targetUser." -ForegroundColor Green
# 2. Reset password to immediately invalidate OAuth refresh token chains$newPassword = [System.Web.Security.Membership]::GeneratePassword(18, 4) + "!A1"Update-MgUser -UserId $targetUser -PasswordProfile @{ ForceChangePasswordNextSignIn = $true Password = $newPassword}Write-Host "[+] Password forcibly rotated." -ForegroundColor Green
# 3. Terminate active sessions in Microsoft 365 Admin Portal# Continuous Access Evaluation (CAE) will revoke access tokens within seconds across supported workloads (Exchange, SharePoint, Teams)💻 Step 2: Primary Refresh Token (PRT) Quarantine on Endpoint
Section titled “💻 Step 2: Primary Refresh Token (PRT) Quarantine on Endpoint”If the user’s endpoint was infected with an infostealer or accessed by an attacker, the Primary Refresh Token (PRT) stored in the TPM/Cloud AP plugin must be regenerated:
:: Execute on affected Windows workstation (Command Prompt as Admin):: 1. Sever Entra ID device registrationdsregcmd /leave
:: 2. Re-register device with Entra ID to issue fresh cryptographic keysdsregcmd /join🔎 Step 3: KQL Hunting: Tracing Replayed Token Activity
Section titled “🔎 Step 3: KQL Hunting: Tracing Replayed Token Activity”Identify every action the attacker executed using the stolen token in SigninLogs and AuditLogs:
1. Detect Token Replay from Anomalous IP / Hosting Providers
Section titled “1. Detect Token Replay from Anomalous IP / Hosting Providers”Find sign-ins where the session presented a valid MFA claim, but the IP address belonged to a VPN, Tor exit node, or cloud datacenter (AWS, DigitalOcean, Linode):
let TargetUser = "compromised.user@company.com";SigninLogs| where TimeGenerated > ago(7d)| where UserPrincipalName =~ TargetUser| where ResultType == 0 // Successful logon| extend AutonomousSystemName = tostring(AutonomousSystemNumber)| project TimeGenerated, UserPrincipalName, IPAddress, AppDisplayName, City = tostring(LocationDetails.city), Country = tostring(LocationDetails.countryOrRegion), UserAgent, AuthenticationRequirement| sort by TimeGenerated desc2. Hunting for Graph API & Egress Activity with Stolen Token
Section titled “2. Hunting for Graph API & Egress Activity with Stolen Token”Attackers commonly use stolen tokens with CLI tools (like TokenTactics or AADInternals) to dump the Global Address List, access OneDrive, or search Outlook:
let TargetUser = "compromised.user@company.com";AuditLogs| where TimeGenerated > ago(3d)| where InitiatedBy.user.userPrincipalName =~ TargetUser| project TimeGenerated, OperationName, TargetResources, Result, AdditionalDetails| sort by TimeGenerated desc📱 Step 4: Audit Malicious OAuth App Consents & Persistence
Section titled “📱 Step 4: Audit Malicious OAuth App Consents & Persistence”Adversaries use compromised sessions to grant persistence permissions to their own third-party App Registrations:
# Audit and remove any enterprise apps consented by the user in the last 7 daysGet-MgUserOAuth2PermissionGrant -UserId $targetUser | ForEach-Object { [PSCustomObject]@{ ConsentId = $_.Id ClientId = $_.ClientId Scope = $_.Scope ConsentType = $_.ConsentType }}To remove a suspect grant:
Remove-MgOauth2PermissionGrant -OAuth2PermissionGrantId "<ConsentId>"🛡️ Step 5: Post-Incident Hardening Checklist
Section titled “🛡️ Step 5: Post-Incident Hardening Checklist”- Audit MFA Authentication Methods: Verify that the attacker did not register an unauthorized phone number or Microsoft Authenticator app on
mysignins.microsoft.com. - Check Exchange Inbox Rules: Inspect mailbox for hidden rules forwarding incoming emails to external domains.
- Enable Continuous Access Evaluation (CAE): Ensure CAE is enabled in Conditional Access to revoke tokens in real-time when IP/location changes occur.
- Configure Conditional Access Token Protection: Require cryptographic proof-of-possession binding for refresh tokens on managed devices.