Query Details

Azure AD Device Registration From New IP Address

Query

# *Azure AD Device Registration from New IP Address*

## Query Information

#### MITRE ATT&CK Technique(s)

| Technique ID | Title    | Link    |
| ---  | --- | --- |
| T1098.005 | Device Registration | https://attack.mitre.org/techniques/T1098/005/ |

#### Description

This rule detects new device registrations in Azure Active Directory (AAD) that originate from an IP address not previously associated with the user's account within the last 29 days. It filters out registrations from corporate IP ranges and common mobile operating systems (iOS, Android) to reduce noise. The rule categorizes the risk level of the IP address based on historical sign-in counts, focusing on 'High Risk - New IP' events. It then enriches these events with additional sign-in details like device name, risk level during sign-in, country, and city.

#### Author <Optional>
- **Name: Benjamin Zulliger**
- **Github: https://github.com/benscha/KQLAdvancedHunting**
- **LinkedIn: https://www.linkedin.com/in/benjamin-zulliger/**


## Defender XDR
```KQL
let ExcludedOS = datatable( OperatingSystem: string) ["iOS", "Android"];
let CorporateIPRange   = "xx.xx.";
// List of new Device Registrations
let DeviceRegistration = AuditLogs
| where TimeGenerated >ago(2h)
| where Category == "Device"
| where OperationName in ("Register device")
| extend Additional = todynamic(AdditionalDetails)
| mv-expand Additional
| extend DetailKey = tostring(Additional.key), 
         DetailValue = tostring(Additional.value)
| where DetailKey == "Device OS"
| project TimeGenerated,
          OperationName,
          InitiatedBy = tostring(InitiatedBy.user.displayName),
          AccountUpn = tostring(InitiatedBy.user.userPrincipalName),
          TargetDevice = tostring(TargetResources[0].displayName),
          DeviceId = tostring(TargetResources[0].id),
          Result = tostring(Result),
          IPAddress = tostring(InitiatedBy.user.ipAddress),
          OperatingSystem = DetailValue
| where OperatingSystem !in (ExcludedOS)
| where isnotempty( AccountUpn)
| sort by TimeGenerated desc
| where IPAddress !startswith (CorporateIPRange)
| summarize arg_max(TimeGenerated, *) by AccountUpn
| project TimeGenerated, AccountUpn, TargetDevice, IPAddress, OperatingSystem;
let HistoricalIPCounts = AADSignInEventsBeta
| where ErrorCode == 0
| where Timestamp >= ago(29d)
| summarize IPSeenCount = count() by AccountUpn, IPAddress;
// Build the IP list per account
let HistoricalIPs = AADSignInEventsBeta
| where ErrorCode == 0
| where Timestamp >= ago(29d)
| summarize HistoricalIPs = make_set(IPAddress) by AccountUpn;
// Join with RiskySignIns and Counts
DeviceRegistration
| join kind=leftouter HistoricalIPs on AccountUpn
| join kind=leftouter HistoricalIPCounts on AccountUpn, IPAddress
| extend 
    IPSeenBefore = iff(isnotempty(IPSeenCount), true, false),
    IPSeenCount = coalesce(IPSeenCount, 0)
| extend IPRiskLevel = case(
        IPSeenBefore == false, "High Risk - New IP",
        IPSeenBefore == true and IPSeenCount < 3, "Medium Risk - Rare IP",
        IPSeenBefore == true and IPSeenCount >= 3, "Lower Risk - Frequent IP",
        "Unknown"
    )
// Filter for only New IPs. here you can adapt the value
| where IPRiskLevel startswith "High"
| join kind=leftouter ( AADSignInEventsBeta
        | summarize arg_max(TimeGenerated, DeviceName, RiskLevelDuringSignIn, Country, City) by AccountUpn, IPAddress ) on AccountUpn, IPAddress
```

Explanation

This query is designed to identify potentially suspicious device registrations in Azure Active Directory (AAD). Here's a simplified breakdown of what it does:

  1. Purpose: The query aims to detect new device registrations from IP addresses that haven't been used by the user's account in the past 29 days. It excludes registrations from known corporate IP ranges and common mobile operating systems (iOS, Android) to minimize false positives.

  2. Data Collection: It collects data from AAD audit logs, focusing on device registration events. It extracts details like the time of registration, the user's account, the device name, and the IP address used.

  3. Filtering:

    • It filters out registrations from corporate IP ranges and devices running iOS or Android.
    • It only considers registrations from new IP addresses that haven't been seen in the last 29 days.
  4. Risk Assessment:

    • It categorizes the risk level of each IP address based on how frequently it has been used in the past.
    • IPs not seen before are labeled as "High Risk - New IP."
    • IPs seen infrequently are labeled as "Medium Risk - Rare IP."
    • IPs seen frequently are labeled as "Lower Risk - Frequent IP."
  5. Enrichment: The query enriches the detected events with additional sign-in details, such as the device name, risk level during sign-in, and the geographical location (country and city) of the IP address.

  6. Output: The final output focuses on high-risk events, specifically those involving new IP addresses, providing a detailed view of potentially suspicious device registrations.

This query helps security teams monitor and investigate unusual device registration activities that could indicate unauthorized access attempts.

Details

Benjamin Zulliger profile picture

Benjamin Zulliger

Released: November 3, 2025

Tables

AuditLogsAADSignInEventsBeta

Keywords

AzureActiveDirectoryDeviceRegistrationIPAddressUserAccountOperatingSystemRiskLevelSignInCountryCity

Operators

letdatatablewhere>ago==inextendtodynamicmv-expandtostringproject!inisnotemptysort by!startswithsummarizearg_maxbymake_setjoinkind=leftouteriffcoalescecasestartswith

Actions