Query Details

Security Event Account Removed From Monitored AD Group

Query

let query_frequency = 1h;
let query_period = 14d;
let wait_for_addition = 30m;
let _DomainGroups =
    _GetWatchlist("SID-AuditDomainGroups")
    | where Notes has "[Removal]"
    | project GroupSID, SAMAccountName, Auditor, Severity, Notes
;
SecurityEvent
| where TimeGenerated > ago(query_frequency + wait_for_addition)
| where EventID in (4728, 4732, 4756, 4729, 4733, 4757)
| lookup kind=inner _DomainGroups on $left.TargetSid == $right.GroupSID
| extend MemberAccount = extract("[Cc][Nn]=([^,]*).*$", 1, MemberName)
| summarize
    GroupAddition_TimeGenerated = maxif(TimeGenerated, EventID in (4728, 4732, 4756)),
    GroupRemoval_TimeGenerated = maxif(TimeGenerated, EventID in (4729, 4733, 4757)),
    arg_max(TimeGenerated, *)
    by MemberSid, MemberAccount
| where GroupRemoval_TimeGenerated between (ago(query_frequency + wait_for_addition) .. ago(wait_for_addition))
| where not(isnotempty(GroupAddition_TimeGenerated) and GroupAddition_TimeGenerated > GroupRemoval_TimeGenerated)
| join kind=leftouter (
    SecurityEvent
    | where TimeGenerated > ago(query_period)
    | where EventID in (4722, 4725, 4726)
    | summarize
        AccountEnable_TimeGenerated = maxif(TimeGenerated, EventID == 4722),
        AccountDisable_TimeGenerated = maxif(TimeGenerated, EventID == 4725),
        AccountDeletion_TimeGenerated = maxif(TimeGenerated, EventID == 4726)
        by TargetSid
    ) on $left.MemberSid == $right.TargetSid
// Custom exclusions
| where isempty(AccountDeletion_TimeGenerated)
| where not(isnotempty(AccountDisable_TimeGenerated) and isnotempty(AccountEnable_TimeGenerated) and AccountDisable_TimeGenerated > GroupRemoval_TimeGenerated and AccountDisable_TimeGenerated > AccountEnable_TimeGenerated)
| where not(isnotempty(AccountDisable_TimeGenerated) and isempty(AccountEnable_TimeGenerated) and AccountDisable_TimeGenerated > GroupRemoval_TimeGenerated)
| project
    TimeGenerated,
    Computer,
    ActorAccount = Account,
    Activity = trim_end(@"\.", Activity),
    GroupName = TargetUserName,
    MemberAccount,
    GroupAddition_TimeGenerated,
    GroupRemoval_TimeGenerated,
    AccountEnable_TimeGenerated,
    AccountDisable_TimeGenerated,
    AccountDeletion_TimeGenerated,
    ActorAccountSid = SubjectUserSid,
    GroupSid = TargetSid,
    MemberSid,
    AlertSeverity = Severity,
    Auditor,
    Notes,
    EventData

Explanation

This query is designed to monitor changes in domain groups within a security system. It checks every hour for the past 14 days and waits for 30 minutes before adding new data.

The query first retrieves a list of domain groups that have had a removal event. It then checks the security event logs for specific event IDs that correspond to group addition and removal events.

For each member of the domain groups, the query records the time of the latest group addition and removal events. It then filters out any group removal events that occurred within the last hour to 30 minutes ago.

The query also checks if a group addition event occurred after a group removal event and excludes these cases.

Next, the query joins this data with another set of security event logs that record account enable, disable, and deletion events. It records the latest time of each of these events for each member.

Finally, the query excludes cases where an account was deleted, or an account was disabled after it was removed from a group. It also excludes cases where an account was disabled but not re-enabled after it was removed from a group.

The result is a detailed report of domain group changes, including the time of each event, the computer where the event occurred, the account that performed the action, the group name, the member account, and other relevant information.

Details

Jose Sebastián Canós profile picture

Jose Sebastián Canós

Released: October 31, 2022

Tables

SecurityEvent_GetWatchlist

Keywords

SecurityEvent,TimeGenerated,EventID,DomainGroups,GroupSID,SAMAccountName,Auditor,Severity,Notes,MemberAccount,MemberSid,Computer,Account,Activity,GroupName,ActorAccountSid,GroupSid,AlertSeverity,EventData

Operators

let_GetWatchlist()wherehasprojectSecurityEventinlookupkind=innerextendextractsummarizemaxifarg_maxbybetweennotisnotemptyjoinkind=leftouterisemptytrim_endproject.

Actions