Query Details
id: 5a6f1c3e-2a1b-4c9e-9f01-11a2b3c4d503
name: Intune - Device registered with impossible travel to sign-in
description: |
Correlates a new Intune/Azure AD device registration with a sign-in from a geographic
location inconsistent with the user's recent sign-ins (impossible travel). Common in
token-theft scenarios where an adversary registers their own device using a stolen PRT
or refresh token (AADInternals `Join-AADIntDeviceToAzureAD -PRTToken`).
severity: High
requiredDataConnectors:
- connectorId: AzureActiveDirectory
dataTypes:
- SigninLogs
- connectorId: AzureMonitor(IntuneLogs)
dataTypes:
- IntuneAuditLogs
queryFrequency: 1h
queryPeriod: 1d
triggerOperator: gt
triggerThreshold: 0
status: Available
tactics:
- Persistence
- CredentialAccess
relevantTechniques:
- T1098.005
- T1528
query: |
let lookback = 1d;
let NetworkAllowlist = _GetWatchlist('NetworkAllowlist') | project IPRange = tostring(SearchKey);
let AllowedRanges = toscalar(NetworkAllowlist | summarize make_list(IPRange));
let registrations =
IntuneAuditLogs
| where TimeGenerated > ago(lookback)
| where OperationName has_any ("enroll","register","Create Device")
| extend DeviceName = tostring(parse_json(tostring(Properties)).TargetObjectName)
| project RegTime=TimeGenerated, UserPrincipalName=tolower(tostring(Identity)), DeviceName, OperationName;
let signins =
SigninLogs
| where TimeGenerated > ago(lookback)
| where ResultType == 0
| project SignInTime=TimeGenerated, UserPrincipalName=tolower(UserPrincipalName),
IPAddress, Location=tostring(LocationDetails.countryOrRegion),
City=tostring(LocationDetails.city), AppDisplayName, DeviceDetail=tostring(DeviceDetail);
registrations
| join kind=inner signins on UserPrincipalName
| where not(ipv4_is_in_any_range(tostring(IPAddress), AllowedRanges))
| where abs(datetime_diff('minute', RegTime, SignInTime)) <= 60
| summarize Locations = make_set(Location, 10),
Cities = make_set(City, 10),
IPs = make_set(IPAddress, 10),
Apps = make_set(AppDisplayName, 10),
FirstSignIn = min(SignInTime), LastSignIn = max(SignInTime)
by UserPrincipalName, DeviceName, RegTime, OperationName
| where array_length(Locations) > 1
| extend AccountCustomEntity = UserPrincipalName, HostCustomEntity = DeviceName
entityMappings:
- entityType: Account
fieldMappings:
- identifier: FullName
columnName: AccountCustomEntity
- entityType: Host
fieldMappings:
- identifier: HostName
columnName: HostCustomEntity
version: 1.0.0
kind: Scheduled
This query is designed to detect suspicious activity related to device registrations in Intune/Azure AD that may indicate a security threat, such as token theft. Here's a simple breakdown of what it does:
Purpose: The query identifies cases where a new device is registered to a user's account and there is a sign-in from a location that is inconsistent with the user's recent sign-in history. This is often referred to as "impossible travel" because it would be unlikely for a user to physically travel between these locations in such a short time.
Data Sources: It uses data from Azure Active Directory Sign-in Logs and Intune Audit Logs to find relevant events.
Logic:
1d) to find device registration events and successful sign-ins.Output: The query summarizes the findings by listing the different locations, cities, IP addresses, and applications involved in the sign-ins, along with the first and last sign-in times. It highlights the user and device involved in these activities.
Severity and Tactics: The query is marked with high severity and is associated with tactics like Persistence and Credential Access, indicating that it could be part of a broader attack strategy.
Trigger: It runs every hour and triggers an alert if any suspicious activity is detected.
Overall, this query helps security teams identify and respond to potential security incidents involving unauthorized device registrations and sign-ins from unusual locations.

David Alonso
Released: April 22, 2026
Tables
Keywords
Operators