IR AnalystSwitch roles in the top navigation to see different perspectives.

Revoke all active cloud sessions, refresh tokens, and access tokens for compromised accounts. This ensures the attacker loses all authenticated sessions across M365, Azure, and federated SaaS applications.

Actions

  1. 1.Revoke all Azure AD refresh tokens: `Revoke-MgUserSignInSession -UserId <user_id>`. This invalidates all active sessions and forces re-authentication across all devices and applications.
  2. 2.Revoke specific OAuth app tokens: `Remove-AzureADOAuth2PermissionGrant -ObjectId <grant_id>` for each malicious grant identified. Also remove service principal assignments: `Remove-AzureADServiceAppRoleAssignment`.
  3. 3.Force re-registration of all user devices: `Get-AzureADUserRegisteredDevice -ObjectId <user_id> | ForEach-Object { Set-AzureADDevice -ObjectId $_.ObjectId -AccountEnabled $false }`. This invalidates device-based SSO tokens.
  4. 4.For Azure resources: revoke Azure RBAC role assignments granted by the attacker: `Get-AzRoleAssignment -SignInName <compromised_user> | Where-Object { $_.CreatedOn -ge T_START } | Remove-AzRoleAssignment`.
  5. 5.Verify revocation is effective: check sign-in logs for any successful authentications after revocation. Residual sessions may persist for up to 1 hour due to token caching: `SigninLogs | where UserPrincipalName == "compromised_user" | where TimeGenerated > ago(1h) | where ResultType == 0`.

Queries

SigninLogs | where TimeGenerated > ago(2h) | where UserPrincipalName == "[email protected]" | where ResultType == 0 | project TimeGenerated, AppDisplayName, IPAddress, ClientAppUsed, DeviceDetail, ConditionalAccessStatus | order by TimeGenerated desc
AuditLogs | where TimeGenerated > ago(24h) | where OperationName in ("Revoke user all refresh tokens","Invalidate all refresh tokens for user","Disable device") | where InitiatedBy has "ir-admin" | project TimeGenerated, OperationName, TargetResources | order by TimeGenerated desc
CloudAppEvents | where Timestamp > ago(2h) | where AccountObjectId == "<user_object_id>" | summarize PostRevocationActivity=count() by ActionType, IPAddress | order by PostRevocationActivity desc

Notes

  • Token revocation is NOT instant. Azure AD access tokens have a default lifetime of 60-90 minutes. The attacker may retain access for up to 1 hour after revocation. Monitor for continued activity during this window.
  • Continuous Access Evaluation (CAE) can reduce this window for supported applications. Verify CAE is enabled in the tenant Conditional Access settings.