← Back to SOC feed Coverage →

Account added and removed from privileged groups

kql LOW Azure-Sentinel
T1098T1078
SecurityEventWindowsEvent
microsoftofficial
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-04-19T09:00:00Z · Confidence: medium

Hunt Hypothesis

Accounts are being added to and then rapidly removed from privileged groups, indicating potential lateral movement or privilege escalation by an adversary. SOC teams should proactively hunt for this behavior in Azure Sentinel to identify and mitigate early-stage compromise attempts that may evade standard detection mechanisms.

KQL Query

let WellKnownLocalSID = "S-1-5-32-5[0-9][0-9]$";
let WellKnownGroupSID = "S-1-5-21-[0-9]*-[0-9]*-[0-9]*-5[0-9][0-9]$|S-1-5-21-[0-9]*-[0-9]*-[0-9]*-1102$|S-1-5-21-[0-9]*-[0-9]*-[0-9]*-1103$|S-1-5-21-[0-9]*-[0-9]*-[0-9]*-498$|S-1-5-21-[0-9]*-[0-9]*-[0-9]*-1000$";
let AC_Add =
(union isfuzzy=true
(SecurityEvent
// Event ID related to member addition.
| where EventID in (4728, 4732,4756)
| where TargetSid matches regex WellKnownLocalSID or TargetSid matches regex WellKnownGroupSID
| parse EventData with * '"MemberName">' * '=' AccountAdded ",OU" *
| where isnotempty(AccountAdded)
| extend GroupAddedTo = TargetUserName, AddingAccount = Account
| extend  AccountAdded_GroupAddedTo_AddingAccount = strcat(AccountAdded, "||", GroupAddedTo, "||", AddingAccount )
| project AccountAdded_GroupAddedTo_AddingAccount, AccountAddedTime = TimeGenerated
),
(WindowsEvent
// Event ID related to member addition.
| where EventID in (4728, 4732,4756)
| extend TargetSid = tostring(EventData.TargetSid)
| where TargetSid matches regex WellKnownLocalSID or TargetSid matches regex WellKnownGroupSID
| parse EventData.MemberName with * '"MemberName">' * '=' AccountAdded ",OU" *
| where isnotempty(AccountAdded)
| extend TargetUserName = tostring(EventData.TargetUserName)
| extend AddingAccount =  strcat(tostring(EventData.SubjectDomainName),"\\", tostring(EventData.SubjectUserName))
| extend GroupAddedTo = TargetUserName
| extend  AccountAdded_GroupAddedTo_AddingAccount = strcat(AccountAdded, "||", GroupAddedTo, "||", AddingAccount )
| project AccountAdded_GroupAddedTo_AddingAccount, AccountAddedTime = TimeGenerated
)
);
let AC_Remove =
( union isfuzzy=true
(SecurityEvent
// Event IDs related to member removal.
| where EventID in (4729,4733,4757)
| where TargetSid matches regex WellKnownLocalSID or TargetSid matches regex WellKnownGroupSID
| parse EventData with * '"MemberName">' * '=' AccountRemoved ",OU" *
| where isnotempty(AccountRemoved)
| extend GroupRemovedFrom = TargetUserName, RemovingAccount = Account
| extend AccountRemoved_GroupRemovedFrom_RemovingAccount = strcat(AccountRemoved, "||", GroupRemovedFrom, "||", RemovingAccount)
| project AccountRemoved_GroupRemovedFrom_RemovingAccount, AccountRemovedTime = TimeGenerated, Computer, AccountRemoved = tolower(AccountRemoved),
RemovingAccount, RemovingAccountLogonId = SubjectLogonId, GroupRemovedFrom = TargetUserName, TargetDomainName
),
(WindowsEvent
// Event IDs related to member removal.
| where EventID in (4729,4733,4757)
| extend TargetSid = tostring(EventData.TargetSid)
| where TargetSid matches regex WellKnownLocalSID or TargetSid matches regex WellKnownGroupSID
| parse EventData.MemberName with * '"MemberName">' * '=' AccountRemoved ",OU" *
| where isnotempty(AccountRemoved)
| extend TargetUserName = tostring(EventData.TargetUserName)
| extend RemovingAccount =  strcat(tostring(EventData.SubjectDomainName),"\\", tostring(EventData.SubjectUserName))
| extend GroupRemovedFrom = TargetUserName
| extend AccountRemoved_GroupRemovedFrom_RemovingAccount = strcat(AccountRemoved, "||", GroupRemovedFrom, "||", RemovingAccount)
| extend RemovedAccountLogonId= tostring(EventData.SubjectLogonId)
| extend TargetDomainName = tostring(EventData.TargetDomainName)
| project AccountRemoved_GroupRemovedFrom_RemovingAccount, AccountRemovedTime = TimeGenerated, Computer, AccountRemoved = tolower(AccountRemoved),
RemovingAccount, RemovedAccountLogonId, GroupRemovedFrom = TargetUserName, TargetDomainName
));
AC_Add
| join kind = inner AC_Remove 
on $left.AccountAdded_GroupAddedTo_AddingAccount == $right.AccountRemoved_GroupRemovedFrom_RemovingAccount
| extend DurationinSecondAfter_Removed = datetime_diff ('second', AccountRemovedTime, AccountAddedTime)
| where DurationinSecondAfter_Removed > 0
| extend HostName = tostring(split(Computer, ".")[0]), DomainIndex = toint(indexof(Computer, '.'))
| extend HostNameDomain = iff(DomainIndex != -1, substring(Computer, DomainIndex + 1), Computer)
| extend RemovedAccountName = tostring(split(AccountRemoved, @"\")[1]), RemovedAccountNTDomain = tostring(split(AccountRemoved, @"\")[0])
| extend RemovingAccountName = tostring(split(RemovingAccount, @"\")[1]), RemovingAccountNTDomain = tostring(split(RemovingAccount, @"\")[0])
| project-away DomainIndex

Analytic Rule Definition

id: 7efc75ce-e2a4-400f-a8b1-283d3b0f2c60
name: Account added and removed from privileged groups
description: |
  'Identifies accounts that are added to a privileged group and then quickly removed, which could be a sign of compromise.'
severity: Low
requiredDataConnectors:
  - connectorId: SecurityEvents
    dataTypes:
      - SecurityEvent
  - connectorId: WindowsSecurityEvents
    dataTypes:
      - SecurityEvent
  - connectorId: WindowsForwardedEvents
    dataTypes:
      - WindowsEvent
queryFrequency: 1d
queryPeriod: 1d
triggerOperator: gt
triggerThreshold: 0
tactics:
  - Persistence
  - PrivilegeEscalation
relevantTechniques:
  - T1098
  - T1078
query: |
  let WellKnownLocalSID = "S-1-5-32-5[0-9][0-9]$";
  let WellKnownGroupSID = "S-1-5-21-[0-9]*-[0-9]*-[0-9]*-5[0-9][0-9]$|S-1-5-21-[0-9]*-[0-9]*-[0-9]*-1102$|S-1-5-21-[0-9]*-[0-9]*-[0-9]*-1103$|S-1-5-21-[0-9]*-[0-9]*-[0-9]*-498$|S-1-5-21-[0-9]*-[0-9]*-[0-9]*-1000$";
  let AC_Add =
  (union isfuzzy=true
  (SecurityEvent
  // Event ID related to member addition.
  | where EventID in (4728, 4732,4756)
  | where TargetSid matches regex WellKnownLocalSID or TargetSid matches regex WellKnownGroupSID
  | parse EventData with * '"MemberName">' * '=' AccountAdded ",OU" *
  | where isnotempty(AccountAdded)
  | extend GroupAddedTo = TargetUserName, AddingAccount = Account
  | extend  AccountAdded_GroupAddedTo_AddingAccount = strcat(AccountAdded, "||", GroupAddedTo, "||", AddingAccount )
  | project AccountAdded_GroupAddedTo_AddingAccount, AccountAddedTime = TimeGenerated
  ),
  (WindowsEvent
  // Event ID related to member addition.
  | where EventID in (4728, 4732,4756)
  | extend TargetSid = tostring(EventData.TargetSid)
  | where TargetSid matches regex WellKnownLocalSID or TargetSid matches regex WellKnownGroupSID
  | parse EventData.MemberName with * '"MemberName">' * '=' AccountAdded ",OU" *
  | where isnotempty(AccountAdded)
  | extend TargetUserName = tostring(EventData.TargetUserName)
  | extend AddingAccount =  strcat(tostring(EventData.SubjectDomainName),"\\", tostring(EventData.SubjectUserName))
  | extend GroupAddedTo = TargetUserName
  | extend  AccountAdded_GroupAddedTo_AddingAccount = strcat(AccountAdded, "||", GroupAddedTo, "||", AddingAccount )
  | project AccountAdded_GroupAddedTo_AddingAccount, AccountAddedTime = TimeGenerated
  )
  );
  let AC_Remove =
  ( union isfuzzy=true
  (SecurityEvent
  // Event IDs related to member removal.
  | where EventID in (4729,4733,4757)
  | where TargetSid matches regex WellKnownLocalSID or TargetSid matches regex WellKnownGroupSID
  | parse EventData with * '"MemberName">' * '=' AccountRemoved ",OU" *
  | where isnotempty(AccountRemoved)
  | extend GroupRemovedFrom = TargetUserName, RemovingAccount = Account
  | extend AccountRemoved_GroupRemovedFrom_RemovingAccount = strcat(AccountRemoved, "||", GroupRemovedFrom, "||", RemovingAccount)
  | project AccountRemoved_GroupRemovedFrom_RemovingAccount, AccountRemovedTime = TimeGenerated, Computer, Account

Required Data Sources

Sentinel TableNotes
SecurityEventEnsure this data connector is enabled
WindowsEventEnsure this data connector is enabled

MITRE ATT&CK Context

References

False Positive Guidance

Original source: https://github.com/Azure/Azure-Sentinel/blob/main/Detections/SecurityEvent/UserAccountAdd-Removed.yaml