From 179d3e8eb57f6e3afa4d802a7a7accaa4cf8d211 Mon Sep 17 00:00:00 2001 From: Lou Stella Date: Wed, 23 Feb 2022 17:33:46 -0600 Subject: [PATCH 01/11] initial commit --- detections/endpoint/eventvwr_uac_bypass.yml | 1 + .../ssa___windows_eventvwr_uac_bypass.yml | 62 +++++++++++++++++++ detections/endpoint/wsreset_uac_bypass.yml | 1 + ...ssa___windows_eventvwr_uac_bypass.test.yml | 10 +++ .../ssa___windows_wsreset_uac_bypass.test.yml | 11 ++++ 5 files changed, 85 insertions(+) create mode 100644 detections/endpoint/ssa___windows_eventvwr_uac_bypass.yml create mode 100644 tests/endpoint/ssa___windows_eventvwr_uac_bypass.test.yml create mode 100644 tests/endpoint/ssa___windows_wsreset_uac_bypass.test.yml diff --git a/detections/endpoint/eventvwr_uac_bypass.yml b/detections/endpoint/eventvwr_uac_bypass.yml index d86049b7dc..9669c84655 100644 --- a/detections/endpoint/eventvwr_uac_bypass.yml +++ b/detections/endpoint/eventvwr_uac_bypass.yml @@ -40,6 +40,7 @@ tags: analytic_story: - Windows Defense Evasion Tactics - IcedID + - Living Off The Land automated_detection_testing: passed confidence: 100 context: diff --git a/detections/endpoint/ssa___windows_eventvwr_uac_bypass.yml b/detections/endpoint/ssa___windows_eventvwr_uac_bypass.yml new file mode 100644 index 0000000000..c102612000 --- /dev/null +++ b/detections/endpoint/ssa___windows_eventvwr_uac_bypass.yml @@ -0,0 +1,62 @@ +name: Windows Eventvwr UAC Bypass +id: 66adff66-90d9-11ec-aba7-acde48001122 +version: 1 +date: '2022-02-18' +author: Lou Stella, Splunk +type: Anomaly +datamodel: +- Endpoint_Registry +description: The following search identifies Eventvwr bypass by identifying the registry modification into a specific path that eventvwr.msc looks to (but is not valid) upon execution. A successful attack will include a suspicious command to be executed upon eventvwr.msc loading. Upon triage, review the parallel processes that have executed. Identify any additional registry modifications on the endpoint that may look suspicious. Remediate as necessary. +search: '| from read_ssa_enriched_events() | where "Endpoint_Registry" IN (_datamodels) | eval timestamp=parse_long(ucast(map_get(input_event, "_time"), "string", null)), registry_path=lower(ucast(map_get(input_event, "registry_path"), "string", null)), registry_hive=lower(ucast(map_get(input_event, "registry_hive"), "string", null)), registry_value_name=lower(ucast(map_get(input_event, "registry_value_name"), "string", null)), registry_key_name=lower(ucast(map_get(input_event, "parent_process_name"), "string", null)), registry_value_type=lower(ucast(map_get(input_event, "registry_value_type"), "string", null)), registry_value_data=lower(ucast(map_get(input_event, "registry_value_data"), "string", null)), process_guid=lower(ucast(map_get(input_event, "process_guid"), "string", null)), event_id=ucast(map_get(input_event, "event_id"), "int", null) | where registry_path IS NOT NULL AND (like (registry_path, "%mscfile\\shell\\open\\command%")) | eval start_time=timestamp, end_time=timestamp, entities=mvappend(ucast(map_get(input_event, "dest_user_id"), "string", null), ucast(map_get(input_event, "dest_device_id"), "string", null)) | eval body=create_map(["event_id", event_id, "registry_path", registry_path, "registry_hive", registry_hive, "registry_value_name", registry_value_name, "registry_key_name", registry_key_name, "registry_value_type", registry_value_type, "registry_value_data", registry_value_data, "process_guid", process_guid]) | into write_ssa_detected_events();' +how_to_implement: To successfully implement this search you need to be ingesting information on process that include the name of the process responsible for the changes from your endpoints into the `Endpoint_Registry` datamodel. +known_false_positives: UPDATE_KNOWN_FALSE_POSITIVES +references: +- https://blog.malwarebytes.com/malwarebytes-news/2021/02/lazyscripter-from-empire-to-double-rat/ +- https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1548.002/T1548.002.md +- https://attack.mitre.org/techniques/T1548/002 +- https://enigma0x3.net/2016/08/15/fileless-uac-bypass-using-eventvwr-exe-and-registry-hijacking/ +tags: + analytic_story: + - Windows Defense Evasion Tactics + - IcedID + - Living Off The Land + dataset: + - https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1548.002/ssa_eventvwr/windows-sysmon-registry.log + kill_chain_phases: + - Privilege Escalation + mitre_attack_id: + - T1548.002 + - T1548 + product: + - Splunk Behavioral Analytics + required_fields: + - _time + - event_id + - registry_path + - registry_hive + - registry_value_name + - registry_key_name + - registry_value_type + - registry_value_data + - process_guid + security_domain: endpoint + impact: 80 + confidence: 100 + risk_score: 80 + context: + - Source:Endpoint + - Stage:Privilege Escalation + message: Registry values were modified to bypass UAC using Event Viewer on $dest_device_id$ + observable: + - name: dest_device_id + type: Hostname + role: + - Victim + - name: dest_user_id + type: User + role: + - Victim + nist: + - DE.AE + cis20: + - CIS 14 \ No newline at end of file diff --git a/detections/endpoint/wsreset_uac_bypass.yml b/detections/endpoint/wsreset_uac_bypass.yml index b422b0def9..f58b522cbe 100644 --- a/detections/endpoint/wsreset_uac_bypass.yml +++ b/detections/endpoint/wsreset_uac_bypass.yml @@ -36,6 +36,7 @@ references: tags: analytic_story: - Windows Defense Evasion Tactics + - Living Off The Land confidence: 90 context: - Source:Endpoint diff --git a/tests/endpoint/ssa___windows_eventvwr_uac_bypass.test.yml b/tests/endpoint/ssa___windows_eventvwr_uac_bypass.test.yml new file mode 100644 index 0000000000..4ecb8affd8 --- /dev/null +++ b/tests/endpoint/ssa___windows_eventvwr_uac_bypass.test.yml @@ -0,0 +1,10 @@ +name: Windows Eventvwr UAC Bypass Unit Test +tests: +- name: Windows Eventvwr UAC Bypass + file: endpoint/ssa___windows_eventvwr_uac_bypass.yml + pass_condition: '@count_gt(0)' + attack_data: + - file_name: windows-sysmon-registry.log + data: https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1548.002/ssa_eventvwr/windows-sysmon-registry.log + source: XmlWinEventLog:Microsoft-Windows-Sysmon/Operational + sourcetype: xmlwineventlog \ No newline at end of file diff --git a/tests/endpoint/ssa___windows_wsreset_uac_bypass.test.yml b/tests/endpoint/ssa___windows_wsreset_uac_bypass.test.yml new file mode 100644 index 0000000000..61f5eba349 --- /dev/null +++ b/tests/endpoint/ssa___windows_wsreset_uac_bypass.test.yml @@ -0,0 +1,11 @@ +name: Windows WSReset UAC Bypass Unit Test +tests: +- name: Windows WSReset UAC Bypass + file: endpoint/ssa___windows_wsreset_uac_bypass.yml + pass_condition: '@count_gt(0)' + description: Test Windows WSReset UAC Bypass detections + attack_data: + - file_name: hidden_windows-security.log + data: https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1548/uac_bypass/windows-sysmon.log + source: XmlWinEventLog:Microsoft-Windows-Sysmon/Operational + sourcetype: xmlwineventlog \ No newline at end of file From aa03cc011a5abc39f85f160c1ba00efe29c61195 Mon Sep 17 00:00:00 2001 From: Lou Stella Date: Wed, 23 Feb 2022 18:16:40 -0600 Subject: [PATCH 02/11] updates --- detections/endpoint/ssa___windows_eventvwr_uac_bypass.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/detections/endpoint/ssa___windows_eventvwr_uac_bypass.yml b/detections/endpoint/ssa___windows_eventvwr_uac_bypass.yml index c102612000..612b865c32 100644 --- a/detections/endpoint/ssa___windows_eventvwr_uac_bypass.yml +++ b/detections/endpoint/ssa___windows_eventvwr_uac_bypass.yml @@ -7,7 +7,7 @@ type: Anomaly datamodel: - Endpoint_Registry description: The following search identifies Eventvwr bypass by identifying the registry modification into a specific path that eventvwr.msc looks to (but is not valid) upon execution. A successful attack will include a suspicious command to be executed upon eventvwr.msc loading. Upon triage, review the parallel processes that have executed. Identify any additional registry modifications on the endpoint that may look suspicious. Remediate as necessary. -search: '| from read_ssa_enriched_events() | where "Endpoint_Registry" IN (_datamodels) | eval timestamp=parse_long(ucast(map_get(input_event, "_time"), "string", null)), registry_path=lower(ucast(map_get(input_event, "registry_path"), "string", null)), registry_hive=lower(ucast(map_get(input_event, "registry_hive"), "string", null)), registry_value_name=lower(ucast(map_get(input_event, "registry_value_name"), "string", null)), registry_key_name=lower(ucast(map_get(input_event, "parent_process_name"), "string", null)), registry_value_type=lower(ucast(map_get(input_event, "registry_value_type"), "string", null)), registry_value_data=lower(ucast(map_get(input_event, "registry_value_data"), "string", null)), process_guid=lower(ucast(map_get(input_event, "process_guid"), "string", null)), event_id=ucast(map_get(input_event, "event_id"), "int", null) | where registry_path IS NOT NULL AND (like (registry_path, "%mscfile\\shell\\open\\command%")) | eval start_time=timestamp, end_time=timestamp, entities=mvappend(ucast(map_get(input_event, "dest_user_id"), "string", null), ucast(map_get(input_event, "dest_device_id"), "string", null)) | eval body=create_map(["event_id", event_id, "registry_path", registry_path, "registry_hive", registry_hive, "registry_value_name", registry_value_name, "registry_key_name", registry_key_name, "registry_value_type", registry_value_type, "registry_value_data", registry_value_data, "process_guid", process_guid]) | into write_ssa_detected_events();' +search: '| from read_ssa_enriched_events() | where "Endpoint_Registry" IN (_datamodels) | eval timestamp=parse_long(ucast(map_get(input_event, "_time"), "string", null)), registry_path=lower(ucast(map_get(input_event, "registry_path"), "string", null)), registry_hive=lower(ucast(map_get(input_event, "registry_hive"), "string", null)), registry_value_name=lower(ucast(map_get(input_event, "registry_value_name"), "string", null)), registry_key_name=lower(ucast(map_get(input_event, "parent_process_name"), "string", null)), registry_value_type=lower(ucast(map_get(input_event, "registry_value_type"), "string", null)), registry_value_data=lower(ucast(map_get(input_event, "registry_value_data"), "string", null)), process_guid=lower(ucast(map_get(input_event, "process_guid"), "string", null)) | where registry_path IS NOT NULL AND (like (registry_path, "%mscfile\\shell\\open\\command%")) | eval start_time=timestamp, end_time=timestamp, entities=mvappend(ucast(map_get(input_event, "dest_user_id"), "string", null), ucast(map_get(input_event, "dest_device_id"), "string", null)) | eval body=create_map(["event_id", event_id, "registry_path", registry_path, "registry_hive", registry_hive, "registry_value_name", registry_value_name, "registry_key_name", registry_key_name, "registry_value_type", registry_value_type, "registry_value_data", registry_value_data, "process_guid", process_guid]) | into write_ssa_detected_events();' how_to_implement: To successfully implement this search you need to be ingesting information on process that include the name of the process responsible for the changes from your endpoints into the `Endpoint_Registry` datamodel. known_false_positives: UPDATE_KNOWN_FALSE_POSITIVES references: From 9cf8199444ff91c0c8cdad93f75025f0aebbd588 Mon Sep 17 00:00:00 2001 From: Lou Stella Date: Wed, 23 Feb 2022 18:18:40 -0600 Subject: [PATCH 03/11] update again --- detections/endpoint/ssa___windows_eventvwr_uac_bypass.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/detections/endpoint/ssa___windows_eventvwr_uac_bypass.yml b/detections/endpoint/ssa___windows_eventvwr_uac_bypass.yml index 612b865c32..af4089645e 100644 --- a/detections/endpoint/ssa___windows_eventvwr_uac_bypass.yml +++ b/detections/endpoint/ssa___windows_eventvwr_uac_bypass.yml @@ -7,7 +7,7 @@ type: Anomaly datamodel: - Endpoint_Registry description: The following search identifies Eventvwr bypass by identifying the registry modification into a specific path that eventvwr.msc looks to (but is not valid) upon execution. A successful attack will include a suspicious command to be executed upon eventvwr.msc loading. Upon triage, review the parallel processes that have executed. Identify any additional registry modifications on the endpoint that may look suspicious. Remediate as necessary. -search: '| from read_ssa_enriched_events() | where "Endpoint_Registry" IN (_datamodels) | eval timestamp=parse_long(ucast(map_get(input_event, "_time"), "string", null)), registry_path=lower(ucast(map_get(input_event, "registry_path"), "string", null)), registry_hive=lower(ucast(map_get(input_event, "registry_hive"), "string", null)), registry_value_name=lower(ucast(map_get(input_event, "registry_value_name"), "string", null)), registry_key_name=lower(ucast(map_get(input_event, "parent_process_name"), "string", null)), registry_value_type=lower(ucast(map_get(input_event, "registry_value_type"), "string", null)), registry_value_data=lower(ucast(map_get(input_event, "registry_value_data"), "string", null)), process_guid=lower(ucast(map_get(input_event, "process_guid"), "string", null)) | where registry_path IS NOT NULL AND (like (registry_path, "%mscfile\\shell\\open\\command%")) | eval start_time=timestamp, end_time=timestamp, entities=mvappend(ucast(map_get(input_event, "dest_user_id"), "string", null), ucast(map_get(input_event, "dest_device_id"), "string", null)) | eval body=create_map(["event_id", event_id, "registry_path", registry_path, "registry_hive", registry_hive, "registry_value_name", registry_value_name, "registry_key_name", registry_key_name, "registry_value_type", registry_value_type, "registry_value_data", registry_value_data, "process_guid", process_guid]) | into write_ssa_detected_events();' +search: '| from read_ssa_enriched_events() | where "Endpoint_Registry" IN (_datamodels) | eval timestamp=parse_long(ucast(map_get(input_event, "_time"), "string", null)), registry_path=lower(ucast(map_get(input_event, "registry_path"), "string", null)), registry_hive=lower(ucast(map_get(input_event, "registry_hive"), "string", null)), registry_value_name=lower(ucast(map_get(input_event, "registry_value_name"), "string", null)), registry_key_name=lower(ucast(map_get(input_event, "parent_process_name"), "string", null)), registry_value_type=lower(ucast(map_get(input_event, "registry_value_type"), "string", null)), registry_value_data=lower(ucast(map_get(input_event, "registry_value_data"), "string", null)), process_guid=lower(ucast(map_get(input_event, "process_guid"), "string", null)) | where registry_path IS NOT NULL AND (like (registry_path, "%command%")) | eval start_time=timestamp, end_time=timestamp, entities=mvappend(ucast(map_get(input_event, "dest_user_id"), "string", null), ucast(map_get(input_event, "dest_device_id"), "string", null)) | eval body=create_map(["registry_path", registry_path, "registry_hive", registry_hive, "registry_value_name", registry_value_name, "registry_key_name", registry_key_name, "registry_value_type", registry_value_type, "registry_value_data", registry_value_data, "process_guid", process_guid]) | into write_ssa_detected_events();' how_to_implement: To successfully implement this search you need to be ingesting information on process that include the name of the process responsible for the changes from your endpoints into the `Endpoint_Registry` datamodel. known_false_positives: UPDATE_KNOWN_FALSE_POSITIVES references: From be19bf61b921b5faa2a33519feb1240750adeb40 Mon Sep 17 00:00:00 2001 From: Lou Stella Date: Wed, 23 Feb 2022 18:26:26 -0600 Subject: [PATCH 04/11] fixed like statement --- detections/endpoint/ssa___windows_eventvwr_uac_bypass.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/detections/endpoint/ssa___windows_eventvwr_uac_bypass.yml b/detections/endpoint/ssa___windows_eventvwr_uac_bypass.yml index af4089645e..fa2ece5a8e 100644 --- a/detections/endpoint/ssa___windows_eventvwr_uac_bypass.yml +++ b/detections/endpoint/ssa___windows_eventvwr_uac_bypass.yml @@ -7,7 +7,7 @@ type: Anomaly datamodel: - Endpoint_Registry description: The following search identifies Eventvwr bypass by identifying the registry modification into a specific path that eventvwr.msc looks to (but is not valid) upon execution. A successful attack will include a suspicious command to be executed upon eventvwr.msc loading. Upon triage, review the parallel processes that have executed. Identify any additional registry modifications on the endpoint that may look suspicious. Remediate as necessary. -search: '| from read_ssa_enriched_events() | where "Endpoint_Registry" IN (_datamodels) | eval timestamp=parse_long(ucast(map_get(input_event, "_time"), "string", null)), registry_path=lower(ucast(map_get(input_event, "registry_path"), "string", null)), registry_hive=lower(ucast(map_get(input_event, "registry_hive"), "string", null)), registry_value_name=lower(ucast(map_get(input_event, "registry_value_name"), "string", null)), registry_key_name=lower(ucast(map_get(input_event, "parent_process_name"), "string", null)), registry_value_type=lower(ucast(map_get(input_event, "registry_value_type"), "string", null)), registry_value_data=lower(ucast(map_get(input_event, "registry_value_data"), "string", null)), process_guid=lower(ucast(map_get(input_event, "process_guid"), "string", null)) | where registry_path IS NOT NULL AND (like (registry_path, "%command%")) | eval start_time=timestamp, end_time=timestamp, entities=mvappend(ucast(map_get(input_event, "dest_user_id"), "string", null), ucast(map_get(input_event, "dest_device_id"), "string", null)) | eval body=create_map(["registry_path", registry_path, "registry_hive", registry_hive, "registry_value_name", registry_value_name, "registry_key_name", registry_key_name, "registry_value_type", registry_value_type, "registry_value_data", registry_value_data, "process_guid", process_guid]) | into write_ssa_detected_events();' +search: '| from read_ssa_enriched_events() | where "Endpoint_Registry" IN (_datamodels) | eval timestamp=parse_long(ucast(map_get(input_event, "_time"), "string", null)), registry_path=lower(ucast(map_get(input_event, "registry_path"), "string", null)), registry_hive=lower(ucast(map_get(input_event, "registry_hive"), "string", null)), registry_value_name=lower(ucast(map_get(input_event, "registry_value_name"), "string", null)), registry_key_name=lower(ucast(map_get(input_event, "parent_process_name"), "string", null)), registry_value_type=lower(ucast(map_get(input_event, "registry_value_type"), "string", null)), registry_value_data=lower(ucast(map_get(input_event, "registry_value_data"), "string", null)), process_guid=lower(ucast(map_get(input_event, "process_guid"), "string", null)) | where registry_path IS NOT NULL AND (like (registry_path, "%mscfile\\\\shell\\\\open\\\\command%")) | eval start_time=timestamp, end_time=timestamp, entities=mvappend(ucast(map_get(input_event, "dest_user_id"), "string", null), ucast(map_get(input_event, "dest_device_id"), "string", null)) | eval body=create_map(["registry_path", registry_path, "registry_hive", registry_hive, "registry_value_name", registry_value_name, "registry_key_name", registry_key_name, "registry_value_type", registry_value_type, "registry_value_data", registry_value_data, "process_guid", process_guid]) | into write_ssa_detected_events();' how_to_implement: To successfully implement this search you need to be ingesting information on process that include the name of the process responsible for the changes from your endpoints into the `Endpoint_Registry` datamodel. known_false_positives: UPDATE_KNOWN_FALSE_POSITIVES references: From 97120e2aeb3eb01cdac2b6276a90b369e772569c Mon Sep 17 00:00:00 2001 From: Lou Stella Date: Wed, 23 Feb 2022 19:30:57 -0600 Subject: [PATCH 05/11] Added back other WIP detection --- .../ssa___windows_wsreset_uac_bypass.yml | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 detections/endpoint/ssa___windows_wsreset_uac_bypass.yml diff --git a/detections/endpoint/ssa___windows_wsreset_uac_bypass.yml b/detections/endpoint/ssa___windows_wsreset_uac_bypass.yml new file mode 100644 index 0000000000..a6f54f30a2 --- /dev/null +++ b/detections/endpoint/ssa___windows_wsreset_uac_bypass.yml @@ -0,0 +1,47 @@ +name: Windows WSReset UAC Bypass +id: 3118f0c2-90d9-11ec-b833-acde48001122 +version: 1 +date: '2022-02-18' +author: Lou Stella, Splunk +type: Anomaly +datamodel: +- Endpoint_Registry +description: This analytic is built to detect a suspicious modification of the Windows registry related to UAC bypass. This technique is to modify the registry in this detection, create a registry value with the path of the payload and run WSreset.exe to bypass User Account Control. +search: '|from read_ssa_enriched_events() | where "Endpoint_Registry IN (_datamodels) | eval timestamp=parse_long(ucast(map_get(input_event, "_time"), "string", null)), registry_path=lower(ucast(map_get(input_event, "registry_path"), "string", null)), registry_hive=lower(ucast(map_get(input_event, "registry_hive"), "string", null)), registry_value_name=lower(ucast(map_get(input_event, "registry_value_name"), "string", null)), registry_key_name=lower(ucast(map_get(input_event, "parent_process_name"), "string", null)), registry_value_type=lower(ucast(map_get(input_event, "registry_value_type"), "string", null)), registry_value_data=lower(ucast(map_get(input_event, "registry_value_data"), "string", null)), process_guid=lower(ucast(map_get(input_event, "process_guid"), "string", null)), event_id=ucast(map_get(input_event, "event_id"), "string", null) | where registry_path IS NOT NULL AND registry_value_name IS NOT NULL and like (registry_path, "%\\AppX82a6gwre4fdg3bt635tn5ctqjf8msdd2\\Shell\\open\\command%") AND (registry_value_name="(Default)" OR registry_value_name="DelegateExecute") | eval start_time=timestamp, end_time=timestamp, entities=mvappend(ucast(map_get(input_event, "dest_user_id"), "string", null), ucast(map_get(input_event, "dest_device_id"), "string", null)) | eval body=create_map(["event_id", event_id, "registry_path", registry_path, "registry_hive", registry_hive, "registry_value_name", registry_value_name, "registry_key_name", registry_key_name, "registry_value_type", registry_value_type, "registry_value_data", registry_value_data, "process_guid", process_guid]) | into write_ssa_detected_events() ' +how_to_implement: To successfully implement this search you need to be ingesting information on process that include the name of the process responsible for the changes from your endpoints into the `Endpoint_Registry` datamodel. +known_false_positives: UPDATE_KNOWN_FALSE_POSITIVES +references: +- https://github.com/hfiref0x/UACME +- https://blog.morphisec.com/trickbot-uses-a-new-windows-10-uac-bypass +tags: + analytic_story: + - Living Off The Land + - Windows Defense Evasion Tactics + dataset: + - UPDATE_DATASET_URL + kill_chain_phases: + - Privilege Escalation + mitre_attack_id: + - T1548.002 + - T1548 + product: + - Splunk Behavioral Analytics + required_fields: + - _time + security_domain: endpoint + impact: + confidence: + # (impact * confidence)/100 + risk_score: + context: + - Source:Endpoint + - Stage:Persistence + - Stage:Privilege Escalation + - Stage:Defense Evasion + - Scope:Incoming + message: + observable: + nist: + - + cis20: + - \ No newline at end of file From ca2163ae8c6767f0364c9a13242720c7b2bd683b Mon Sep 17 00:00:00 2001 From: Lou Stella Date: Fri, 25 Feb 2022 10:40:46 -0600 Subject: [PATCH 06/11] Moved to Experimental --- .../ssa___windows_wsreset_uac_bypass.yml | 47 ------------------ .../ssa___windows_wsreset_uac_bypass.yml | 48 +++++++++++++++++++ 2 files changed, 48 insertions(+), 47 deletions(-) delete mode 100644 detections/endpoint/ssa___windows_wsreset_uac_bypass.yml create mode 100644 detections/experimental/endpoint/ssa___windows_wsreset_uac_bypass.yml diff --git a/detections/endpoint/ssa___windows_wsreset_uac_bypass.yml b/detections/endpoint/ssa___windows_wsreset_uac_bypass.yml deleted file mode 100644 index a6f54f30a2..0000000000 --- a/detections/endpoint/ssa___windows_wsreset_uac_bypass.yml +++ /dev/null @@ -1,47 +0,0 @@ -name: Windows WSReset UAC Bypass -id: 3118f0c2-90d9-11ec-b833-acde48001122 -version: 1 -date: '2022-02-18' -author: Lou Stella, Splunk -type: Anomaly -datamodel: -- Endpoint_Registry -description: This analytic is built to detect a suspicious modification of the Windows registry related to UAC bypass. This technique is to modify the registry in this detection, create a registry value with the path of the payload and run WSreset.exe to bypass User Account Control. -search: '|from read_ssa_enriched_events() | where "Endpoint_Registry IN (_datamodels) | eval timestamp=parse_long(ucast(map_get(input_event, "_time"), "string", null)), registry_path=lower(ucast(map_get(input_event, "registry_path"), "string", null)), registry_hive=lower(ucast(map_get(input_event, "registry_hive"), "string", null)), registry_value_name=lower(ucast(map_get(input_event, "registry_value_name"), "string", null)), registry_key_name=lower(ucast(map_get(input_event, "parent_process_name"), "string", null)), registry_value_type=lower(ucast(map_get(input_event, "registry_value_type"), "string", null)), registry_value_data=lower(ucast(map_get(input_event, "registry_value_data"), "string", null)), process_guid=lower(ucast(map_get(input_event, "process_guid"), "string", null)), event_id=ucast(map_get(input_event, "event_id"), "string", null) | where registry_path IS NOT NULL AND registry_value_name IS NOT NULL and like (registry_path, "%\\AppX82a6gwre4fdg3bt635tn5ctqjf8msdd2\\Shell\\open\\command%") AND (registry_value_name="(Default)" OR registry_value_name="DelegateExecute") | eval start_time=timestamp, end_time=timestamp, entities=mvappend(ucast(map_get(input_event, "dest_user_id"), "string", null), ucast(map_get(input_event, "dest_device_id"), "string", null)) | eval body=create_map(["event_id", event_id, "registry_path", registry_path, "registry_hive", registry_hive, "registry_value_name", registry_value_name, "registry_key_name", registry_key_name, "registry_value_type", registry_value_type, "registry_value_data", registry_value_data, "process_guid", process_guid]) | into write_ssa_detected_events() ' -how_to_implement: To successfully implement this search you need to be ingesting information on process that include the name of the process responsible for the changes from your endpoints into the `Endpoint_Registry` datamodel. -known_false_positives: UPDATE_KNOWN_FALSE_POSITIVES -references: -- https://github.com/hfiref0x/UACME -- https://blog.morphisec.com/trickbot-uses-a-new-windows-10-uac-bypass -tags: - analytic_story: - - Living Off The Land - - Windows Defense Evasion Tactics - dataset: - - UPDATE_DATASET_URL - kill_chain_phases: - - Privilege Escalation - mitre_attack_id: - - T1548.002 - - T1548 - product: - - Splunk Behavioral Analytics - required_fields: - - _time - security_domain: endpoint - impact: - confidence: - # (impact * confidence)/100 - risk_score: - context: - - Source:Endpoint - - Stage:Persistence - - Stage:Privilege Escalation - - Stage:Defense Evasion - - Scope:Incoming - message: - observable: - nist: - - - cis20: - - \ No newline at end of file diff --git a/detections/experimental/endpoint/ssa___windows_wsreset_uac_bypass.yml b/detections/experimental/endpoint/ssa___windows_wsreset_uac_bypass.yml new file mode 100644 index 0000000000..97b08bc1e3 --- /dev/null +++ b/detections/experimental/endpoint/ssa___windows_wsreset_uac_bypass.yml @@ -0,0 +1,48 @@ +name: Windows WSReset UAC Bypass +id: 3118f0c2-90d9-11ec-b833-acde48001122 +version: 1 +date: '2022-02-18' +author: Lou Stella, Splunk +type: Anomaly +datamodel: +- Endpoint_Registry +description: This analytic is built to detect a suspicious modification of the Windows registry related to UAC bypass. This technique is to modify the registry in this detection, create a registry value with the path of the payload and run WSreset.exe to bypass User Account Control. +search: '| from read_ssa_enriched_events() | where "Endpoint_Registry" IN (_datamodels) | eval timestamp=parse_long(ucast(map_get(input_event, "_time"), "string", null)), registry_path=lower(ucast(map_get(input_event, "registry_path"), "string", null)), registry_hive=lower(ucast(map_get(input_event, "registry_hive"), "string", null)), registry_value_name=lower(ucast(map_get(input_event, "registry_value_name"), "string", null)), registry_key_name=lower(ucast(map_get(input_event, "parent_process_name"), "string", null)), registry_value_type=lower(ucast(map_get(input_event, "registry_value_type"), "string", null)), registry_value_data=lower(ucast(map_get(input_event, "registry_value_data"), "string", null)), process_guid=lower(ucast(map_get(input_event, "process_guid"), "string", null)) | where registry_path IS NOT NULL AND registry_value_name IS NOT NULL and like (registry_path, "%\\\\AppX82a6gwre4fdg3bt635tn5ctqjf8msdd2\\\\Shell\\\\open\\\\command%") AND (registry_value_name="(Default)" OR registry_value_name="DelegateExecute") | eval start_time=timestamp, end_time=timestamp, entities=mvappend(ucast(map_get(input_event, "dest_user_id"), "string", null), ucast(map_get(input_event, "dest_device_id"), "string", null)) | eval body=create_map(["event_id", event_id, "registry_path", registry_path, "registry_hive", registry_hive, "registry_value_name", registry_value_name, "registry_key_name", registry_key_name, "registry_value_type", registry_value_type, "registry_value_data", registry_value_data, "process_guid", process_guid]) | into write_ssa_detected_events() ' +how_to_implement: To successfully implement this search you need to be ingesting information on process that include the name of the process responsible for the changes from your endpoints into the `Endpoint_Registry` datamodel. +known_false_positives: UPDATE_KNOWN_FALSE_POSITIVES +references: +- https://github.com/hfiref0x/UACME +- https://blog.morphisec.com/trickbot-uses-a-new-windows-10-uac-bypass +tags: + analytic_story: + - Living Off The Land + - Windows Defense Evasion Tactics + kill_chain_phases: + - Privilege Escalation + mitre_attack_id: + - T1548.002 + - T1548 + product: + - Splunk Behavioral Analytics + required_fields: + - _time + security_domain: endpoint + impact: 70 + confidence: 90 + risk_score: 63 + context: + - Source:Endpoint + - Stage:Persistence + - Stage:Privilege Escalation + - Stage:Defense Evasion + - Scope:Incoming + message: + observable: + - name: dest + type: Hostname + role: + - Victim + nist: + - DE.AE + cis20: + - CIS 14 \ No newline at end of file From 760747cea2940438edfd1c5dc0697b5477b93e38 Mon Sep 17 00:00:00 2001 From: Lou Stella Date: Fri, 25 Feb 2022 10:46:46 -0600 Subject: [PATCH 07/11] Small update to body --- .../experimental/endpoint/ssa___windows_wsreset_uac_bypass.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/detections/experimental/endpoint/ssa___windows_wsreset_uac_bypass.yml b/detections/experimental/endpoint/ssa___windows_wsreset_uac_bypass.yml index 97b08bc1e3..23366f9fd7 100644 --- a/detections/experimental/endpoint/ssa___windows_wsreset_uac_bypass.yml +++ b/detections/experimental/endpoint/ssa___windows_wsreset_uac_bypass.yml @@ -7,7 +7,7 @@ type: Anomaly datamodel: - Endpoint_Registry description: This analytic is built to detect a suspicious modification of the Windows registry related to UAC bypass. This technique is to modify the registry in this detection, create a registry value with the path of the payload and run WSreset.exe to bypass User Account Control. -search: '| from read_ssa_enriched_events() | where "Endpoint_Registry" IN (_datamodels) | eval timestamp=parse_long(ucast(map_get(input_event, "_time"), "string", null)), registry_path=lower(ucast(map_get(input_event, "registry_path"), "string", null)), registry_hive=lower(ucast(map_get(input_event, "registry_hive"), "string", null)), registry_value_name=lower(ucast(map_get(input_event, "registry_value_name"), "string", null)), registry_key_name=lower(ucast(map_get(input_event, "parent_process_name"), "string", null)), registry_value_type=lower(ucast(map_get(input_event, "registry_value_type"), "string", null)), registry_value_data=lower(ucast(map_get(input_event, "registry_value_data"), "string", null)), process_guid=lower(ucast(map_get(input_event, "process_guid"), "string", null)) | where registry_path IS NOT NULL AND registry_value_name IS NOT NULL and like (registry_path, "%\\\\AppX82a6gwre4fdg3bt635tn5ctqjf8msdd2\\\\Shell\\\\open\\\\command%") AND (registry_value_name="(Default)" OR registry_value_name="DelegateExecute") | eval start_time=timestamp, end_time=timestamp, entities=mvappend(ucast(map_get(input_event, "dest_user_id"), "string", null), ucast(map_get(input_event, "dest_device_id"), "string", null)) | eval body=create_map(["event_id", event_id, "registry_path", registry_path, "registry_hive", registry_hive, "registry_value_name", registry_value_name, "registry_key_name", registry_key_name, "registry_value_type", registry_value_type, "registry_value_data", registry_value_data, "process_guid", process_guid]) | into write_ssa_detected_events() ' +search: '| from read_ssa_enriched_events() | where "Endpoint_Registry" IN (_datamodels) | eval timestamp=parse_long(ucast(map_get(input_event, "_time"), "string", null)), registry_path=lower(ucast(map_get(input_event, "registry_path"), "string", null)), registry_hive=lower(ucast(map_get(input_event, "registry_hive"), "string", null)), registry_value_name=lower(ucast(map_get(input_event, "registry_value_name"), "string", null)), registry_key_name=lower(ucast(map_get(input_event, "parent_process_name"), "string", null)), registry_value_type=lower(ucast(map_get(input_event, "registry_value_type"), "string", null)), registry_value_data=lower(ucast(map_get(input_event, "registry_value_data"), "string", null)), process_guid=lower(ucast(map_get(input_event, "process_guid"), "string", null)) | where registry_path IS NOT NULL AND registry_value_name IS NOT NULL and like (registry_path, "%\\\\AppX82a6gwre4fdg3bt635tn5ctqjf8msdd2\\\\Shell\\\\open\\\\command%") AND (registry_value_name="(Default)" OR registry_value_name="DelegateExecute") | eval start_time=timestamp, end_time=timestamp, entities=mvappend(ucast(map_get(input_event, "dest_user_id"), "string", null), ucast(map_get(input_event, "dest_device_id"), "string", null)) | eval body=create_map(["registry_path", registry_path, "registry_hive", registry_hive, "registry_value_name", registry_value_name, "registry_key_name", registry_key_name, "registry_value_type", registry_value_type, "registry_value_data", registry_value_data, "process_guid", process_guid]) | into write_ssa_detected_events(); ' how_to_implement: To successfully implement this search you need to be ingesting information on process that include the name of the process responsible for the changes from your endpoints into the `Endpoint_Registry` datamodel. known_false_positives: UPDATE_KNOWN_FALSE_POSITIVES references: From 4d05f75a0f0740d6ddabb7c0e57e4c107bacc4c1 Mon Sep 17 00:00:00 2001 From: Lou Stella Date: Fri, 25 Feb 2022 10:48:30 -0600 Subject: [PATCH 08/11] Removed broken test --- .../ssa___windows_wsreset_uac_bypass.test.yml | 11 ----------- 1 file changed, 11 deletions(-) delete mode 100644 tests/endpoint/ssa___windows_wsreset_uac_bypass.test.yml diff --git a/tests/endpoint/ssa___windows_wsreset_uac_bypass.test.yml b/tests/endpoint/ssa___windows_wsreset_uac_bypass.test.yml deleted file mode 100644 index 61f5eba349..0000000000 --- a/tests/endpoint/ssa___windows_wsreset_uac_bypass.test.yml +++ /dev/null @@ -1,11 +0,0 @@ -name: Windows WSReset UAC Bypass Unit Test -tests: -- name: Windows WSReset UAC Bypass - file: endpoint/ssa___windows_wsreset_uac_bypass.yml - pass_condition: '@count_gt(0)' - description: Test Windows WSReset UAC Bypass detections - attack_data: - - file_name: hidden_windows-security.log - data: https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1548/uac_bypass/windows-sysmon.log - source: XmlWinEventLog:Microsoft-Windows-Sysmon/Operational - sourcetype: xmlwineventlog \ No newline at end of file From 9f65b5d0d4ce1d1cb042b16a156b05de5dae7972 Mon Sep 17 00:00:00 2001 From: Lou Stella Date: Fri, 25 Feb 2022 13:48:04 -0600 Subject: [PATCH 09/11] Updated required fields --- .../endpoint/ssa___windows_wsreset_uac_bypass.yml | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/detections/experimental/endpoint/ssa___windows_wsreset_uac_bypass.yml b/detections/experimental/endpoint/ssa___windows_wsreset_uac_bypass.yml index 23366f9fd7..7c2e44ce70 100644 --- a/detections/experimental/endpoint/ssa___windows_wsreset_uac_bypass.yml +++ b/detections/experimental/endpoint/ssa___windows_wsreset_uac_bypass.yml @@ -7,9 +7,9 @@ type: Anomaly datamodel: - Endpoint_Registry description: This analytic is built to detect a suspicious modification of the Windows registry related to UAC bypass. This technique is to modify the registry in this detection, create a registry value with the path of the payload and run WSreset.exe to bypass User Account Control. -search: '| from read_ssa_enriched_events() | where "Endpoint_Registry" IN (_datamodels) | eval timestamp=parse_long(ucast(map_get(input_event, "_time"), "string", null)), registry_path=lower(ucast(map_get(input_event, "registry_path"), "string", null)), registry_hive=lower(ucast(map_get(input_event, "registry_hive"), "string", null)), registry_value_name=lower(ucast(map_get(input_event, "registry_value_name"), "string", null)), registry_key_name=lower(ucast(map_get(input_event, "parent_process_name"), "string", null)), registry_value_type=lower(ucast(map_get(input_event, "registry_value_type"), "string", null)), registry_value_data=lower(ucast(map_get(input_event, "registry_value_data"), "string", null)), process_guid=lower(ucast(map_get(input_event, "process_guid"), "string", null)) | where registry_path IS NOT NULL AND registry_value_name IS NOT NULL and like (registry_path, "%\\\\AppX82a6gwre4fdg3bt635tn5ctqjf8msdd2\\\\Shell\\\\open\\\\command%") AND (registry_value_name="(Default)" OR registry_value_name="DelegateExecute") | eval start_time=timestamp, end_time=timestamp, entities=mvappend(ucast(map_get(input_event, "dest_user_id"), "string", null), ucast(map_get(input_event, "dest_device_id"), "string", null)) | eval body=create_map(["registry_path", registry_path, "registry_hive", registry_hive, "registry_value_name", registry_value_name, "registry_key_name", registry_key_name, "registry_value_type", registry_value_type, "registry_value_data", registry_value_data, "process_guid", process_guid]) | into write_ssa_detected_events(); ' +search: '| from read_ssa_enriched_events() | where "Endpoint_Registry" IN (_datamodels) | eval timestamp=parse_long(ucast(map_get(input_event, "_time"), "string", null)), registry_path=lower(ucast(map_get(input_event, "registry_path"), "string", null)), registry_hive=lower(ucast(map_get(input_event, "registry_hive"), "string", null)), registry_value_name=lower(ucast(map_get(input_event, "registry_value_name"), "string", null)), registry_key_name=lower(ucast(map_get(input_event, "registry_key_name"), "string", null)), registry_value_type=lower(ucast(map_get(input_event, "registry_value_type"), "string", null)), registry_value_data=lower(ucast(map_get(input_event, "registry_value_data"), "string", null)), process_guid=lower(ucast(map_get(input_event, "process_guid"), "string", null)) | where registry_path IS NOT NULL AND registry_value_name IS NOT NULL and like (registry_path, "%\\\\AppX82a6gwre4fdg3bt635tn5ctqjf8msdd2\\\\Shell\\\\open\\\\command%") AND (registry_value_name="(Default)" OR registry_value_name="DelegateExecute") | eval start_time=timestamp, end_time=timestamp, entities=mvappend(ucast(map_get(input_event, "dest_user_id"), "string", null), ucast(map_get(input_event, "dest_device_id"), "string", null)) | eval body=create_map(["registry_path", registry_path, "registry_hive", registry_hive, "registry_value_name", registry_value_name, "registry_key_name", registry_key_name, "registry_value_type", registry_value_type, "registry_value_data", registry_value_data, "process_guid", process_guid]) | into write_ssa_detected_events(); ' how_to_implement: To successfully implement this search you need to be ingesting information on process that include the name of the process responsible for the changes from your endpoints into the `Endpoint_Registry` datamodel. -known_false_positives: UPDATE_KNOWN_FALSE_POSITIVES +known_false_positives: Unknown at this point in time. references: - https://github.com/hfiref0x/UACME - https://blog.morphisec.com/trickbot-uses-a-new-windows-10-uac-bypass @@ -26,6 +26,13 @@ tags: - Splunk Behavioral Analytics required_fields: - _time + - registry_path + - registry_hive + - registry_value_name + - registry_key_name + - registry_value_type + - registry_value_data + - process_guid security_domain: endpoint impact: 70 confidence: 90 From d3322283c39eea6c55e4dfe68f832bd0728bb987 Mon Sep 17 00:00:00 2001 From: Lou Stella Date: Fri, 25 Feb 2022 13:49:21 -0600 Subject: [PATCH 10/11] Added risk_severity --- detections/endpoint/ssa___windows_eventvwr_uac_bypass.yml | 1 + .../experimental/endpoint/ssa___windows_wsreset_uac_bypass.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/detections/endpoint/ssa___windows_eventvwr_uac_bypass.yml b/detections/endpoint/ssa___windows_eventvwr_uac_bypass.yml index fa2ece5a8e..78dc50a0cd 100644 --- a/detections/endpoint/ssa___windows_eventvwr_uac_bypass.yml +++ b/detections/endpoint/ssa___windows_eventvwr_uac_bypass.yml @@ -43,6 +43,7 @@ tags: impact: 80 confidence: 100 risk_score: 80 + risk_severity: high context: - Source:Endpoint - Stage:Privilege Escalation diff --git a/detections/experimental/endpoint/ssa___windows_wsreset_uac_bypass.yml b/detections/experimental/endpoint/ssa___windows_wsreset_uac_bypass.yml index 7c2e44ce70..68f37f6895 100644 --- a/detections/experimental/endpoint/ssa___windows_wsreset_uac_bypass.yml +++ b/detections/experimental/endpoint/ssa___windows_wsreset_uac_bypass.yml @@ -37,6 +37,7 @@ tags: impact: 70 confidence: 90 risk_score: 63 + risk_severity: medium context: - Source:Endpoint - Stage:Persistence From 176c3390730cee1cf2c597bb62820d4c139a793c Mon Sep 17 00:00:00 2001 From: Lou Stella Date: Fri, 25 Feb 2022 14:22:53 -0600 Subject: [PATCH 11/11] Updated FP --- detections/endpoint/ssa___windows_eventvwr_uac_bypass.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/detections/endpoint/ssa___windows_eventvwr_uac_bypass.yml b/detections/endpoint/ssa___windows_eventvwr_uac_bypass.yml index 78dc50a0cd..1d87d7bca4 100644 --- a/detections/endpoint/ssa___windows_eventvwr_uac_bypass.yml +++ b/detections/endpoint/ssa___windows_eventvwr_uac_bypass.yml @@ -9,7 +9,7 @@ datamodel: description: The following search identifies Eventvwr bypass by identifying the registry modification into a specific path that eventvwr.msc looks to (but is not valid) upon execution. A successful attack will include a suspicious command to be executed upon eventvwr.msc loading. Upon triage, review the parallel processes that have executed. Identify any additional registry modifications on the endpoint that may look suspicious. Remediate as necessary. search: '| from read_ssa_enriched_events() | where "Endpoint_Registry" IN (_datamodels) | eval timestamp=parse_long(ucast(map_get(input_event, "_time"), "string", null)), registry_path=lower(ucast(map_get(input_event, "registry_path"), "string", null)), registry_hive=lower(ucast(map_get(input_event, "registry_hive"), "string", null)), registry_value_name=lower(ucast(map_get(input_event, "registry_value_name"), "string", null)), registry_key_name=lower(ucast(map_get(input_event, "parent_process_name"), "string", null)), registry_value_type=lower(ucast(map_get(input_event, "registry_value_type"), "string", null)), registry_value_data=lower(ucast(map_get(input_event, "registry_value_data"), "string", null)), process_guid=lower(ucast(map_get(input_event, "process_guid"), "string", null)) | where registry_path IS NOT NULL AND (like (registry_path, "%mscfile\\\\shell\\\\open\\\\command%")) | eval start_time=timestamp, end_time=timestamp, entities=mvappend(ucast(map_get(input_event, "dest_user_id"), "string", null), ucast(map_get(input_event, "dest_device_id"), "string", null)) | eval body=create_map(["registry_path", registry_path, "registry_hive", registry_hive, "registry_value_name", registry_value_name, "registry_key_name", registry_key_name, "registry_value_type", registry_value_type, "registry_value_data", registry_value_data, "process_guid", process_guid]) | into write_ssa_detected_events();' how_to_implement: To successfully implement this search you need to be ingesting information on process that include the name of the process responsible for the changes from your endpoints into the `Endpoint_Registry` datamodel. -known_false_positives: UPDATE_KNOWN_FALSE_POSITIVES +known_false_positives: None known at this time. references: - https://blog.malwarebytes.com/malwarebytes-news/2021/02/lazyscripter-from-empire-to-double-rat/ - https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1548.002/T1548.002.md