diff --git a/detections/application/windows_ad_dangerous_group_acl_modification.yml b/detections/application/windows_ad_dangerous_group_acl_modification.yml new file mode 100644 index 0000000000..6ac006d500 --- /dev/null +++ b/detections/application/windows_ad_dangerous_group_acl_modification.yml @@ -0,0 +1,82 @@ +name: Windows AD Dangerous Group ACL Modification +id: 59b0fc85-7a0d-4585-97ec-06a382801990 +version: 1 +date: '2023-11-13' +author: Dean Luxton +status: production +type: TTP +data_source: +- Windows Security 5136 +description: Group ACL modification event with potentially dangerous permissions applied. +search: '`wineventlog_security` EventCode=5136 ObjectClass=group + | eval old_value=if(OperationType=="%%14675",AttributeValue,null), new_value=if(OperationType=="%%14674",AttributeValue,null) + | stats min(_time) as _time values(old_value) as old_value values(new_value) as new_value values(OperationType) as OperationType by ObjectClass ObjectDN OpCorrelationID src_user SubjectLogonId + | rex field=old_value max_match=10000 "\((?P.*?)\)" + | rex field=new_value max_match=10000 "\((?P.*?)\)" + | mvexpand new_ace + | where NOT new_ace IN (old_values) + | rex field=new_ace "(?P.*?);(?P.*?);(?P.*?);(?P.*?);(?P.*?);(?P.*?)$" + | rex max_match=100 field=aceAccessRights "(?P[A-Z]{2})" + | rex max_match=100 field=aceFlags "(?P[A-Z]{2})" + | lookup ace_control_access_rights_lookup.csv control_access_rights_guid as aceObjectGuid OUTPUT control_access_rights_value as ControlAccessRights + | lookup ace_access_rights_lookup.csv access_rights_string as AccessRights OUTPUT access_rights_value + | lookup ace_type_lookup.csv ace_type_string as aceType OUTPUT ace_type_value as aceType + | lookup ace_flag_lookup.csv flag_string as aceFlags OUTPUT flag_value as ace_flag_value + ``` Optional SID resolution lookups + | lookup identity_lookup_expanded objectSid as aceSid OUTPUT downLevelDomainName as user + | lookup admon_groups_def objectSid as aceSid OUTPUT cn as group ``` + | lookup builtin_groups_lookup.csv builtin_group_string as aceSid OUTPUT builtin_group_name as builtin_group + | eval aceAccessRights=if(aceAccessRights="CCDCLCSWRPWPDTLOCRSDRCWDWO","Full control",'access_rights_value'), aceFlags=coalesce(ace_flag_value,"This object only"), user=coalesce(user, group, builtin_group, aceSid), ControlAccessRights=coalesce(ControlAccessRights,aceObjectGuid) + | stats values(aceType) as aceType values(aceFlags) as aceFlags(inheritance) values(ControlAccessRights) as ControlAccessRights values(aceAccessRights) as aceAccessRights values(aceInheritedTypeGuid) as inheritedTypeGuid values(new_ace) as new_ace by _time ObjectClass ObjectDN src_user SubjectLogonId user OpCorrelationID + | search aceAccessRights IN ("Full control","All validated writes","All extended rights","Modify permissions","Modify owner","Write all properties") + | eval ControlAccessRights=if(mvcount(ControlAccessRights)=1 AND ControlAccessRights="","All rights",'ControlAccessRights') + | `windows_ad_dangerous_group_acl_modification_filter`' +how_to_implement: See link in references for how to configure logging for these eventcodes. Include lookups for SID resolution if evt_resolve_ad_obj is set to 0. +known_false_positives: Unknown +references: +- https://learn.microsoft.com/en-us/windows/win32/secauthz/ace-strings +- https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-adts/1522b774-6464-41a3-87a5-1e5633c3fbbb +- https://trustedsec.com/blog/a-hitchhackers-guide-to-dacl-based-detections-part-1-a +tags: + analytic_story: + - Sneaky Active Directory Persistence Tricks + asset_type: Endpoint + confidence: 100 + impact: 100 + message: $src_user$ has removed $user$ $aceAccessRights$ ACL rights to domain root $ObjectDN$ + mitre_attack_id: + - T1484 + - T1222 + - T1222.001 + observable: + - name: user + type: User + role: + - Victim + - name: src_user + type: User + role: + - Victim + product: + - Splunk Enterprise + - Splunk Enterprise Security + - Splunk Cloud + risk_score: 100 + required_fields: + - _time + - OperationType + - ObjectDN + - OpCorrelationID + - src_user + - AttributeLDAPDisplayName + - AttributeValue + - ObjectClass + - SubjectLogonId + - DSName + security_domain: endpoint +tests: + - name: True Positive Test + attack_data: + - data: https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1484/DCShadowPermissions/windows-security-xml.log + source: XmlWinEventLog:Security + sourcetype: xmlwineventlog \ No newline at end of file diff --git a/detections/application/windows_ad_domain_root_acl_deletion.yml b/detections/application/windows_ad_domain_root_acl_deletion.yml new file mode 100644 index 0000000000..353b3783f2 --- /dev/null +++ b/detections/application/windows_ad_domain_root_acl_deletion.yml @@ -0,0 +1,81 @@ +name: Windows AD Domain Root ACL Deletion +id: 3cb56e57-5642-4638-907f-8dfde9afb889 +version: 1 +date: '2023-11-13' +author: Dean Luxton +status: production +type: TTP +data_source: +- Windows Security 5136 +description: ACL deletion performed on the domain root object, significant AD change with high impact. Following MS guidance all changes at this level should be reviewed. Drill into the logonID within EventCode 4624 for information on the source device during triage. +search: '`wineventlog_security` EventCode=5136 ObjectClass=domainDNS + | eval old_value=if(OperationType=="%%14675",AttributeValue,null), new_value=if(OperationType=="%%14674",AttributeValue,null) + | stats min(_time) as _time values(old_value) as old_value values(new_value) as new_value values(OperationType) as OperationType by ObjectClass ObjectDN OpCorrelationID src_user SubjectLogonId + | rex field=old_value max_match=10000 "\((?P.*?)\)" + | rex field=new_value max_match=10000 "\((?P.*?)\)" + | mvexpand old_values + | where NOT old_values IN (new_values) + | rex field=old_values "(?P.*?);(?P.*?);(?P.*?);(?P.*?);;(?P.*?)$" + | rex max_match=100 field=aceAccessRights "(?P[A-Z]{2})" + | rex max_match=100 field=aceFlags "(?P[A-Z]{2})" + | lookup ace_control_access_rights_lookup.csv control_access_rights_guid as aceObjectGuid OUTPUT control_access_rights_value as ControlAccessRights + | lookup ace_access_rights_lookup.csv access_rights_string as AccessRights OUTPUT access_rights_value + | lookup ace_type_lookup.csv ace_type_string as aceType OUTPUT ace_type_value + | lookup ace_flag_lookup.csv flag_string as aceFlags OUTPUT flag_value as ace_flag_value + ``` Optional SID resolution lookups + | lookup identity_lookup_expanded objectSid as aceSid OUTPUT downLevelDomainName as user + | lookup admon_groups_def objectSid as aceSid OUTPUT cn as group ``` + | lookup builtin_groups_lookup.csv builtin_group_string as aceSid OUTPUT builtin_group_name as builtin_group + | eval aceAccessRights=if(aceAccessRights="CCDCLCSWRPWPDTLOCRSDRCWDWO","Full control",'access_rights_value'), aceType=ace_type_value, aceFlags=coalesce(ace_flag_value,"This object only"), aceControlAccessRights=ControlAccessRights, user=coalesce(user, group, builtin_group, aceSid) + | stats values(aceType) as aceType values(aceFlags) as aceFlags(inheritance) values(aceControlAccessRights) as aceControlAccessRights values(aceAccessRights) as aceAccessRights values(old_values) as old_values by _time ObjectClass ObjectDN src_user SubjectLogonId user OpCorrelationID + | eval ControlAccessRights=if(mvcount(ControlAccessRights)=1 AND ControlAccessRights="","All rights",'ControlAccessRights') + | `windows_ad_domain_root_acl_deletion_filter`' +how_to_implement: See link in references for how to configure logging for these eventcodes. Include lookups for SID resolution if evt_resolve_ad_obj is set to 0. +known_false_positives: Unknown +references: +- https://learn.microsoft.com/en-us/windows/win32/secauthz/ace-strings +- https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-adts/1522b774-6464-41a3-87a5-1e5633c3fbbb +- https://trustedsec.com/blog/a-hitchhackers-guide-to-dacl-based-detections-part-1-a +tags: + analytic_story: + - Sneaky Active Directory Persistence Tricks + asset_type: Endpoint + confidence: 100 + impact: 100 + message: $src_user$ has removed $user$ $aceAccessRights$ ACL rights to domain root $ObjectDN$ + mitre_attack_id: + - T1484 + - T1222 + - T1222.001 + observable: + - name: user + type: User + role: + - Victim + - name: src_user + type: User + role: + - Victim + product: + - Splunk Enterprise + - Splunk Enterprise Security + - Splunk Cloud + risk_score: 100 + required_fields: + - _time + - OperationType + - ObjectDN + - OpCorrelationID + - src_user + - AttributeLDAPDisplayName + - AttributeValue + - ObjectClass + - SubjectLogonId + - DSName + security_domain: endpoint +tests: + - name: True Positive Test + attack_data: + - data: https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1484/DCShadowPermissions/windows-security-xml.log + source: XmlWinEventLog:Security + sourcetype: xmlwineventlog diff --git a/detections/application/windows_ad_object_owner_updated.yml b/detections/application/windows_ad_object_owner_updated.yml new file mode 100644 index 0000000000..d087a45910 --- /dev/null +++ b/detections/application/windows_ad_object_owner_updated.yml @@ -0,0 +1,76 @@ +name: Windows AD Object Owner Updated +id: 4af01f6b-d8d4-4f96-8635-758a01557130 +version: 1 +date: '2023-11-13' +author: Dean Luxton +status: production +type: TTP +data_source: +- Windows Security 5136 +description: AD Object Owner Updated +search: ' `wineventlog_security` EventCode=5136 + | eval old_value=if(OperationType=="%%14675",AttributeValue,null), new_value=if(OperationType=="%%14674",AttributeValue,null) + | stats min(_time) as _time values(old_value) as old_value values(new_value) as new_value values(OperationType) as OperationType by ObjectClass ObjectDN OpCorrelationID src_user SubjectLogonId DSName + | rex field=old_value "O:(?P.*?)G:" + | rex field=new_value "O:(?P.*?)G:" + | where old_owner!=new_owner + ``` optional SID resolution lookups + | lookup identity_lookup_expanded objectSid as new_owner OUTPUT downLevelDomainName as new_owner_user + | lookup admon_groups_def objectSid as new_owner OUTPUT cn as new_owner_group + | lookup identity_lookup_expanded objectSid as old_owner OUTPUT downLevelDomainName as old_owner_user + | lookup admon_groups_def objectSid as old_owner OUTPUT cn as old_owner_group + ``` + | lookup builtin_groups_lookup.csv builtin_group_string as new_owner_group OUTPUT builtin_group_name as new_owner_group_builtin_group + | lookup builtin_groups_lookup.csv builtin_group_string as old_owner OUTPUT builtin_group_name as old_owner_group_builtin_group + | eval user=coalesce(new_owner_user, new_owner_group, new_owner_group_builtin_group, new_owner), previousOwner=coalesce(old_owner_user, old_owner_group, old_owner_group_builtin_group, old_owner) + | stats values(previousOwner) as previousOwner values(user) as user values(SubjectLogonId) as SubjectLogonId by _time ObjectClass ObjectDN src_user OpCorrelationID DSName + | `windows_ad_object_owner_updated_filter`' +how_to_implement: This analytic leverages event code 5136, see documentation in references on how to enable logging. +known_false_positives: Unknown +references: +- https://learn.microsoft.com/en-us/windows/win32/secauthz/ace-strings +- https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-adts/1522b774-6464-41a3-87a5-1e5633c3fbbb +- https://trustedsec.com/blog/a-hitchhackers-guide-to-dacl-based-detections-part-1-a +tags: + analytic_story: + - Sneaky Active Directory Persistence Tricks + asset_type: Endpoint + confidence: 100 + impact: 100 + message: $src_user$ has removed $user$ $aceAccessRights$ ACL rights to domain root $ObjectDN$ + mitre_attack_id: + - T1484 + - T1222 + - T1222.001 + observable: + - name: user + type: User + role: + - Victim + - name: src_user + type: User + role: + - Victim + product: + - Splunk Enterprise + - Splunk Enterprise Security + - Splunk Cloud + risk_score: 100 + required_fields: + - _time + - OperationType + - ObjectDN + - OpCorrelationID + - src_user + - AttributeLDAPDisplayName + - AttributeValue + - ObjectClass + - SubjectLogonId + - DSName + security_domain: endpoint +tests: + - name: True Positive Test + attack_data: + - data: https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1484/DCShadowPermissions/windows-security-xml.log + source: XmlWinEventLog:Security + sourcetype: xmlwineventlog \ No newline at end of file diff --git a/detections/application/windows_ad_suspicious_attribute_modification.yml b/detections/application/windows_ad_suspicious_attribute_modification.yml new file mode 100644 index 0000000000..f8d3497e5f --- /dev/null +++ b/detections/application/windows_ad_suspicious_attribute_modification.yml @@ -0,0 +1,73 @@ +name: Windows AD Suspicious Attribute Modification +id: 5682052e-ce55-4f9f-8d28-59191420b7e0 +version: 1 +date: '2023-11-13' +author: Dean Luxton +status: production +type: TTP +data_source: +- Windows Security 5136 +description: Suspicious AD Attribute Modification +search: ' `wineventlog_security` EventCode=5136 EventCode=5136 AttributeLDAPDisplayName IN ("msDS-AllowedToDelegateTo","msDS-AllowedToActOnBehalfOfOtherIdentity","msDS-KeyCredentialLink","scriptPath","msTSInitialProgram") OperationType=%%14674 + | table _time ObjectClass ObjectDN OpCorrelationID src_user SubjectLogonId DSName AttributeValue AttributeLDAPDisplayName + | rename SubjectLogonId as TargetLogonId, src_user as initiator, DSRGetChanges_user as target_user, _time as eventTime + | appendpipe + | [| map search="search `wineventlog_security` EventCode=4624 TargetLogonId=$TargetLogonId$"] + | stats min(eventTime) as _time values(initiator) as src_user, values(DSName) as targetDomain, values(ObjectDN) as ObjectDN, values(ObjectClass) as ObjectClass, values(src_category) as src_category, values(src_ip) as src_ip values(LogonType) as LogonType values(AttributeValue) as AttributeValue values(AttributeLDAPDisplayName) as AttributeLDAPDisplayName by TargetLogonId + | rex field=ObjectDN "^CN=(?P.*?),[A-Z]{2}\=" + | eval dest=if(ObjectClass="computer",cn,null), user=if(ObjectClass="user",cn,null) + | fields - cn + | `windows_ad_suspicious_attribute_modification_filter`' +how_to_implement: This analytic leverages event code 5136, see documentation in references on how to enable logging. +known_false_positives: Unknown +references: +- https://learn.microsoft.com/en-us/windows/win32/secauthz/ace-strings +- https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-adts/1522b774-6464-41a3-87a5-1e5633c3fbbb +- https://trustedsec.com/blog/a-hitchhackers-guide-to-dacl-based-detections-part-1-a +tags: + analytic_story: + - Sneaky Active Directory Persistence Tricks + asset_type: Endpoint + confidence: 100 + impact: 100 + message: $src_user$ has removed $user$ $aceAccessRights$ ACL rights to domain root $ObjectDN$ + mitre_attack_id: + - T1484 + - T1222 + - T1222.001 + observable: + - name: user + type: User + role: + - Victim + - name: src_user + type: User + role: + - Victim + - name: dest + type: Hostname + role: + - Victim + product: + - Splunk Enterprise + - Splunk Enterprise Security + - Splunk Cloud + risk_score: 100 + required_fields: + - _time + - OperationType + - ObjectDN + - OpCorrelationID + - src_user + - AttributeLDAPDisplayName + - AttributeValue + - ObjectClass + - SubjectLogonId + - DSName + security_domain: endpoint +tests: + - name: True Positive Test + attack_data: + - data: https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1484/DCShadowPermissions/windows-security-xml.log + source: XmlWinEventLog:Security + sourcetype: xmlwineventlog diff --git a/dist/DA-ESS-ContentUpdate/default/transforms.conf b/dist/DA-ESS-ContentUpdate/default/transforms.conf index d519127145..c1083d68a0 100644 --- a/dist/DA-ESS-ContentUpdate/default/transforms.conf +++ b/dist/DA-ESS-ContentUpdate/default/transforms.conf @@ -100,6 +100,10 @@ default_match = false match_type = WILDCARD(domain) min_matches = 1 +[builtin_groups_lookup] +filename = builtin_groups_lookup.csv +# description = A lookup file that will contain translations for builtin AD group strings + [cloud_instances_enough_data] collection = cloud_instances_enough_data external_type = kvstore diff --git a/lookups/builtin_groups_lookup.csv b/lookups/builtin_groups_lookup.csv new file mode 100644 index 0000000000..327669a496 --- /dev/null +++ b/lookups/builtin_groups_lookup.csv @@ -0,0 +1,39 @@ +builtin_group_string,builtin_group_name +AO,Account operators +RU,Alias to allow previous Windows 2000 +AN,Anonymous logon +AU,Authenticated users +BA,Built-in administrators +BG,Built-in guests +BO,Backup operators +BU,Built-in users +CA,Certificate server administrators +CG,Creator group +CO,Creator owner +DA,Domain administrators +DC,Domain computers +DD,Domain controllers +DG,Domain guests +DU,Domain users +EA,Enterprise administrators +ED,Enterprise domain controllers +WD,Everyone +PA,Group Policy administrators +IU,Interactively logged-on user +LA,Local administrator +LG,Local guest +LS,Local service account +SY,Local system +NU,Network sign-in user +NO,Network configuration operators +NS,Network service account +PO,Printer operators +PS,Personal self +PU,Power users +RS,RAS servers group +RD,Terminal server users +RE,Replicator +RC,Restricted code +SA,Schema administrators +SO,Server operators +SU,Service sign-in user \ No newline at end of file diff --git a/lookups/builtin_groups_lookup.yml b/lookups/builtin_groups_lookup.yml new file mode 100644 index 0000000000..cc4959d3c4 --- /dev/null +++ b/lookups/builtin_groups_lookup.yml @@ -0,0 +1,3 @@ +description: A lookup file that will contain translations for builtin AD group strings +filename: builtin_groups_lookup.csv +name: builtin_groups_lookup \ No newline at end of file