Query Details

HUNT 13 AAD Prov Sync Token Replay Geography 14v90d

Query

id: aa1f000d-200d-420d-920d-aadprov-hunt13
name: HUNT-13 Sync Account Token-Replay Geography (14d vs 90d)
description: |
  Surfaces new sign-in geographies / IP addresses for the Entra Connector
  sync account on the non-interactive table (AADNonInteractiveUserSignInLogs),
  where most sync token-refresh traffic lives. Token theft from the Entra
  Connect host typically surfaces here as a refresh-token replay from a new
  IP/Location that never appears in the 90-day baseline. Complements HUNT-03
  (which is allowlist-based and interactive-inclusive): this hunt is a
  first-seen baseline-diff scoped to the non-interactive channel only.
  MITRE ATT&CK: T1078.004 (Valid Accounts: Cloud Accounts),
  T1550.001 (Use Alternate Authentication Material: Application Access Token).
severity: High
requiredDataConnectors:
  - connectorId: AzureActiveDirectory
    dataTypes:
      - AADNonInteractiveUserSignInLogs
tactics:
  - InitialAccess
  - DefenseEvasion
relevantTechniques:
  - T1078.004
  - T1550.001
query: |
  let Lookback = 14d;
  let Baseline = 90d;
  let SyncSignins =
      AADNonInteractiveUserSignInLogs
      | where ResultType == 0
      | where UserPrincipalName startswith "Sync_"
           or UserPrincipalName contains "DirSync"
           or UserDisplayName has "On-Premises Directory Synchronization Service Account";
  // IPs / locations seen in the 90d->14d historical window (the known-good baseline).
  let KnownGeo =
      SyncSignins
      | where TimeGenerated between (ago(Baseline) .. ago(Lookback))
      | summarize by UserPrincipalName, IPAddress, Location;
  SyncSignins
  | where TimeGenerated > ago(Lookback)
  | join kind=leftanti KnownGeo on UserPrincipalName, IPAddress, Location
  | summarize
      SigninCount = count(),
      Apps        = make_set(AppDisplayName, 10),
      Locations   = make_set(Location, 10),
      ASNs        = make_set(AutonomousSystemNumber, 10),
      Days        = dcount(startofday(TimeGenerated)),
      FirstSeen   = min(TimeGenerated),
      LastSeen    = max(TimeGenerated)
    by UserPrincipalName, IPAddress
  | order by FirstSeen desc

Explanation

This query is designed to detect suspicious sign-in activities for a specific type of account used in directory synchronization (sync accounts) within an Azure Active Directory environment. Here's a simplified breakdown:

  1. Purpose: The query identifies new geographic locations or IP addresses from which these sync accounts are signing in. This is important because it can indicate potential token theft or unauthorized access if these locations/IPs have not been seen in the past 90 days.

  2. Data Source: It uses data from the AADNonInteractiveUserSignInLogs, which records non-interactive sign-ins (like those performed by background services).

  3. Timeframe:

    • Lookback Period: The query examines sign-ins from the last 14 days.
    • Baseline Period: It compares these against a 90-day historical baseline to identify new locations/IPs.
  4. Process:

    • It first filters sign-ins related to sync accounts.
    • It establishes a baseline of known good locations/IPs from the 90-day period.
    • It then identifies any sign-ins in the last 14 days from locations/IPs not seen in the baseline.
  5. Output: The query provides a summary of these new sign-ins, including:

    • The number of sign-ins (SigninCount).
    • The applications accessed (Apps).
    • The locations and Autonomous System Numbers (ASNs) involved.
    • The number of days these sign-ins occurred (Days).
    • The first and last time these sign-ins were seen.
  6. Severity and Techniques: The query is marked with high severity and is associated with tactics like Initial Access and Defense Evasion, referencing specific MITRE ATT&CK techniques related to cloud account misuse and token replay attacks.

In essence, this query helps security teams identify potentially unauthorized access attempts to sync accounts by highlighting new and unusual sign-in patterns.

Details

David Alonso profile picture

David Alonso

Released: June 1, 2026

Tables

AADNonInteractiveUserSignInLogs

Keywords

EntraConnectorSyncAccountTokenIPLocationSigninUserPrincipalNameUserDisplayNameDirectorySynchronizationServiceAccountTimeGeneratedIPAddressLocationAppDisplayNameAutonomousSystemNumber

Operators

letwherestartswithcontainshasbetweenagosummarizebyjoinkind=leftantioncountmake_setdcountstartofdayminmaxorder bydesc

Actions