Query Details

HUNT-14 Provisioning Self-Service Loop - Actor Modifies Own Object (30d)

HUNT 14 AAD Prov Self Provisioning Loop 30d

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

Severity

Medium

Tactics

PersistencePrivilegeEscalation

MITRE Techniques

Actions

GitHub