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.