Query Details

HUNT 14 AAD Prov Self Provisioning Loop 30d

Query

id: aa1f000e-200e-420e-920e-aadprov-hunt14
name: HUNT-14 Provisioning Self-Service Loop - Actor Modifies Own Object (30d)
description: |
  Surfaces provisioning events where the initiating identity and the target
  identity are the same principal - an actor provisioning, enabling,
  re-enabling, or rewriting attributes on their own object through the
  provisioning channel. Self-modification through provisioning is a stealthy
  privilege-persistence path: the change rarely raises a console alert and
  bypasses the usual two-person separation that direct admin portal edits
  attract. Benign in some HR-driven self-service scenarios, so treat as a
  hunt rather than an alert and triage on the PropName / AssignedRoles
  custom output.
  MITRE ATT&CK: T1098 (Account Manipulation),
  T1078.004 (Valid Accounts: Cloud Accounts).
severity: Medium
requiredDataConnectors:
  - connectorId: AzureActiveDirectory
    dataTypes:
      - AADProvisioningLogs
tactics:
  - Persistence
  - PrivilegeEscalation
relevantTechniques:
  - T1098
  - T1078.004
query: |
  let PrivilegedUsers =
      IdentityInfo
      | where TimeGenerated > ago(14d)
      | summarize arg_max(TimeGenerated, *) by AccountUPN
      | where isnotempty(AssignedRoles) and AssignedRoles != "[]"
      | project AccountUPN, AssignedRoles;
  AADProvisioningLogs
  | where TimeGenerated > ago(30d)
  | where ResultType =~ "Success"
  | extend InitiatorUpn = tolower(tostring(parse_json(InitiatedBy).userPrincipalName)),
           TargetUpn    = tolower(tostring(parse_json(TargetIdentity).userPrincipalName)),
           SPName       = tostring(parse_json(ServicePrincipal).Name)
  | where isnotempty(InitiatorUpn) and InitiatorUpn == TargetUpn
  | mv-expand Mod = todynamic(ModifiedProperties)
  | extend PropName = tostring(Mod.displayName),
           OldValue = tostring(Mod.oldValue),
           NewValue = tostring(Mod.newValue)
  | summarize
      EventCount    = count(),
      Actions       = make_set(ProvisioningAction, 10),
      ChangedProps  = make_set(PropName, 25),
      Jobs          = make_set(JobId, 10),
      FirstSeen     = min(TimeGenerated),
      LastSeen      = max(TimeGenerated)
    by InitiatorUpn, SPName
  | join kind=leftouter (PrivilegedUsers) on $left.InitiatorUpn == $right.AccountUPN
  | extend IsPrivileged = isnotempty(AssignedRoles)
  | project InitiatorUpn, IsPrivileged, AssignedRoles, SPName, EventCount,
            Actions, ChangedProps, Jobs, FirstSeen, LastSeen
  | order by IsPrivileged desc, EventCount desc

Explanation

This query is designed to identify and analyze instances where a user modifies their own account attributes through provisioning activities within Azure Active Directory. Here's a simplified breakdown:

  1. Purpose: The query detects self-service provisioning events where a user (the initiator) changes their own account details. This can be a subtle way for a user to maintain privileges without triggering alerts that typically occur with direct admin portal changes.

  2. Context: Such self-modifications can be legitimate in some HR-driven scenarios but may also indicate privilege persistence or escalation attempts. Therefore, these events are treated as hunting opportunities rather than immediate alerts.

  3. Data Source: It uses data from Azure Active Directory provisioning logs.

  4. Process:

    • It first identifies users with assigned roles (privileged users) from the last 14 days.
    • Then, it examines provisioning logs from the last 30 days to find successful events where the initiator and target are the same user.
    • It extracts details about the changes made, such as the properties modified and their old and new values.
    • It summarizes these events by counting occurrences, listing actions taken, properties changed, and job IDs, and notes the first and last time such events were seen.
    • It checks if the user involved is privileged by joining with the list of privileged users.
    • Finally, it orders the results by whether the user is privileged and the number of events.
  5. Output: The query provides a list of users who have modified their own accounts, highlighting whether they are privileged, the actions they took, and the properties they changed, along with timestamps of these activities. This helps in assessing potential security risks related to account manipulation.

Details

David Alonso profile picture

David Alonso

Released: June 1, 2026

Tables

IdentityInfoAADProvisioningLogs

Keywords

AzureActiveDirectoryAADProvisioningLogsIdentityInfoAccountUPNAssignedRolesInitiatedByTargetIdentityServicePrincipalModifiedPropertiesProvisioningActionJobIdTimeGenerated

Operators

letwheresummarizearg_maxisnotemptyprojectagoextendtolowertostringparse_jsonmv-expandtodynamicmake_setminmaxjoinonorder by

Actions