Query Details
id: f3a1c2e4-8b5d-4e7f-a9c1-2b3d4e5f6a7b
name: Token Theft - Refresh Token Replay from New Location
version: 1.0.0
kind: Scheduled
description: |
Detects when the same user refreshes an OAuth token from a completely different
IP address AND country within a 30-minute window. This is a strong indicator of
refresh token theft / pass-the-cookie attacks where an attacker has stolen a
refresh token and is replaying it from a different network.
MITRE ATT&CK: T1528 (Steal Application Access Token), T1539 (Steal Web Session Cookie)
severity: High
requiredDataConnectors:
- connectorId: AzureActiveDirectory
dataTypes:
- AADNonInteractiveUserSignInLogs
queryFrequency: 1h
queryPeriod: 1h
triggerOperator: gt
triggerThreshold: 0
tactics:
- CredentialAccess
- LateralMovement
relevantTechniques:
- T1528
- T1539
query: |
AADNonInteractiveUserSignInLogs
| where TimeGenerated > ago(1h)
| where ResultType == 0
| sort by UserPrincipalName asc, AppId asc, TimeGenerated asc
| extend PrevIP = prev(IPAddress, 1)
| extend PrevCountry = prev(Location, 1)
| extend PrevTime = prev(TimeGenerated, 1)
| extend PrevUser = prev(UserPrincipalName, 1)
| extend PrevApp = prev(AppId, 1)
| where UserPrincipalName == PrevUser
and AppId == PrevApp
and IPAddress != PrevIP
and Location != PrevCountry
and (TimeGenerated - PrevTime) < 30m
| project
TimeGenerated,
PrevTokenTime = PrevTime,
UserPrincipalName,
AppDisplayName,
CurrentIP = IPAddress,
CurrentCountry = Location,
PreviousIP = PrevIP,
PreviousCountry = PrevCountry,
TimeBetweenTokens = (TimeGenerated - PrevTime),
CorrelationId,
UniqueTokenIdentifier
| order by TimeGenerated desc
entityMappings:
- entityType: Account
fieldMappings:
- identifier: FullName
columnName: UserPrincipalName
- entityType: IP
fieldMappings:
- identifier: Address
columnName: CurrentIP
customDetails:
PreviousIP: PreviousIP
PreviousCountry: PreviousCountry
CurrentCountry: CurrentCountry
AppDisplayName: AppDisplayName
alertDetailsOverride:
alertDisplayNameFormat: "Token Replay Detected - {{UserPrincipalName}} authenticated from new country after prior token from {{CurrentCountry}}"
alertDescriptionFormat: "User {{UserPrincipalName}} refreshed a token from {{CurrentIP}} ({{CurrentCountry}}) within 30 min of a prior refresh from a different country. Possible refresh token theft."
alertSeverityColumnName: ""
alertTacticsColumnName: ""
incidentConfiguration:
createIncident: true
groupingConfiguration:
enabled: true
reopenClosedIncident: false
lookbackDuration: PT5H
matchingMethod: AnyAlert
groupByEntities:
- Account
groupByAlertDetails: []
groupByCustomDetails: []
This query is designed to detect suspicious activity related to OAuth token refreshes, which could indicate a security breach. Here's a simple breakdown of what it does:
Purpose: The query identifies instances where the same user refreshes an OAuth token from a different IP address and country within a 30-minute window. This behavior is a strong indicator of potential token theft or a "pass-the-cookie" attack, where an attacker uses a stolen refresh token from a different location.
Data Source: It uses logs from Azure Active Directory, specifically focusing on non-interactive user sign-ins.
Detection Logic:
Output: The query outputs details such as the time of the token refresh, the user's name, the application used, the current and previous IP addresses and countries, and the time difference between the token refreshes.
Alerting: If such activity is detected, it triggers an alert with a high severity level, indicating potential credential access or lateral movement tactics. The alert includes details about the user and the suspicious activity.
Incident Management: The system is configured to create incidents based on these alerts, grouping them by user account for better incident management.
In summary, this query helps identify and alert on potential security incidents involving the misuse of OAuth tokens from different locations, which could signify unauthorized access attempts.

David Alonso
Released: May 29, 2026
Tables
Keywords
Operators