From a7637dae832038842cc6613c98a8e51bcd827c77 Mon Sep 17 00:00:00 2001 From: P4T12ICK Date: Wed, 8 Dec 2021 09:46:20 +0100 Subject: [PATCH 1/9] BA detections --- .../modules/streams_service_api_helper.py | 6 +- .../modules/test_ssa_detections.py | 10 ++- .../ssa___high_file_deletion_frequency.yml | 80 +++++++++++++++++++ ...sa___high_file_deletion_frequency.test.yml | 10 +++ 4 files changed, 100 insertions(+), 6 deletions(-) create mode 100644 detections/endpoint/ssa___high_file_deletion_frequency.yml create mode 100644 tests/endpoint/ssa___high_file_deletion_frequency.test.yml diff --git a/bin/ssa-end-to-end-testing/modules/streams_service_api_helper.py b/bin/ssa-end-to-end-testing/modules/streams_service_api_helper.py index cec0be1d22..1d3c366206 100644 --- a/bin/ssa-end-to-end-testing/modules/streams_service_api_helper.py +++ b/bin/ssa-end-to-end-testing/modules/streams_service_api_helper.py @@ -429,7 +429,7 @@ class DSPApi: return preview_id - def ingest_data(self, data): + def ingest_data(self, data, sourcetype): """ Send events @@ -443,9 +443,11 @@ class DSPApi: response response body in JSON format """ + if sourcetype == "WinEventLog:Security": + sourcetype = "WinEventLog" data = [{ "body": event, - "sourcetype": "WinEventLog" + "sourcetype": sourcetype } for event in data] response = requests.post(self.return_api_endpoint(INGEST_ENDPOINT), json=data, headers=request_headers(self.header_token)) if response.status_code != HTTPStatus.OK: diff --git a/bin/ssa-end-to-end-testing/modules/test_ssa_detections.py b/bin/ssa-end-to-end-testing/modules/test_ssa_detections.py index 1c21291c7a..b334d775b6 100644 --- a/bin/ssa-end-to-end-testing/modules/test_ssa_detections.py +++ b/bin/ssa-end-to-end-testing/modules/test_ssa_detections.py @@ -1,5 +1,6 @@ import logging import os +from re import S import time import sys import uuid @@ -70,6 +71,7 @@ class SSADetectionTesting: test_id = str(uuid.uuid4()) test_results = self.ssa_detection_test(test_obj["detection_obj"]["search"], file_path_attack_data, "SSA Smoke Test " + test_obj["test_obj"]["name"], test_id, + test_obj['test_obj']['tests'][0]['attack_data'][0]['source'], test_obj['test_obj']['tests'][0]['pass_condition']) return test_results @@ -113,7 +115,7 @@ class SSADetectionTesting: else: LOGGER.warning("Found and deleted an old pipeline: %s", pipeline['name']) - def ssa_detection_test_main(self, spl, source, test_name, pass_condition, test_id): + def ssa_detection_test_main(self, spl, source, test_name, pass_condition, test_id, sourcetype): self.execution_passed = True self.wait_time(SLEEP_TIME_CREATE_INDEX) @@ -152,7 +154,7 @@ class SSADetectionTesting: assert len(data) > 0, "No events to send, skip to next test." - data_uploaded = self.api.ingest_data(data) + data_uploaded = self.api.ingest_data(data, sourcetype) assert data_uploaded, "Failed to upload test data" self.wait_time(SLEEP_TIME_SEND_DATA) @@ -212,10 +214,10 @@ class SSADetectionTesting: else: LOGGER.info("Testing successfully cleaned up") - def ssa_detection_test(self, spl, source, test_name, test_id, pass_condition='@count_gt(0)'): + def ssa_detection_test(self, spl, source, test_name, test_id, sourcetype, pass_condition='@count_gt(0)'): self.ssa_detection_test_init() try: - test_result = self.ssa_detection_test_main(spl, source, test_name, pass_condition, test_id) + test_result = self.ssa_detection_test_main(spl, source, test_name, pass_condition, test_id, sourcetype) self.ssa_detection_test_teardown() return test_result except AssertionError as e: diff --git a/detections/endpoint/ssa___high_file_deletion_frequency.yml b/detections/endpoint/ssa___high_file_deletion_frequency.yml new file mode 100644 index 0000000000..b676a2cc0e --- /dev/null +++ b/detections/endpoint/ssa___high_file_deletion_frequency.yml @@ -0,0 +1,80 @@ +name: High File Deletion Frequency +id: b6200efd-13bd-4336-920a-057b25bbcfaf +version: 1 +date: '2021-12-07' +author: Patrick Bareiss, Splunk +type: Anomaly +datamodel: +- Endpoint_Filesystem +description: This detection detects a high amount of file deletions in a short time for specific file types. + This can be an indicator for a malicious insider. +search: '| from read_ssa_enriched_events() | eval timestamp=parse_long(ucast(map_get(input_event, "_time"), "string", null)) + | eval action=ucast(map_get(input_event, "action"), "string", null), + process=ucast(map_get(input_event, "process"), "string", null), + file_name=ucast(map_get(input_event, "file_name"), "string", null), + file_path=ucast(map_get(input_event, "file_path"), "string", null), + dest_user_id=ucast(map_get(input_event, "dest_user_id"), "string", null), + dest_device_id=ucast(map_get(input_event, "dest_device_id"), "string", null) + | where "Endpoint_Filesystem" IN(_datamodels) + | where action="deleted" + | where like(file_name, "%.cmd") OR like(file_name, "%.ini") OR like(file_name, "%.gif") + OR like(file_name, "%.jpg") OR like(file_name, "%.jpeg") OR like(file_name, "%.db") + OR like(file_name, "%.doc%") OR like(file_name, "%.ps1") OR like(file_name, "%.xls%") + OR like(file_name, "%.ppt%") OR like(file_name, "%.bmp") OR like(file_name, "%.zip") + OR like(file_name, "%.rar") OR like(file_name, "%.7z") OR like(file_name, "%.chm") + OR like(file_name, "%.png") OR like(file_name, "%.log") OR like(file_name, "%.vbs") + OR like(file_name, "%.js") + | stats count(file_name) AS count BY dest_user_id, dest_device_id, span(timestamp, 10m) + | where count > 20 + | eval start_time=window_start, end_time=window_end, entities=mvappend(dest_user_id, dest_device_id), body=create_map(["count", count]) + | 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` datamodel in the `Filesytem` node. +known_false_positives: user may delete bunch of pictures or files in a folder. +references: +- https://www.fireeye.com/blog/threat-research/2020/10/fin11-email-campaigns-precursor-for-ransomware-data-theft.html +- https://blog.virustotal.com/2020/11/keep-your-friends-close-keep-ransomware.html +tags: + analytic_story: + - Clop Ransomware + confidence: 80 + context: + - Source:Endpoint + - Stage:Execution + dataset: + - https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1485/excessive_file_deletions/windows-sysmon.log + impact: 90 + kill_chain_phases: + - Exploitation + message: High frequency file deletion activity detected on host $Computer$ + mitre_attack_id: + - T1485 + observable: + - name: user + type: User + role: + - Victim + - name: Computer + type: Endpoint + role: + - Victim + - name: deleted_files + type: File Name + role: + - Target + product: + - Splunk Enterprise + - Splunk Enterprise Security + - Splunk Cloud + required_fields: + - EventCode + - TargetFilename + - Computer + - user + - Image + - ProcessID + - _time + risk_score: 72 + security_domain: endpoint + diff --git a/tests/endpoint/ssa___high_file_deletion_frequency.test.yml b/tests/endpoint/ssa___high_file_deletion_frequency.test.yml new file mode 100644 index 0000000000..8c9b5f4172 --- /dev/null +++ b/tests/endpoint/ssa___high_file_deletion_frequency.test.yml @@ -0,0 +1,10 @@ +name: High File Deletion Frequency Unit Test +tests: + - name: High File Deletion Frequency + file: endpoint/ssa___high_file_deletion_frequency..yml + pass_condition: '@count_gt(0)' + description: Test for High File Deletion Frequency + attack_data: + - file_name: sysmon.log + data: https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1560.001/archive_tools/windows-security.log + source: xmlwineventlog From ae44ed6e6b843efa002c1747c4aaad2d441ca6fc Mon Sep 17 00:00:00 2001 From: P4T12ICK Date: Wed, 8 Dec 2021 09:59:22 +0100 Subject: [PATCH 2/9] BA detections --- bin/ssa-end-to-end-testing/modules/test_ssa_detections.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/ssa-end-to-end-testing/modules/test_ssa_detections.py b/bin/ssa-end-to-end-testing/modules/test_ssa_detections.py index b334d775b6..6f506c2669 100644 --- a/bin/ssa-end-to-end-testing/modules/test_ssa_detections.py +++ b/bin/ssa-end-to-end-testing/modules/test_ssa_detections.py @@ -49,7 +49,7 @@ class SSADetectionTesting: for i in range(0, len(test_spls)): self.max_execution_time = MAX_EXECUTION_TIME_LIMIT test_id = str(uuid.uuid4()) - test_result = self.ssa_detection_test(read_spl(file_path_spl, test_spls[i]), file_path_data, test_names[i], test_id) + test_result = self.ssa_detection_test(read_spl(file_path_spl, test_spls[i]), file_path_data, test_names[i], "WinEventLog", test_id) test_results.append(test_result.copy()) passed = True From 4c8ab01f3cd37f6382cc326adf0a88a9e974a04f Mon Sep 17 00:00:00 2001 From: P4T12ICK Date: Wed, 8 Dec 2021 10:20:36 +0100 Subject: [PATCH 3/9] BA detections --- bin/ssa-end-to-end-testing/modules/test_ssa_detections.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/ssa-end-to-end-testing/modules/test_ssa_detections.py b/bin/ssa-end-to-end-testing/modules/test_ssa_detections.py index 6f506c2669..7a47976885 100644 --- a/bin/ssa-end-to-end-testing/modules/test_ssa_detections.py +++ b/bin/ssa-end-to-end-testing/modules/test_ssa_detections.py @@ -49,7 +49,7 @@ class SSADetectionTesting: for i in range(0, len(test_spls)): self.max_execution_time = MAX_EXECUTION_TIME_LIMIT test_id = str(uuid.uuid4()) - test_result = self.ssa_detection_test(read_spl(file_path_spl, test_spls[i]), file_path_data, test_names[i], "WinEventLog", test_id) + test_result = self.ssa_detection_test(read_spl(file_path_spl, test_spls[i]), file_path_data, test_names[i], test_id, "WinEventLog") test_results.append(test_result.copy()) passed = True From 88bbb3dd645deaa43b7f79f859b0e638d7483869 Mon Sep 17 00:00:00 2001 From: P4T12ICK Date: Wed, 8 Dec 2021 10:43:36 +0100 Subject: [PATCH 4/9] BA detections --- tests/endpoint/ssa___high_file_deletion_frequency.test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/endpoint/ssa___high_file_deletion_frequency.test.yml b/tests/endpoint/ssa___high_file_deletion_frequency.test.yml index 8c9b5f4172..2204d122a0 100644 --- a/tests/endpoint/ssa___high_file_deletion_frequency.test.yml +++ b/tests/endpoint/ssa___high_file_deletion_frequency.test.yml @@ -1,7 +1,7 @@ name: High File Deletion Frequency Unit Test tests: - name: High File Deletion Frequency - file: endpoint/ssa___high_file_deletion_frequency..yml + file: endpoint/ssa___high_file_deletion_frequency.yml pass_condition: '@count_gt(0)' description: Test for High File Deletion Frequency attack_data: From 95268a9d27c9b0b82ce97b4350f489a7800fdc74 Mon Sep 17 00:00:00 2001 From: P4T12ICK Date: Wed, 8 Dec 2021 11:20:58 +0100 Subject: [PATCH 5/9] BA detections --- .../modules/test_ssa_detections.py | 2 +- bin/ssa-end-to-end-testing/modules/utils.py | 47 +++++++++++-------- 2 files changed, 28 insertions(+), 21 deletions(-) diff --git a/bin/ssa-end-to-end-testing/modules/test_ssa_detections.py b/bin/ssa-end-to-end-testing/modules/test_ssa_detections.py index 7a47976885..72221bd621 100644 --- a/bin/ssa-end-to-end-testing/modules/test_ssa_detections.py +++ b/bin/ssa-end-to-end-testing/modules/test_ssa_detections.py @@ -149,7 +149,7 @@ class SSADetectionTesting: self.test_results["msg"] = msg return self.test_results - data = read_data(source) + data = read_data(source, sourcetype) LOGGER.info("Sending (%d) events" % (len(data))) assert len(data) > 0, "No events to send, skip to next test." diff --git a/bin/ssa-end-to-end-testing/modules/utils.py b/bin/ssa-end-to-end-testing/modules/utils.py index 8e9d21ad6d..e9579e3326 100644 --- a/bin/ssa-end-to-end-testing/modules/utils.py +++ b/bin/ssa-end-to-end-testing/modules/utils.py @@ -3,6 +3,7 @@ import logging import os import fileinput import re +import io from .data_manipulation import DataManipulation @@ -104,32 +105,38 @@ def replace_ssa_macros(source, sink, spl): return spl -def read_data(file_path): - data_manipulation = DataManipulation() - modified_file = data_manipulation.manipulate_timestamp(file_path, 'xmlwineventlog', 'WinEventLog:Security') +def read_data(file_path, sourcetype): data = [] - date_rex = r'\d{2}/\d{2}/\d{4} \d{2}:\d{2}:\d{2} [AP]M' - count = len(open(modified_file).readlines()) + if sourcetype == "WinEventLog:Security": + data_manipulation = DataManipulation() + modified_file = data_manipulation.manipulate_timestamp(file_path, 'xmlwineventlog', 'WinEventLog:Security') + date_rex = r'\d{2}/\d{2}/\d{4} \d{2}:\d{2}:\d{2} [AP]M' + count = len(open(modified_file).readlines()) - i = 0 - file = fileinput.input(files=modified_file) - event = file[0] - start_position = 0 + i = 0 + file = fileinput.input(files=modified_file) + event = file[0] + start_position = 0 - for i in range(1, count): - line = file[i] - i = i + 1 - if re.match(date_rex, line): - data.append(event) - start_position = i - event = line - else: - event = event + line + for i in range(1, count): + line = file[i] + i = i + 1 + if re.match(date_rex, line): + data.append(event) + start_position = i + event = line + else: + event = event + line - data.append(event) - fileinput.close() + data.append(event) + fileinput.close() + elif sourcetype == "xmlwineventlog": + f = io.open(file_path, "r", encoding="utf-8") + for line in fileinput.input(files=f): + data.append(line) + f.close() return data From 98d9e927e73f54214f9e8d4da5b024cee29a7f11 Mon Sep 17 00:00:00 2001 From: P4T12ICK Date: Wed, 8 Dec 2021 12:08:42 +0100 Subject: [PATCH 6/9] BA detections --- bin/ssa-end-to-end-testing/modules/utils.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/bin/ssa-end-to-end-testing/modules/utils.py b/bin/ssa-end-to-end-testing/modules/utils.py index e9579e3326..9add3aa4cf 100644 --- a/bin/ssa-end-to-end-testing/modules/utils.py +++ b/bin/ssa-end-to-end-testing/modules/utils.py @@ -132,11 +132,9 @@ def read_data(file_path, sourcetype): data.append(event) fileinput.close() elif sourcetype == "xmlwineventlog": - f = io.open(file_path, "r", encoding="utf-8") - for line in fileinput.input(files=f): + for line in fileinput.input(files=file_path): data.append(line) - f.close() return data From 9f6fc87a59aa50d608feb92f2017cf294d20b826 Mon Sep 17 00:00:00 2001 From: P4T12ICK Date: Wed, 8 Dec 2021 12:21:40 +0100 Subject: [PATCH 7/9] BA detections --- bin/ssa-end-to-end-testing/modules/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/ssa-end-to-end-testing/modules/utils.py b/bin/ssa-end-to-end-testing/modules/utils.py index 9add3aa4cf..a803caa3b7 100644 --- a/bin/ssa-end-to-end-testing/modules/utils.py +++ b/bin/ssa-end-to-end-testing/modules/utils.py @@ -107,7 +107,7 @@ def replace_ssa_macros(source, sink, spl): def read_data(file_path, sourcetype): data = [] - if sourcetype == "WinEventLog:Security": + if sourcetype == "WinEventLog:Security" or sourcetype == "WinEventLog": data_manipulation = DataManipulation() modified_file = data_manipulation.manipulate_timestamp(file_path, 'xmlwineventlog', 'WinEventLog:Security') date_rex = r'\d{2}/\d{2}/\d{4} \d{2}:\d{2}:\d{2} [AP]M' From 7e1fbbc8adbe5f1940cb43fae8b12f5dc7e4e8b3 Mon Sep 17 00:00:00 2001 From: P4T12ICK Date: Wed, 8 Dec 2021 12:50:13 +0100 Subject: [PATCH 8/9] BA detections --- tests/endpoint/ssa___high_file_deletion_frequency.test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/endpoint/ssa___high_file_deletion_frequency.test.yml b/tests/endpoint/ssa___high_file_deletion_frequency.test.yml index 2204d122a0..d4b1a78b25 100644 --- a/tests/endpoint/ssa___high_file_deletion_frequency.test.yml +++ b/tests/endpoint/ssa___high_file_deletion_frequency.test.yml @@ -6,5 +6,5 @@ tests: description: Test for High File Deletion Frequency attack_data: - file_name: sysmon.log - data: https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1560.001/archive_tools/windows-security.log + data: https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1485/excessive_file_deletions/windows-sysmon.log source: xmlwineventlog From 2e4bebab223b9ece417c715c97cbf6bc1738cb45 Mon Sep 17 00:00:00 2001 From: P4T12ICK Date: Wed, 8 Dec 2021 15:27:44 +0100 Subject: [PATCH 9/9] BA detections --- ...xcessive_number_of_office_files_copied.yml | 54 +++++++++++++++++++ .../ssa___high_file_deletion_frequency.yml | 15 ++---- ...ive_number_of_office_files_copied.test.yml | 10 ++++ 3 files changed, 69 insertions(+), 10 deletions(-) create mode 100644 detections/endpoint/ssa___excessive_number_of_office_files_copied.yml create mode 100644 tests/endpoint/ssa___excessive_number_of_office_files_copied.test.yml diff --git a/detections/endpoint/ssa___excessive_number_of_office_files_copied.yml b/detections/endpoint/ssa___excessive_number_of_office_files_copied.yml new file mode 100644 index 0000000000..bd29f2cbbf --- /dev/null +++ b/detections/endpoint/ssa___excessive_number_of_office_files_copied.yml @@ -0,0 +1,54 @@ +name: Excessive Number of Office Files Copied +id: 3c6594a9-8df6-45a1-9357-d73b62083c63 +version: 1 +date: '2021-12-07' +author: Patrick Bareiss, Splunk +type: Anomaly +datamodel: +- Endpoint_Filesystem +description: This detection detects a high amount of office file copied. + This can be an indicator for a malicious insider. +search: '| from read_ssa_enriched_events() + | eval timestamp=parse_long(ucast(map_get(input_event, "_time"), "string", null)) + | eval action=ucast(map_get(input_event, "action"), "string", null), + process=ucast(map_get(input_event, "process"), "string", null), + file_name=ucast(map_get(input_event, "file_name"), "string", null), + file_path=ucast(map_get(input_event, "file_path"), "string", null), + dest_user_id=ucast(map_get(input_event, "dest_user_id"), "string", null), + dest_device_id=ucast(map_get(input_event, "dest_device_id"), "string", null) + | where "Endpoint_Filesystem" IN(_datamodels) + | where action="created" + | where like(file_name, "%.doc%") OR like(file_name, "%.xls%") OR like(file_name, "%.ppt%") + | stats count(file_name) AS count BY dest_user_id, dest_device_id, span(timestamp, 10m) + | where count > 20 + | eval start_time=window_start, end_time=window_end, entities=mvappend(dest_user_id, dest_device_id), body=create_map(["count", count]) + | 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` datamodel in the `Filesytem` node. +known_false_positives: user may copy a lot of office fies from one folder to another +references: [] +tags: + analytic_story: [] + confidence: 80 + context: + - Source:Endpoint + - Stage:Exfitration + dataset: + - https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1048.003/mass_file_creation/windows-sysmon.log + impact: 90 + kill_chain_phases: + - Exploitation + message: High number of files copied + mitre_attack_id: + - T1048.003 + product: + - Splunk Behavioral Analytics + required_fields: + - action + - process + - file_name + - file_path + risk_score: 72 + security_domain: endpoint + diff --git a/detections/endpoint/ssa___high_file_deletion_frequency.yml b/detections/endpoint/ssa___high_file_deletion_frequency.yml index b676a2cc0e..d20a68653e 100644 --- a/detections/endpoint/ssa___high_file_deletion_frequency.yml +++ b/detections/endpoint/ssa___high_file_deletion_frequency.yml @@ -64,17 +64,12 @@ tags: role: - Target product: - - Splunk Enterprise - - Splunk Enterprise Security - - Splunk Cloud + - Splunk Behavioral Analytics required_fields: - - EventCode - - TargetFilename - - Computer - - user - - Image - - ProcessID - - _time + - action + - process + - file_name + - file_path risk_score: 72 security_domain: endpoint diff --git a/tests/endpoint/ssa___excessive_number_of_office_files_copied.test.yml b/tests/endpoint/ssa___excessive_number_of_office_files_copied.test.yml new file mode 100644 index 0000000000..b78607f1a9 --- /dev/null +++ b/tests/endpoint/ssa___excessive_number_of_office_files_copied.test.yml @@ -0,0 +1,10 @@ +name: Excessive Number of Office Files Copied Unit Test +tests: + - name: Excessive Number of Office Files Copied + file: endpoint/ssa___excessive_number_of_office_files_copied.yml + pass_condition: '@count_gt(0)' + description: Test for Excessive Number of Office Files Copied + attack_data: + - file_name: sysmon.log + data: https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1048.003/mass_file_creation/windows-sysmon.log + source: xmlwineventlog