← Back to SOC feed Coverage →

Active Directory Sensitive Group Modifications

kql MEDIUM Azure-Sentinel
IdentityDirectoryEvents
huntingmicrosoftofficial
This rule was pulled from an open-source repository and enriched with AI. Validate in a test environment before deploying to production.
View original rule at Azure-Sentinel →
Retrieved: 2026-05-07T23:00:00Z · Confidence: medium

Hunt Hypothesis

Adversaries may modify sensitive Active Directory groups to escalate privileges or maintain persistence within the network. Proactively hunting for these modifications in Azure Sentinel helps identify potential lateral movement or privilege escalation attempts early.

KQL Query

// Detects changes in Tier 0 group memberships
// Command leverages MDI schema
// Execute from https://security.microsoft.com or through the M365D advanced hunting API
let Events = materialize (
IdentityDirectoryEvents
| where ActionType == 'Group Membership changed'
| extend ActivityType = iff(isnotempty(tostring(AdditionalFields['TO.GROUP'])),"Added Account", "Removed Account")
| where isnotempty(AccountSid)
);
let Tier0Adds = (
Events
| where ActivityType == "Added Account"
| extend TargetGroup = tostring(AdditionalFields['TO.GROUP'])
| extend TargetObject = iff(isempty(tostring(AdditionalFields['TARGET_OBJECT.USER'])), tostring(AdditionalFields['TARGET_OBJECT.GROUP']), tostring(AdditionalFields['TARGET_OBJECT.USER']))
| extend TargetType = iff(isempty(tostring(AdditionalFields['TARGET_OBJECT.USER'])), "Security Group", "User Account")
//| extend TargetObject = AdditionalFields['TARGET_OBJECT.USER']
);
let Tier0Removes = (
Events
| where ActivityType == "Removed Account"
| extend TargetGroup = tostring(AdditionalFields['FROM.GROUP'])
| extend TargetObject = iff(isempty(tostring(AdditionalFields['TARGET_OBJECT.USER'])),tostring(AdditionalFields['TARGET_OBJECT.GROUP']), tostring(AdditionalFields['TARGET_OBJECT.USER']))
| extend TargetType = iff(isempty(tostring(AdditionalFields['TARGET_OBJECT.USER'])), "Security Group", "User Account")
);
let Tier0Groups = datatable(TargetGroup:string)
[
'Enterprise Admins',
'Domain Admins',
'Domain Controllers'
'Administrators',
'Enterprise Key Admins',
'Account Operators',
'Organization Management',
'Backup Operators',
'RTCDomainServerAdmins',
'ENTERPRISE DOMAIN CONTROLLERS',
'Cert Publishers',
'Schema Admins',
'DnsAdmins',
'Exchange Recipient Administrators',
'Replicator',
'Read-Only Domain Controllers',
'Print Operators'
];
Tier0Groups
| join (union Tier0Adds, Tier0Removes) on TargetGroup
| project Timestamp, ActionType, ActivityType,TargetType, ActorUpn=AccountUpn, TargetObject, TargetAccountUpn, TargetGroup
// If you are setting up a detection rule in M365D, you'll need to add ReportId and AccountSid to the projected columns

Analytic Rule Definition

id: 20774145-ef68-42ab-9f3f-19fecbcdbac9
name: Active Directory Sensitive Group Modifications
description: |
  This query shows all modifications to highly sensitive active directory groups (also known as Tier 0). An example of these groups include Domain Admins, Schema Admins and Enterprise Admins.
  More info can be found here:
  https://docs.microsoft.com/security/compass/privileged-access-access-model#evolution-from-the-legacy-ad-tier-model
  https://docs.microsoft.com/windows-server/identity/ad-ds/plan/security-best-practices/appendix-c--protected-accounts-and-groups-in-active-directory
  This advanced hunting query requires Defender for Identity be deployed due to it's reliance on the IdentityDirectoryEvents table.
requiredDataConnectors:
- connectorId: MicrosoftThreatProtection
  dataTypes:
  - IdentityDirectoryEvents
tactics:
- Privilege escalation
- Credential Access
query: |
  // Detects changes in Tier 0 group memberships
  // Command leverages MDI schema
  // Execute from https://security.microsoft.com or through the M365D advanced hunting API
  let Events = materialize (
  IdentityDirectoryEvents
  | where ActionType == 'Group Membership changed'
  | extend ActivityType = iff(isnotempty(tostring(AdditionalFields['TO.GROUP'])),"Added Account", "Removed Account")
  | where isnotempty(AccountSid)
  );
  let Tier0Adds = (
  Events
  | where ActivityType == "Added Account"
  | extend TargetGroup = tostring(AdditionalFields['TO.GROUP'])
  | extend TargetObject = iff(isempty(tostring(AdditionalFields['TARGET_OBJECT.USER'])), tostring(AdditionalFields['TARGET_OBJECT.GROUP']), tostring(AdditionalFields['TARGET_OBJECT.USER']))
  | extend TargetType = iff(isempty(tostring(AdditionalFields['TARGET_OBJECT.USER'])), "Security Group", "User Account")
  //| extend TargetObject = AdditionalFields['TARGET_OBJECT.USER']
  );
  let Tier0Removes = (
  Events
  | where ActivityType == "Removed Account"
  | extend TargetGroup = tostring(AdditionalFields['FROM.GROUP'])
  | extend TargetObject = iff(isempty(tostring(AdditionalFields['TARGET_OBJECT.USER'])),tostring(AdditionalFields['TARGET_OBJECT.GROUP']), tostring(AdditionalFields['TARGET_OBJECT.USER']))
  | extend TargetType = iff(isempty(tostring(AdditionalFields['TARGET_OBJECT.USER'])), "Security Group", "User Account")
  );
  let Tier0Groups = datatable(TargetGroup:string)
  [
  'Enterprise Admins',
  'Domain Admins',
  'Domain Controllers'
  'Administrators',
  'Enterprise Key Admins',
  'Account Operators',
  'Organization Management',
  'Backup Operators',
  'RTCDomainServerAdmins',
  'ENTERPRISE DOMAIN CONTROLLERS',
  'Cert Publishers',
  'Schema Admins',
  'DnsAdmins',
  'Exchange Recipient Administrators',
  'Replicator',
  'Read-Only Domain Controllers',
  'Print Operators'
  ];
  Tier0Groups
  | join (union Tier0Adds, Tier0Removes) on TargetGroup
  | project Timestamp, ActionType, ActivityType,TargetType, ActorUpn=AccountUpn, TargetObject, TargetAccountUpn, TargetGroup
  // If you are setting up

Required Data Sources

Sentinel TableNotes
IdentityDirectoryEventsEnsure this data connector is enabled

MITRE ATT&CK Context

References

False Positive Guidance

Original source: https://github.com/Azure/Azure-Sentinel/blob/main/Hunting Queries/Microsoft 365 Defender/Credential Access/Active Directory Sensitive Group Modifications.yaml