Query Details

HUNT 06 AAD Prov New Service Principals 30v90d

Query

id: aa1f0006-2006-4206-9206-aadprov-hunt06
name: HUNT-06 New ServicePrincipals Performing Provisioning (30d vs 90d)
description: |
  Provisioning SPs active in the last 30 days but absent from the prior 60.
  Complements RULE-11 with a longer history window for retrospective hunts
  after a watchlist refresh or new SCIM application investigation.
severity: Medium
requiredDataConnectors:
  - connectorId: AzureActiveDirectory
    dataTypes:
      - AADProvisioningLogs
tactics:
  - Persistence
relevantTechniques:
  - T1136
query: |
  let Recent =
      AADProvisioningLogs
      | where TimeGenerated > ago(30d)
      | extend SPName = tostring(parse_json(ServicePrincipal).Name),
               SPId   = tostring(parse_json(ServicePrincipal).Id)
      | summarize
          Events     = count(),
          FirstSeen  = min(TimeGenerated),
          LastSeen   = max(TimeGenerated),
          Operations = make_set(OperationName, 10),
          Targets    = dcount(TargetIdentity)
        by SPId, SPName;
  let Historical =
      AADProvisioningLogs
      | where TimeGenerated between (ago(120d) .. ago(30d))
      | extend SPId = tostring(parse_json(ServicePrincipal).Id)
      | distinct SPId;
  Recent
  | join kind=leftanti (Historical) on SPId
  | order by Events desc

Explanation

This query is designed to identify new service principals (SPs) that have been actively involved in provisioning activities within the last 30 days but were not active in the preceding 60 days. Here's a simple breakdown of what the query does:

  1. Data Source: It uses data from Azure Active Directory's provisioning logs.

  2. Recent Activity: The query first looks at provisioning logs from the last 30 days. It extracts the name and ID of each service principal and summarizes their activity, including the number of events, the first and last time they were seen, the types of operations they performed, and the number of unique targets they interacted with.

  3. Historical Activity: It then checks the logs from 30 to 120 days ago to find service principals that were active during that period.

  4. Comparison: The query compares the two sets of data to find service principals that are active in the recent period but were not present in the historical period.

  5. Output: The result is a list of service principals that are newly active in the last 30 days, sorted by the number of events they were involved in, in descending order.

This query is useful for identifying potentially suspicious new service principals that might be involved in persistence tactics, as defined by the MITRE ATT&CK framework technique T1136 (Create Account).

Details

David Alonso profile picture

David Alonso

Released: June 1, 2026

Tables

AADProvisioningLogs

Keywords

AzureActiveDirectoryAADProvisioningLogsServicePrincipalTimeGeneratedSPNameSPIdEventsFirstSeenLastSeenOperationsTargetsTargetIdentity

Operators

let|where>ago()extendtostring()parse_json()summarizecount()min()max()make_set()dcount()bybetween..distinctjoinkind=leftantionorder bydesc

Actions