From cbfc4ca303882010992e980438020e2fbaaa0408 Mon Sep 17 00:00:00 2001 From: divious1 Date: Wed, 10 Feb 2021 20:03:49 -0500 Subject: [PATCH] skeleton --- bin/pretty_yaml.py | 72 +++++++++++++++++++ ...f_shadow_copy_with_wmic_and_powershell.yml | 3 + ...cessive_account_lockouts_from_endpoint.yml | 1 + .../detect_new_local_admin_account.yml | 1 + ...ulating_windows_services_registry_keys.yml | 6 ++ .../sc_exe_manipulating_windows_services.yml | 2 + .../ssa___first_time_seen_cmd_line.yml | 1 + ...system_information_discovery_detection.yml | 3 + 8 files changed, 89 insertions(+) create mode 100755 bin/pretty_yaml.py diff --git a/bin/pretty_yaml.py b/bin/pretty_yaml.py new file mode 100755 index 0000000000..68b575111e --- /dev/null +++ b/bin/pretty_yaml.py @@ -0,0 +1,72 @@ +#!/bin/python +from os import path, walk +import argparse +import yaml +REPO_PATH = '/home/jhernandez/splunk/security_content/detections' + +def pretty_yaml_detections(): + +def pretty_yaml(REPO_PATH, VERBOSE, objects): + + manifest_files = [] + types = ["endpoint", "application", "cloud", "deprecated", "experimental", "network", "web"] + for t in types: + for root, dirs, files in walk(REPO_PATH + "/" + t): + #for root, dirs, files in walk(REPO_PATH + "/"): + for file in files: + if file.endswith(".yml"): + manifest_files.append((path.join(root, file))) + for manifest_file in manifest_files: + pretty_yaml = dict() + print("processing manifest {0}".format(manifest_file)) + with open(manifest_file, 'r') as stream: + try: + object = list(yaml.safe_load_all(stream))[0] + except yaml.YAMLError as exc: + print(exc) + print("Error reading {0}".format(manifest_file)) + error = True + continue + + pretty_yaml['name'] = object['name'] + pretty_yaml['id'] = object['id'] + pretty_yaml['version'] = object['version'] + pretty_yaml['date'] = object['date'] + pretty_yaml['description'] = object['description'] + if 'how_to_implement' in object: + pretty_yaml['how_to_implement'] = object['how_to_implement'] + else: + pretty_yaml['how_to_implement'] = '' + pretty_yaml['type'] = object['type'] + pretty_yaml['search'] = object['search'] + pretty_yaml['author'] = object['author'] + if 'references' in object: + pretty_yaml['references'] = object['references'] + else: + pretty_yaml['references'] = [] + pretty_yaml['known_false_positives'] = object['known_false_positives'] + pretty_yaml['tags'] = object['tags'] + + + #with open(manifest_file, 'w') as file: + # documents = yaml.dump(object, file, default_flow_style=False, sort_keys=False) + print(yaml.dump(pretty_yaml,default_flow_style=False, sort_keys=False)) + +def main(args): + + parser = argparse.ArgumentParser(description="keeps yamls in security_content sorted and pretty printed with custom sort keys") + parser.add_argument("-p", "--path", required=True, help="path to security_content repo") + parser.add_argument("-v", "--verbose", required=False, default=False, action='store_true', help="prints verbose output") + + # parse them + args = parser.parse_args() + REPO_PATH = args.path + VERBOSE = args.verbose + + pretty_yaml_objects = ['macros','lookups','stories','detections','baselines','response_tasks','responses','deployments'] + for pretty_yaml_object in pretty_yaml_objects: + pretty_yaml(REPO_PATH, VERBOSE, pretty_yaml_object) + +if __name__ == "__main__": + main(sys.argv[1:]) + diff --git a/detections/endpoint/creation_of_shadow_copy_with_wmic_and_powershell.yml b/detections/endpoint/creation_of_shadow_copy_with_wmic_and_powershell.yml index dc0a05d2a5..7ae87fbfbf 100644 --- a/detections/endpoint/creation_of_shadow_copy_with_wmic_and_powershell.yml +++ b/detections/endpoint/creation_of_shadow_copy_with_wmic_and_powershell.yml @@ -7,6 +7,9 @@ known_false_positives: Legtimate administrator usage of wmic to create a shadow name: Creation of Shadow Copy with wmic and powershell references: - https://2017.zeronights.org/wp-content/uploads/materials/ZN17_Kheirkhabarov_Hunting_for_Credentials_Dumping_in_Windows_Environment.pdf +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 `Processes` node. search: '| tstats `security_content_summariesonly` count min(_time) as firstTime max(_time) as lastTime from datamodel=Endpoint.Processes where Processes.process_name=wmic* OR Processes.process_name=powershell* Processes.process=*shadowcopy* Processes.process=*create* diff --git a/detections/endpoint/detect_excessive_account_lockouts_from_endpoint.yml b/detections/endpoint/detect_excessive_account_lockouts_from_endpoint.yml index f59b709091..7107062d4a 100644 --- a/detections/endpoint/detect_excessive_account_lockouts_from_endpoint.yml +++ b/detections/endpoint/detect_excessive_account_lockouts_from_endpoint.yml @@ -20,6 +20,7 @@ id: c026e3dd-7e18-4abb-8f41-929e836efe74 known_false_positives: It's possible that a widely used system, such as a kiosk, could cause a large number of account lockouts. name: Detect Excessive Account Lockouts From Endpoint +references: [] search: '| tstats `security_content_summariesonly` count min(_time) as firstTime max(_time) as lastTime values(All_Changes.user) as user from datamodel=Change.All_Changes where nodename=All_Changes.Account_Management All_Changes.result="lockout" by All_Changes.dest diff --git a/detections/endpoint/detect_new_local_admin_account.yml b/detections/endpoint/detect_new_local_admin_account.yml index 10f088bea5..9b309dfac5 100644 --- a/detections/endpoint/detect_new_local_admin_account.yml +++ b/detections/endpoint/detect_new_local_admin_account.yml @@ -7,6 +7,7 @@ known_false_positives: The activity may be legitimate. For this reason, it's bes to verify the account with an administrator and ask whether there was a valid service request for the account creation. If your local administrator group name is not "Administrators", this search may generate an excessive number of false positives +how_to_implement: 'You must be ingesting Windows event logs using the Splunk Windows TA and collecting event code 4720 and 4732' name: Detect New Local Admin account references: [] search: '`wineventlog_security` EventCode=4720 OR (EventCode=4732 Group_Name=Administrators) diff --git a/detections/endpoint/reg_exe_manipulating_windows_services_registry_keys.yml b/detections/endpoint/reg_exe_manipulating_windows_services_registry_keys.yml index 254508329d..d11acd61cc 100644 --- a/detections/endpoint/reg_exe_manipulating_windows_services_registry_keys.yml +++ b/detections/endpoint/reg_exe_manipulating_windows_services_registry_keys.yml @@ -7,6 +7,12 @@ known_false_positives: It is unusual for a service to be created or modified by manipulating the registry. However, there may be legitimate instances of this behavior. It is important to validate and investigate, as appropriate. name: Reg exe Manipulating Windows Services Registry Keys +how_to_implement: To successfully implement this search, you must be ingesting data +that records registry activity from your hosts to populate the endpoint data model +in the registry node. This is typically populated via endpoint detection-and-response +products, such as Carbon Black or endpoint data sources, such as Sysmon. The data +used for this search is typically generated via logs that report reads and writes +to the registry. references: [] search: '| tstats `security_content_summariesonly` count min(_time) as firstTime max(_time) as lastTime values(Processes.process_name) as process_name values(Processes.parent_process_name) diff --git a/detections/endpoint/sc_exe_manipulating_windows_services.yml b/detections/endpoint/sc_exe_manipulating_windows_services.yml index b723def98b..dcd17bc503 100644 --- a/detections/endpoint/sc_exe_manipulating_windows_services.yml +++ b/detections/endpoint/sc_exe_manipulating_windows_services.yml @@ -7,6 +7,8 @@ known_false_positives: Using sc.exe to manipulate Windows services is uncommon. there may be legitimate instances of this behavior. It is important to validate and investigate as appropriate. name: Sc exe Manipulating Windows Services +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 `Processes` node. references: [] search: '| tstats `security_content_summariesonly` values(Processes.process) as process min(_time) as firstTime max(_time) as lastTime from datamodel=Endpoint.Processes diff --git a/detections/endpoint/ssa___first_time_seen_cmd_line.yml b/detections/endpoint/ssa___first_time_seen_cmd_line.yml index 0cdd233f34..1de5d11a12 100644 --- a/detections/endpoint/ssa___first_time_seen_cmd_line.yml +++ b/detections/endpoint/ssa___first_time_seen_cmd_line.yml @@ -17,6 +17,7 @@ known_false_positives: Legitimate programs can also use command-line arguments t is being executed. We recommend customizing the `first_time_seen_cmd_line_filter` macro to exclude legitimate parent_process_name name: First time seen command line argument - SSA +references: [] search: '| from read_ssa_enriched_events() | eval timestamp=parse_long(ucast(map_get(input_event, "_time"), "string", null)) | eval dest_user_id=ucast(map_get(input_event, "dest_user_id"), "string", null), diff --git a/detections/endpoint/system_information_discovery_detection.yml b/detections/endpoint/system_information_discovery_detection.yml index 1e88beec0b..ac25353a25 100644 --- a/detections/endpoint/system_information_discovery_detection.yml +++ b/detections/endpoint/system_information_discovery_detection.yml @@ -7,6 +7,9 @@ known_false_positives: Administrators debugging servers name: System Information Discovery Detection references: - https://oscp.infosecsanyam.in/priv-escalation/windows-priv-escalation +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 `Processes` node. search: '| tstats `security_content_summariesonly` count min(_time) as firstTime max(_time) as lastTime from datamodel=Endpoint.Processes where (Processes.process="*wmic* qfe*" OR Processes.process=*systeminfo* OR Processes.process=*hostname*) by Processes.user