Security Event Suspicious AD Attributes Accessed From Unexpected Source
Query
let query_frequency = 1h;
let query_period = 14d;
let object_threshold = 5;
let _Dictionary =
_GetWatchlist("Value-WindowsEventsDictionary")
| project Value = tostring(Value), Translation
;
let _ExpectedAccounts = toscalar(
_GetWatchlist("Activity-ExpectedSignificantActivity")
| where Activity in ("AccountOperator", "ADObjectAttributeAccess") and not(Notes has "[Group]")
| summarize make_list(ActorPrincipalName)
);
let _ExpectedGroups = toscalar(
_GetWatchlist("Activity-ExpectedSignificantActivity")
| where Activity == "ADObjectAttributeAccess" and Notes has "[Group]"
| summarize make_list(Auxiliar)
);
let _Identities =
IdentityInfo
| where TimeGenerated > ago(query_period) and isnotempty(AccountDomain)
| summarize arg_max(TimeGenerated, *) by AccountObjectId, AccountSID
| project
SubjectUserName = coalesce(extract(@"(?i:CN\=)([^,]+)", 1, OnPremisesDistinguishedName), AccountName),
GroupMembership = array_sort_asc(GroupMembership)
;
SecurityEvent
| where TimeGenerated > ago(2 * query_frequency)
| where EventID == 4662
and (AccessMask in ("0x100", "0x10") or AccessList in ("%%7688", "%%7684") or Properties has_any ("%%7688", "%%7684"))
and not(Account in (_ExpectedAccounts))
and (Properties has_all (
"612cb747-c0e8-4f92-9221-fdd5f15b550d", // unixUserPassword
"6617e4ac-a2f1-43ab-b60c-11fbd1facf05", // ms-PKI-RoamingTimeStamp - Indicates the time of the last synchronization
"b3f93023-9239-4f7c-b99c-6745d87adbc2", // ms-PKI-DPAPIMasterKeys - Stores the DPAPI Master Keys. These symmetric keys encrypt the private keys and are themselves encrypted.
"b7ff5a38-0818-42b0-8110-d3d154c97f24", // ms-PKI-Credential-Roaming-Tokens
"b8dfa744-31dc-4ef1-ac7c-84baf7ef9da7" // ms-PKI-AccountCredentials - Stores certificates, certificate signing requests, private keys and saved passwords.
)
or Properties has_all (
"612cb747-c0e8-4f92-9221-fdd5f15b550d", // unixUserPassword
"bf967a9c-0de6-11d0-a285-00aa003049e2" // Group
)
or Properties has_any (
"7b8b558a-93a5-4af7-adca-c017e67f1057", // ms-DS-Group-Managed-Service-Account
"ea715d30-8f53-40d0-bd1e-6109186d782c", // ms-FVE-RecoveryInformation
"43061ac1-c8ad-4ccc-b785-2bfac20fc60a", // ms-FVE-RecoveryPassword
"800d94d7-b7a1-42a1-b14d-7cae1423d07f", // ms-DS-Allowed-To-Delegate-To
"3f78c3e5-f79a-46bd-a0b8-9d18116ddc79" // ms-DS-Allowed-To-Act-On-Behalf-Of-Other-Identity
))
| summarize
StartTime = min(TimeGenerated),
EndTime = max(TimeGenerated),
EventCount = count(),
ObjectNameCount = count_distinct(ObjectName),
ObjectNamesSample = array_sort_asc(make_set_if(trim(@"[\%\{\}\s]+", ObjectName), isnotempty(ObjectName), 20)),
SubjectLogonId = make_set_if(SubjectLogonId, isnotempty(SubjectLogonId), 20),
Properties = make_set_if(Properties, isnotempty(Properties), 50),
take_any(Activity, OperationType, AccountType, SubjectUserName, AccessList, EventOriginId)
by Computer, Account, AccessMask, ObjectType
| where ObjectNameCount > object_threshold
| where not(ObjectNameCount < 100 and ObjectType has_any ("bf967aba-0de6-11d0-a285-00aa003049e2", "bf967a86-0de6-11d0-a285-00aa003049e2")) // User Computer
| lookup kind=leftouter _Identities on SubjectUserName
| project-away SubjectUserName
| where not(array_length(_ExpectedGroups) > 0 and GroupMembership has_all (_ExpectedGroups))
| extend AccessList = trim(@"\s+", AccessList)
| lookup kind=leftouter (
_Dictionary
| project
AccessList = Value,
AccessListTranslated = Translation
) on AccessList
| extend ObjectType = trim(@"[\%\{\}\s]+", ObjectType)
| lookup kind=leftouter (
_Dictionary
| project
ObjectType = Value,
ObjectTypeTranslated = Translation
) on ObjectType
| mv-expand Properties to typeof(string)
| mv-expand PropertiesKey = split(translate("{}", "", trim(@"\s+", replace_regex(Properties, @"\s+", " "))), " ") to typeof(string)
| lookup kind=leftouter (
_Dictionary
| project
PropertiesKey = Value,
PropertiesKeyTranslated = Translation
)
on PropertiesKey
| summarize
take_any(*),
PropertiesTranslated = strcat_array(make_list(iff(isnotempty(PropertiesKeyTranslated), PropertiesKeyTranslated, PropertiesKey)), " | ")
by EventOriginId
| as hint.materialized=true _Auxiliar
| mv-expand SubjectLogonId to typeof(string)
| lookup kind=leftouter (
SecurityEvent
| where TimeGenerated > ago(query_frequency + 1h)
| where EventID == 4624 and Account in (toscalar(_Auxiliar | summarize make_list(Account)))
| project Computer, Account, TargetLogonId, IpAddress
)
on Computer, Account, $left.SubjectLogonId == $right.TargetLogonId
| summarize
SubjectLogonIds = make_set(SubjectLogonId),
IpAddresses = make_set_if(IpAddress, isnotempty(IpAddress)),
take_any(*)
by EventOriginId
| summarize
StartTime = min(StartTime),
EndTime = max(EndTime),
Computers = make_set(Computer),
SubjectLogonIds = make_set(SubjectLogonIds),
IpAddresses = make_set(IpAddress),
EventCount = sum(EventCount),
AccessLists = make_set(AccessList),
AccessListsTranslated = make_set(AccessListTranslated),
ObjectTypes = make_set(ObjectType),
ObjectTypesTranslated = array_sort_asc(make_set(ObjectTypeTranslated)),
ObjectNameCount = sum(ObjectNameCount),
ObjectNamesSample = make_set(ObjectNamesSample),
Properties = make_set(Properties),
PropertiesTranslated = make_set(PropertiesTranslated),
take_any(AccountType, Activity, OperationType, GroupMembership)
by Account
| where EndTime > ago(query_frequency)
| where not(array_length(ObjectTypes) == 1 and ObjectTypes has_any ("bf967aba-0de6-11d0-a285-00aa003049e2", "bf967a86-0de6-11d0-a285-00aa003049e2", "bf967a9c-0de6-11d0-a285-00aa003049e2")) // User Computer Group
| project
StartTime,
EndTime,
Computers,
Account,
AccountType,
SubjectLogonIds,
IpAddress = tostring(IpAddresses[0]),
IpAddresses,
Activity,
EventCount,
OperationType,
AccessLists,
AccessListsTranslated,
ObjectTypes,
ObjectTypesTranslated,
ObjectNameCount,
ObjectNameEventCountRatio = round(ObjectNameCount / toreal(EventCount), 2),
ObjectNamesSample,
Properties,
PropertiesTranslated,
AccountGroupMembership = GroupMembershipExplanation
This KQL (Kusto Query Language) query is designed to analyze security events, specifically looking for unusual or potentially suspicious activities related to Active Directory object access. Here's a simplified breakdown of what the query does:
-
Setup and Configuration:
- It defines some parameters like
query_frequency,query_period, andobject_thresholdto control the time frame and thresholds for the analysis. - It retrieves data from watchlists to identify expected accounts and groups that are allowed to perform significant activities.
- It defines some parameters like
-
Data Preparation:
- It gathers identity information from the
IdentityInfotable to map user accounts and their group memberships. - It creates a dictionary from a watchlist to translate certain event values into more understandable terms.
- It gathers identity information from the
-
Event Filtering:
- The query focuses on security events with
EventID4662, which indicates an operation was performed on an Active Directory object. - It filters out events involving expected accounts and checks for specific access properties that might indicate sensitive operations.
- The query focuses on security events with
-
Event Aggregation:
- It summarizes the events by counting occurrences, distinct object names, and other attributes.
- It filters out events that do not meet certain criteria, such as having too few distinct object names.
-
Data Enrichment:
- It enriches the data by looking up additional information about user identities and translating technical codes into human-readable terms using the dictionary.
-
Final Aggregation and Output:
- The query aggregates the results by account, summarizing various attributes like computers involved, IP addresses, access lists, object types, and properties.
- It calculates a ratio of distinct object names to event count to help identify unusual patterns.
- Finally, it projects the relevant fields for output, providing a concise summary of potentially suspicious activities.
In essence, this query is designed to detect and summarize unusual access patterns to Active Directory objects, helping security analysts identify potential security incidents.
Details

Jose Sebastián Canós
Released: December 3, 2025
Tables
_GetWatchlistIdentityInfoSecurityEvent
Keywords
SecurityEventIdentityInfoAccountComputerGroupMembershipPropertiesActivityOperationTypeEventIDAccessMaskObjectTypeEventOriginIdLogonIdIpAddress
Operators
letprojecttostringtoscalarwhereinnothassummarizemake_listarg_maxcoalesceextractagoisnotemptyarray_sort_aschas_anyhas_allcountcount_distinctmake_set_iftrimtake_anybylookupkindleftouterproject-awayextendreplace_regexmv-expandsplitiffstrcat_arrayashint.materializedtotypeofmake_setarray_lengthroundtoreal