From 6e4a5bfdf548675703c1f0ba7814bdd1105127d2 Mon Sep 17 00:00:00 2001 From: Lou Stella Date: Wed, 8 Dec 2021 12:20:10 -0600 Subject: [PATCH 01/32] Create ssa___anomalous_usage_of_account_credentials.yml --- ...anomalous_usage_of_account_credentials.yml | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 detections/experimental/endpoint/ssa___anomalous_usage_of_account_credentials.yml diff --git a/detections/experimental/endpoint/ssa___anomalous_usage_of_account_credentials.yml b/detections/experimental/endpoint/ssa___anomalous_usage_of_account_credentials.yml new file mode 100644 index 0000000000..191279fe48 --- /dev/null +++ b/detections/experimental/endpoint/ssa___anomalous_usage_of_account_credentials.yml @@ -0,0 +1,46 @@ +name: Anomalous Usage of Account Credentials +id: 629cbf9e-5785-11ec-9611-acde48001122 +version: 1 +date: '2021-12-07' +author: Lou Stella, Splunk +type: Anomaly +datamodel: +- Authentication +description: This is an anomaly generating detection looking for multiple interactive logins within a specific time period. +search: '| from read_ssa_enriched_events() | eval device=ucast(map_get(input_event, "dest_device_id"), "string", null), auth_type=ucast(map_get(input_event, "authentication_type"), "integer", null), timestamp=parse_long(ucast(map_get(input_event, "_time"), "string", null)), src_user=ucast(map_get(input_event, "src_user/WINDOWS_ACCOUNT_NAME"), "string", null), reason=ucast(map_get(input_event, "reason"), "string", null) | where auth_type=2 OR auth_type=11 | where reason = "success"| stats estdc(src_user) AS user_counter by device, span(timestamp, 1200s, 300s) | where user_counter>=2 | rename window_end AS timestamp | eval start_time=window_start, end_time=timestamp, entities=mvappend(device), body=create_map(["user_counter", user_counter, "device", device]) | into write_ssa_detected_events();' +how_to_implement: To successfully implement this detection, you need to be ingesting logon events from workstations. +known_false_positives: Shared workstations can cause false positives +references: +- https://attack.mitre.org/techniques/T1078/002/ +tags: + analytic_story: + - Insider Threat + kill_chain_phases: + - Privilege Escalation + - Lateral Movement + mitre_attack_id: + - T1078.002 + cis20: + - CIS 14 + nist: + - PR.AC + - DE.AE + product: + - Splunk Behavioral Analytics + required_fields: + - _time + security_domain: access + impact: 20 + confidence: 30 + risk_score: 6 + context: + - Source:Endpoint + - Stage:Credential Access + message: Multiple interactive logins detected on $device$ + risk_severity: low + observable: + - name: device + type: Hostname + role: + - Victim + From da2c9b74c3feb1c072e944bb8dca31cc35db62c7 Mon Sep 17 00:00:00 2001 From: Lou Stella Date: Wed, 8 Dec 2021 12:22:47 -0600 Subject: [PATCH 02/32] Update ssa___anomalous_usage_of_account_credentials.yml --- .../endpoint/ssa___anomalous_usage_of_account_credentials.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/detections/experimental/endpoint/ssa___anomalous_usage_of_account_credentials.yml b/detections/experimental/endpoint/ssa___anomalous_usage_of_account_credentials.yml index 191279fe48..85e7169ce4 100644 --- a/detections/experimental/endpoint/ssa___anomalous_usage_of_account_credentials.yml +++ b/detections/experimental/endpoint/ssa___anomalous_usage_of_account_credentials.yml @@ -6,7 +6,7 @@ author: Lou Stella, Splunk type: Anomaly datamodel: - Authentication -description: This is an anomaly generating detection looking for multiple interactive logins within a specific time period. +description: This is an anomaly generating detection looking for multiple interactive logins within a specific time period. An insider threat may attempt to steal colleagues credentials in low tech, undetectable methods, in order to gain access to additional information or to hide their own behavior. This should capture their attempted use of those credentials on a workstation. search: '| from read_ssa_enriched_events() | eval device=ucast(map_get(input_event, "dest_device_id"), "string", null), auth_type=ucast(map_get(input_event, "authentication_type"), "integer", null), timestamp=parse_long(ucast(map_get(input_event, "_time"), "string", null)), src_user=ucast(map_get(input_event, "src_user/WINDOWS_ACCOUNT_NAME"), "string", null), reason=ucast(map_get(input_event, "reason"), "string", null) | where auth_type=2 OR auth_type=11 | where reason = "success"| stats estdc(src_user) AS user_counter by device, span(timestamp, 1200s, 300s) | where user_counter>=2 | rename window_end AS timestamp | eval start_time=window_start, end_time=timestamp, entities=mvappend(device), body=create_map(["user_counter", user_counter, "device", device]) | into write_ssa_detected_events();' how_to_implement: To successfully implement this detection, you need to be ingesting logon events from workstations. known_false_positives: Shared workstations can cause false positives From 5841d0fcb8993a58f8adad514c37039fe872dfe7 Mon Sep 17 00:00:00 2001 From: patel-bhavin Date: Wed, 8 Dec 2021 17:05:32 -0800 Subject: [PATCH 03/32] first draft --- .../disable_defender_antivirus_registry.yml | 10 +-- ...___disable_defender_antivirus_registry.yml | 66 +++++++++++++++++++ ...sable_defender_antivirus_registry.test.yml | 15 +++++ 3 files changed, 86 insertions(+), 5 deletions(-) create mode 100644 detections/endpoint/ssa___disable_defender_antivirus_registry.yml create mode 100644 tests/endpoint/ssa___disable_defender_antivirus_registry.test.yml diff --git a/detections/endpoint/disable_defender_antivirus_registry.yml b/detections/endpoint/disable_defender_antivirus_registry.yml index 64c22443d4..bc365d77ff 100644 --- a/detections/endpoint/disable_defender_antivirus_registry.yml +++ b/detections/endpoint/disable_defender_antivirus_registry.yml @@ -12,11 +12,11 @@ description: This particular behavior is typically executed when an adversaries task modifications will occur. During triage, review parallel processes and identify any further file modifications. Endpoint should be isolated. search: '| tstats `security_content_summariesonly` count min(_time) as firstTime max(_time) - as lastTime from datamodel=Endpoint.Registry where Registry.registry_path = "*\\Policies\\Microsoft\\Windows - Defender*" Registry.registry_value_name = DisableAntiVirus Registry.registry_value_data - = 0x00000001 by Registry.dest Registry.user Registry.registry_path Registry.registry_value_name - Registry.registry_value_data | `drop_dm_object_name(Registry)` | `security_content_ctime(lastTime)` - | `security_content_ctime(firstTime)` | `disable_defender_antivirus_registry_filter`' + as lastTime from datamodel=Endpoint.Registry where Registry.registry_path = "*\\Policies\\Microsoft\\Windows Defender*" Registry.registry_key_name = DisableAntiVirus Registry.registry_value_name="DWORD (0x00000001)" by Registry.dest Registry.user Registry.registry_path Registry.registry_value_name Registry.registry_value_data +| `drop_dm_object_name(Registry)` +| `security_content_ctime(lastTime)` +| `security_content_ctime(firstTime)` +| `disable_defender_antivirus_registry_filter`' how_to_implement: To successfully implement this search, you need to be ingesting logs with the registry value name, registry path, and registry value data from your endpoints. If you are using Sysmon, you must have at least version 6.0.4 of the diff --git a/detections/endpoint/ssa___disable_defender_antivirus_registry.yml b/detections/endpoint/ssa___disable_defender_antivirus_registry.yml new file mode 100644 index 0000000000..91bca56165 --- /dev/null +++ b/detections/endpoint/ssa___disable_defender_antivirus_registry.yml @@ -0,0 +1,66 @@ +name: Disable Defender AntiVirus Registry +id: aa4f115a-3024-11ec-9987-acde48001122 +version: 1 +date: '2021-12-08' +author: Bhavin Patel, Splunk +type: TTP +datamodel: +- Endpoint +description: This particular behavior is typically executed when an adversaries or + malware gains access to an endpoint and beings to perform execution and to evade + detections. Usually, a batch (.bat) will be executed and multiple registry and scheduled + task modifications will occur. During triage, review parallel processes and identify + any further file modifications. Endpoint should be isolated. +search: '| tstats `security_content_summariesonly` count min(_time) as firstTime max(_time) + as lastTime from datamodel=Endpoint.Registry where Registry.registry_path = "*\\Policies\\Microsoft\\Windows + Defender*" Registry.registry_value_name = DisableAntiVirus Registry.registry_value_data + = 0x00000001 by Registry.dest Registry.user Registry.registry_path Registry.registry_value_name + Registry.registry_value_data | `drop_dm_object_name(Registry)` | `security_content_ctime(lastTime)` + | `security_content_ctime(firstTime)` | `disable_defender_antivirus_registry_filter`' +how_to_implement: To successfully implement this search, you need to be ingesting + logs with the registry value name, registry path, and registry value data from your + endpoints. If you are using Sysmon, you must have at least version 6.0.4 of the + Sysmon TA. +known_false_positives: admin or user may choose to disable windows defender product +references: +- https://thedfirreport.com/2021/10/18/icedid-to-xinglocker-ransomware-in-24-hours/ +tags: + analytic_story: + - IceID + automated_detection_testing: passed + confidence: 70 + context: + - Source:Endpoint + - Stage:Defense Evasion + dataset: + - https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/malware/icedid/disable_av/sysmon.log + impact: 70 + kill_chain_phases: + - Exploitation + message: modified/added/deleted registry entry $registry_path$ in $dest$ + mitre_attack_id: + - T1562.001 + - T1562 + observable: + - name: dest + type: Hostname + role: + - Victim + - name: user + type: user + role: + - Victim + product: + - Splunk Enterprise + - Splunk Enterprise Security + - Splunk Cloud + required_fields: + - _time + - Registry.dest + - Registry.user + - Registry.registry_value_name + - Registry.registry_key_name + - Registry.registry_path + - Registry.registry_value_data + risk_score: 49 + security_domain: endpoint diff --git a/tests/endpoint/ssa___disable_defender_antivirus_registry.test.yml b/tests/endpoint/ssa___disable_defender_antivirus_registry.test.yml new file mode 100644 index 0000000000..7c2d37bbf5 --- /dev/null +++ b/tests/endpoint/ssa___disable_defender_antivirus_registry.test.yml @@ -0,0 +1,15 @@ +name: Disable Defender AntiVirus Registry Unit Test - SSA +tests: + - name: Disable Defender AntiVirus Registry + file: endpoint/ssa___disable_defender_antivirus_registry.yml + pass_condition: '@count_gt(0)' + description: Test for Disable Defender AntiVirus Registry + attack_data: + - file_name: sysmon.log + data: https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/malware/icedid/disable_av/sysmon.log + source: XmlWinEventLog:Microsoft-Windows-Sysmon/Operational + sourcetype: xmlwineventlog + + + + From 9a5c2f62362883a6f5b975981144dfa1d442f1dc Mon Sep 17 00:00:00 2001 From: patel-bhavin Date: Wed, 8 Dec 2021 17:22:31 -0800 Subject: [PATCH 04/32] datamodel --- ...___disable_defender_antivirus_registry.yml | 33 ++++++++++++------- 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/detections/endpoint/ssa___disable_defender_antivirus_registry.yml b/detections/endpoint/ssa___disable_defender_antivirus_registry.yml index 91bca56165..d63cd977fa 100644 --- a/detections/endpoint/ssa___disable_defender_antivirus_registry.yml +++ b/detections/endpoint/ssa___disable_defender_antivirus_registry.yml @@ -5,23 +5,34 @@ date: '2021-12-08' author: Bhavin Patel, Splunk type: TTP datamodel: -- Endpoint +- Endpoint_Registry description: This particular behavior is typically executed when an adversaries or malware gains access to an endpoint and beings to perform execution and to evade detections. Usually, a batch (.bat) will be executed and multiple registry and scheduled task modifications will occur. During triage, review parallel processes and identify any further file modifications. Endpoint should be isolated. -search: '| tstats `security_content_summariesonly` count min(_time) as firstTime max(_time) - as lastTime from datamodel=Endpoint.Registry where Registry.registry_path = "*\\Policies\\Microsoft\\Windows - Defender*" Registry.registry_value_name = DisableAntiVirus Registry.registry_value_data - = 0x00000001 by Registry.dest Registry.user Registry.registry_path Registry.registry_value_name - Registry.registry_value_data | `drop_dm_object_name(Registry)` | `security_content_ctime(lastTime)` - | `security_content_ctime(firstTime)` | `disable_defender_antivirus_registry_filter`' +search: '| from read_ssa_enriched_events() +| 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_key_name=lower(ucast(map_get(input_event, "registry_key_name"), "string", + null)), registry_value_data=ucast(map_get(input_event, "registry_value_data"), "string", null), + process_guid=ucast(map_get(input_event, "process_guid"), "string", + null), + event_id=ucast(map_get(input_event, "event_id"), "string", null) +| where like(registry_path, "%\\Policies\\Microsoft\\Windows Defender%") + AND registry_key_name="DisableAntiVirus" AND registry_value_data="(0x00000001)" +| 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)), + body=create_map( + [ "event_id", event_id, "registry_path", registry_path, "registry_key_name", + registry_key_name, "process_guid", process_guid,"registry_value_data",registry_value_data]) +| into write_ssa_detected_events();' how_to_implement: To successfully implement this search, you need to be ingesting logs with the registry value name, registry path, and registry value data from your endpoints. If you are using Sysmon, you must have at least version 6.0.4 of the Sysmon TA. -known_false_positives: admin or user may choose to disable windows defender product +known_false_positives: Admin or user may choose to disable windows defender product references: - https://thedfirreport.com/2021/10/18/icedid-to-xinglocker-ransomware-in-24-hours/ tags: @@ -37,7 +48,7 @@ tags: impact: 70 kill_chain_phases: - Exploitation - message: modified/added/deleted registry entry $registry_path$ in $dest$ + message: Modified/added/deleted registry entry $registry_path$ in $dest$ mitre_attack_id: - T1562.001 - T1562 @@ -51,9 +62,7 @@ tags: role: - Victim product: - - Splunk Enterprise - - Splunk Enterprise Security - - Splunk Cloud + - Splunk Behavioral Analytics required_fields: - _time - Registry.dest From 988f5d157a2049ea9816356af1f2513782eb745c Mon Sep 17 00:00:00 2001 From: Lou Stella Date: Thu, 6 Jan 2022 16:08:08 -0600 Subject: [PATCH 05/32] Created test dataset & moved detection out of experimental --- .../ssa___anomalous_usage_of_account_credentials.yml | 4 +++- .../ssa___anomalous_usage_of_account_credentials.yml | 10 ++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) rename detections/{experimental => }/endpoint/ssa___anomalous_usage_of_account_credentials.yml (75%) create mode 100644 tests/endpoint/ssa___anomalous_usage_of_account_credentials.yml diff --git a/detections/experimental/endpoint/ssa___anomalous_usage_of_account_credentials.yml b/detections/endpoint/ssa___anomalous_usage_of_account_credentials.yml similarity index 75% rename from detections/experimental/endpoint/ssa___anomalous_usage_of_account_credentials.yml rename to detections/endpoint/ssa___anomalous_usage_of_account_credentials.yml index 85e7169ce4..5b33b1093d 100644 --- a/detections/experimental/endpoint/ssa___anomalous_usage_of_account_credentials.yml +++ b/detections/endpoint/ssa___anomalous_usage_of_account_credentials.yml @@ -7,7 +7,7 @@ type: Anomaly datamodel: - Authentication description: This is an anomaly generating detection looking for multiple interactive logins within a specific time period. An insider threat may attempt to steal colleagues credentials in low tech, undetectable methods, in order to gain access to additional information or to hide their own behavior. This should capture their attempted use of those credentials on a workstation. -search: '| from read_ssa_enriched_events() | eval device=ucast(map_get(input_event, "dest_device_id"), "string", null), auth_type=ucast(map_get(input_event, "authentication_type"), "integer", null), timestamp=parse_long(ucast(map_get(input_event, "_time"), "string", null)), src_user=ucast(map_get(input_event, "src_user/WINDOWS_ACCOUNT_NAME"), "string", null), reason=ucast(map_get(input_event, "reason"), "string", null) | where auth_type=2 OR auth_type=11 | where reason = "success"| stats estdc(src_user) AS user_counter by device, span(timestamp, 1200s, 300s) | where user_counter>=2 | rename window_end AS timestamp | eval start_time=window_start, end_time=timestamp, entities=mvappend(device), body=create_map(["user_counter", user_counter, "device", device]) | into write_ssa_detected_events();' +search: '| from read_ssa_enriched_events() | eval device=ucast(map_get(input_event, "dest_device_id"), "string", null), auth_type=ucast(map_get(input_event, "authentication_type"), "integer", null), timestamp=parse_long(ucast(map_get(input_event, "_time"), "string", null)), src_user=ucast(map_get(input_event, "src_user/WINDOWS_ACCOUNT_NAME"), "string", null), reason=ucast(map_get(input_event, "reason"), "string", null) | where auth_type=2 OR auth_type=11 | where reason = "success" | where src_user NOT in("DWM-*", "SYSTEM", "ANONYMOUS LOGON") | stats estdc(src_user) AS user_counter by device, span(timestamp, 1200s, 300s) | where user_counter>=2 | rename window_end AS timestamp | eval start_time=window_start, end_time=timestamp, entities=mvappend(device), body=create_map(["user_counter", user_counter, "device", device]) | into write_ssa_detected_events();' how_to_implement: To successfully implement this detection, you need to be ingesting logon events from workstations. known_false_positives: Shared workstations can cause false positives references: @@ -27,6 +27,8 @@ tags: - DE.AE product: - Splunk Behavioral Analytics + dataset: + - https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1078.002/account_login/windows-security.log required_fields: - _time security_domain: access diff --git a/tests/endpoint/ssa___anomalous_usage_of_account_credentials.yml b/tests/endpoint/ssa___anomalous_usage_of_account_credentials.yml new file mode 100644 index 0000000000..b1c41573f8 --- /dev/null +++ b/tests/endpoint/ssa___anomalous_usage_of_account_credentials.yml @@ -0,0 +1,10 @@ +name: Anomalous Usage of Account Credentials Unit Test +tests: + - name: Anomalous Usage of Account Credentials + file: endpoint/ssa___anomalous_usage_of_account_credentials.yml + pass_condition: '@count_gt(0)' + description: Test for Anomalous usage of Account Credentials + attack_data: + - file_name: windows-security.log + data: https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1078.002/account_login/windows-security.log + source: WinEventLog:Security From b1a285b483e856b486522a57c55c0f8711ba096f Mon Sep 17 00:00:00 2001 From: Lou Stella Date: Tue, 11 Jan 2022 11:34:26 -0600 Subject: [PATCH 06/32] Renamed test --- ....yml => ssa___anomalous_usage_of_account_credentials.test.yml} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename tests/endpoint/{ssa___anomalous_usage_of_account_credentials.yml => ssa___anomalous_usage_of_account_credentials.test.yml} (100%) diff --git a/tests/endpoint/ssa___anomalous_usage_of_account_credentials.yml b/tests/endpoint/ssa___anomalous_usage_of_account_credentials.test.yml similarity index 100% rename from tests/endpoint/ssa___anomalous_usage_of_account_credentials.yml rename to tests/endpoint/ssa___anomalous_usage_of_account_credentials.test.yml From 0535389f2348b42145e0c00e3e44fb05ecc9775b Mon Sep 17 00:00:00 2001 From: Lou Stella Date: Tue, 11 Jan 2022 12:44:08 -0600 Subject: [PATCH 07/32] Tweaked detection --- .../endpoint/ssa___anomalous_usage_of_account_credentials.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/detections/endpoint/ssa___anomalous_usage_of_account_credentials.yml b/detections/endpoint/ssa___anomalous_usage_of_account_credentials.yml index 5b33b1093d..f579c02a7f 100644 --- a/detections/endpoint/ssa___anomalous_usage_of_account_credentials.yml +++ b/detections/endpoint/ssa___anomalous_usage_of_account_credentials.yml @@ -7,7 +7,7 @@ type: Anomaly datamodel: - Authentication description: This is an anomaly generating detection looking for multiple interactive logins within a specific time period. An insider threat may attempt to steal colleagues credentials in low tech, undetectable methods, in order to gain access to additional information or to hide their own behavior. This should capture their attempted use of those credentials on a workstation. -search: '| from read_ssa_enriched_events() | eval device=ucast(map_get(input_event, "dest_device_id"), "string", null), auth_type=ucast(map_get(input_event, "authentication_type"), "integer", null), timestamp=parse_long(ucast(map_get(input_event, "_time"), "string", null)), src_user=ucast(map_get(input_event, "src_user/WINDOWS_ACCOUNT_NAME"), "string", null), reason=ucast(map_get(input_event, "reason"), "string", null) | where auth_type=2 OR auth_type=11 | where reason = "success" | where src_user NOT in("DWM-*", "SYSTEM", "ANONYMOUS LOGON") | stats estdc(src_user) AS user_counter by device, span(timestamp, 1200s, 300s) | where user_counter>=2 | rename window_end AS timestamp | eval start_time=window_start, end_time=timestamp, entities=mvappend(device), body=create_map(["user_counter", user_counter, "device", device]) | into write_ssa_detected_events();' +search: '| from read_ssa_enriched_events() | eval device=ucast(map_get(input_event, "dest_device_id"), "string", null), auth_type=ucast(map_get(input_event, "authentication_type"), "string", null), timestamp=parse_long(ucast(map_get(input_event, "_time"), "string", null)), src_user=ucast(map_get(input_event, "src_user/WINDOWS_ACCOUNT_NAME"), "string", null), reason=ucast(map_get(input_event, "reason"), "string", null) | where auth_type=2 OR auth_type=11 | where reason = "success" | where src_user NOT in("DWM-*", "SYSTEM", "ANONYMOUS LOGON") | stats estdc(src_user) AS user_counter by device, span(timestamp, 1200s, 300s) | where user_counter>=2 | rename window_end AS timestamp | eval start_time=window_start, end_time=timestamp, entities=mvappend(device), body=create_map(["user_counter", user_counter, "device", device]) | into write_ssa_detected_events();' how_to_implement: To successfully implement this detection, you need to be ingesting logon events from workstations. known_false_positives: Shared workstations can cause false positives references: From e7f1eff711893d735e366a899916ddb34427742c Mon Sep 17 00:00:00 2001 From: Lou Stella Date: Tue, 11 Jan 2022 13:16:19 -0600 Subject: [PATCH 08/32] fixing field names --- .../endpoint/ssa___anomalous_usage_of_account_credentials.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/detections/endpoint/ssa___anomalous_usage_of_account_credentials.yml b/detections/endpoint/ssa___anomalous_usage_of_account_credentials.yml index f579c02a7f..ff041c1a3b 100644 --- a/detections/endpoint/ssa___anomalous_usage_of_account_credentials.yml +++ b/detections/endpoint/ssa___anomalous_usage_of_account_credentials.yml @@ -7,7 +7,7 @@ type: Anomaly datamodel: - Authentication description: This is an anomaly generating detection looking for multiple interactive logins within a specific time period. An insider threat may attempt to steal colleagues credentials in low tech, undetectable methods, in order to gain access to additional information or to hide their own behavior. This should capture their attempted use of those credentials on a workstation. -search: '| from read_ssa_enriched_events() | eval device=ucast(map_get(input_event, "dest_device_id"), "string", null), auth_type=ucast(map_get(input_event, "authentication_type"), "string", null), timestamp=parse_long(ucast(map_get(input_event, "_time"), "string", null)), src_user=ucast(map_get(input_event, "src_user/WINDOWS_ACCOUNT_NAME"), "string", null), reason=ucast(map_get(input_event, "reason"), "string", null) | where auth_type=2 OR auth_type=11 | where reason = "success" | where src_user NOT in("DWM-*", "SYSTEM", "ANONYMOUS LOGON") | stats estdc(src_user) AS user_counter by device, span(timestamp, 1200s, 300s) | where user_counter>=2 | rename window_end AS timestamp | eval start_time=window_start, end_time=timestamp, entities=mvappend(device), body=create_map(["user_counter", user_counter, "device", device]) | into write_ssa_detected_events();' +search: '| from read_ssa_enriched_events() | eval device=ucast(map_get(input_event, "dest_device_id"), "string", null), auth_type=ucast(map_get(input_event, "authentication_type"), "string", null), timestamp=parse_long(ucast(map_get(input_event, "_time"), "string", null)), src_user=ucast(map_get(input_event, "endpoint_user_windows_account_names"), "string", null), reason=ucast(map_get(input_event, "reason"), "string", null) | where auth_type="2" OR auth_type="11" | where reason = "success" | where src_user NOT in("DWM-*", "SYSTEM", "ANONYMOUS LOGON") | stats estdc(src_user) AS user_counter by device, span(timestamp, 1200s, 300s) | where user_counter>=2 | rename window_end AS timestamp | eval start_time=window_start, end_time=timestamp, entities=mvappend(device), body=create_map(["user_counter", user_counter, "device", device]) | into write_ssa_detected_events();' how_to_implement: To successfully implement this detection, you need to be ingesting logon events from workstations. known_false_positives: Shared workstations can cause false positives references: From 14461f46ffed04aaf995046d40ae91f36f1eb557 Mon Sep 17 00:00:00 2001 From: Lou Stella Date: Tue, 11 Jan 2022 16:44:49 -0600 Subject: [PATCH 09/32] modifying window --- .../endpoint/ssa___anomalous_usage_of_account_credentials.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/detections/endpoint/ssa___anomalous_usage_of_account_credentials.yml b/detections/endpoint/ssa___anomalous_usage_of_account_credentials.yml index ff041c1a3b..beb82bc48b 100644 --- a/detections/endpoint/ssa___anomalous_usage_of_account_credentials.yml +++ b/detections/endpoint/ssa___anomalous_usage_of_account_credentials.yml @@ -7,7 +7,7 @@ type: Anomaly datamodel: - Authentication description: This is an anomaly generating detection looking for multiple interactive logins within a specific time period. An insider threat may attempt to steal colleagues credentials in low tech, undetectable methods, in order to gain access to additional information or to hide their own behavior. This should capture their attempted use of those credentials on a workstation. -search: '| from read_ssa_enriched_events() | eval device=ucast(map_get(input_event, "dest_device_id"), "string", null), auth_type=ucast(map_get(input_event, "authentication_type"), "string", null), timestamp=parse_long(ucast(map_get(input_event, "_time"), "string", null)), src_user=ucast(map_get(input_event, "endpoint_user_windows_account_names"), "string", null), reason=ucast(map_get(input_event, "reason"), "string", null) | where auth_type="2" OR auth_type="11" | where reason = "success" | where src_user NOT in("DWM-*", "SYSTEM", "ANONYMOUS LOGON") | stats estdc(src_user) AS user_counter by device, span(timestamp, 1200s, 300s) | where user_counter>=2 | rename window_end AS timestamp | eval start_time=window_start, end_time=timestamp, entities=mvappend(device), body=create_map(["user_counter", user_counter, "device", device]) | into write_ssa_detected_events();' +search: '| from read_ssa_enriched_events() | eval device=ucast(map_get(input_event, "dest_device_id"), "string", null), auth_type=ucast(map_get(input_event, "authentication_type"), "integer", null), timestamp=parse_long(ucast(map_get(input_event, "_time"), "string", null)), src_user=ucast(map_get(input_event, "dest_user_original_artifact"), "string", null), reason=ucast(map_get(input_event, "reason"), "string", null) | where auth_type=2 OR auth_type=11 | where reason = "success" | where src_user NOT in("DWM-*", "SYSTEM", "ANONYMOUS LOGON") | stats estdc(src_user) AS user_counter by device, span(timestamp, 300s, 300s) | where user_counter>=2 | rename window_end AS timestamp | eval start_time=window_start, end_time=timestamp, entities=mvappend(device), body=create_map(["user_counter", user_counter, "device", device]) | into write_ssa_detected_events();' how_to_implement: To successfully implement this detection, you need to be ingesting logon events from workstations. known_false_positives: Shared workstations can cause false positives references: From 167574e8926a3db3fdcf83514d9640aed785c58d Mon Sep 17 00:00:00 2001 From: Lou Stella Date: Wed, 19 Jan 2022 17:35:10 -0600 Subject: [PATCH 10/32] tweaked search --- .../endpoint/ssa___anomalous_usage_of_account_credentials.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/detections/endpoint/ssa___anomalous_usage_of_account_credentials.yml b/detections/endpoint/ssa___anomalous_usage_of_account_credentials.yml index beb82bc48b..8c74a30736 100644 --- a/detections/endpoint/ssa___anomalous_usage_of_account_credentials.yml +++ b/detections/endpoint/ssa___anomalous_usage_of_account_credentials.yml @@ -5,9 +5,9 @@ date: '2021-12-07' author: Lou Stella, Splunk type: Anomaly datamodel: -- Authentication +- Endpoint_Processes description: This is an anomaly generating detection looking for multiple interactive logins within a specific time period. An insider threat may attempt to steal colleagues credentials in low tech, undetectable methods, in order to gain access to additional information or to hide their own behavior. This should capture their attempted use of those credentials on a workstation. -search: '| from read_ssa_enriched_events() | eval device=ucast(map_get(input_event, "dest_device_id"), "string", null), auth_type=ucast(map_get(input_event, "authentication_type"), "integer", null), timestamp=parse_long(ucast(map_get(input_event, "_time"), "string", null)), src_user=ucast(map_get(input_event, "dest_user_original_artifact"), "string", null), reason=ucast(map_get(input_event, "reason"), "string", null) | where auth_type=2 OR auth_type=11 | where reason = "success" | where src_user NOT in("DWM-*", "SYSTEM", "ANONYMOUS LOGON") | stats estdc(src_user) AS user_counter by device, span(timestamp, 300s, 300s) | where user_counter>=2 | rename window_end AS timestamp | eval start_time=window_start, end_time=timestamp, entities=mvappend(device), body=create_map(["user_counter", user_counter, "device", device]) | into write_ssa_detected_events();' +search: '| from read_ssa_enriched_events() | eval device=ucast(map_get(input_event, "dest_device_id"), "string", null), auth_type=ucast(map_get(input_event, "authentication_type"), "string", null), timestamp=parse_long(ucast(map_get(input_event, "_time"), "string", null)), src_user=ucast(map_get(input_event, "dest_user_original_artifact"), "string", null), signature_id=ucast(map_get(input_event, "EventCode"), "string", null) | where signature_id="4624" | where auth_type="2" OR auth_type="11" | where NOT (src_user="SYSTEM") AND NOT (src_user="ANONYMOUS LOGON") | stats estdc(src_user) AS user_counter by device, span(timestamp, 600s, 300s) | where user_counter>=2 | rename window_end AS timestamp | eval start_time=window_start, end_time=timestamp, entities=mvappend(device), body=create_map(["user_counter", user_counter, "device", device]) | into write_ssa_detected_events();' how_to_implement: To successfully implement this detection, you need to be ingesting logon events from workstations. known_false_positives: Shared workstations can cause false positives references: From b59380d3249298b81c1916adaa42cbba67238094 Mon Sep 17 00:00:00 2001 From: Michael Hart Date: Wed, 19 Jan 2022 20:02:42 -0500 Subject: [PATCH 11/32] Potentially malicious execution on command line --- ...entially_malicious_code_on_commandline.yml | 47 +++++++++++++++++++ ...licious_code_on_cmdline_tokenize_score.yml | 3 ++ ...lly_malicious_code_on_commandline.test.yml | 12 +++++ 3 files changed, 62 insertions(+) create mode 100644 detections/endpoint/potentially_malicious_code_on_commandline.yml create mode 100644 macros/potentially_malicious_code_on_cmdline_tokenize_score.yml create mode 100644 tests/endpoint/potentially_malicious_code_on_commandline.test.yml diff --git a/detections/endpoint/potentially_malicious_code_on_commandline.yml b/detections/endpoint/potentially_malicious_code_on_commandline.yml new file mode 100644 index 0000000000..95fcec5db7 --- /dev/null +++ b/detections/endpoint/potentially_malicious_code_on_commandline.yml @@ -0,0 +1,47 @@ +name: Potentially malicious code on commandline +id: 9c53c446-757e-11ec-871d-acde48001122 +version: 1 +date: '2022-01-14' +author: Michael Hart, Splunk +type: Anomaly +datamodel: +- Endpoint +description: Uses machine learning to detect potentially malicious command lines +search: '| tstats count from datamodel="Endpoint.Processes" by Processes.process | `drop_dm_object_name(Processes)` | `unusual_commandline_detection_tokenizer`' +how_to_implement: UPDATE_HOW_TO_IMPLEMENT +known_false_positives: UPDATE_KNOWN_FALSE_POSITIVES +references: +- +tags: + analytic_story: + - Suspicious Command-Line Executions + dataset: + - https://github.com/splunk/attack_data/blob/master/datasets/attack_techniques/T1059.001/malicious_cmd_line_samples/windows-sysmon.log + kill_chain_phases: + - Exploitation + mitre_attack_id: + - T1059.001 + - T1059.003 + product: + - Splunk Enterprise + - Splunk Enterprise Security + - Splunk Cloud + required_fields: + - _time + security_domain: endpoint + impact: 60 + confidence: 20 + risk_score: 12 + context: + - source:endpoint + - stage:Execution + message: Unusual commandline execution with hallmarks of malicious activity found $Message$ + observable: + - name: ComputerName + type: Hostname + role: + - Victim + - name: User + type: User + role: + - Victim \ No newline at end of file diff --git a/macros/potentially_malicious_code_on_cmdline_tokenize_score.yml b/macros/potentially_malicious_code_on_cmdline_tokenize_score.yml new file mode 100644 index 0000000000..2eaa5b0ee6 --- /dev/null +++ b/macros/potentially_malicious_code_on_cmdline_tokenize_score.yml @@ -0,0 +1,3 @@ +definition: eval orig_process=process, process=replace(lower(process), "`", "") | makemv tokenizer="([\w\d\-]+)" process | eval unusual_cmdline_feature_for=if(match(process, "^for$"), mvcount(mvfilter(match(process, "^for$"))), 0), unusual_cmdline_feature_netsh=if(match(process, "^netsh$"), mvcount(mvfilter(match(process, "^netsh$"))), 0), unusual_cmdline_feature_readbytes=if(match(process, "^readbytes$"), mvcount(mvfilter(match(process, "^readbytes$"))), 0), unusual_cmdline_feature_set=if(match(process, "^set$"), mvcount(mvfilter(match(process, "^set$"))), 0), unusual_cmdline_feature_unrestricted=if(match(process, "^unrestricted$"), mvcount(mvfilter(match(process, "^unrestricted$"))), 0), unusual_cmdline_feature_winstations=if(match(process, "^winstations$"), mvcount(mvfilter(match(process, "^winstations$"))), 0), unusual_cmdline_feature_-value=if(match(process, "^-value$"), mvcount(mvfilter(match(process, "^-value$"))), 0), unusual_cmdline_feature_compression=if(match(process, "^compression$"), mvcount(mvfilter(match(process, "^compression$"))), 0), unusual_cmdline_feature_server=if(match(process, "^server$"), mvcount(mvfilter(match(process, "^server$"))), 0), unusual_cmdline_feature_set-mppreference=if(match(process, "^set-mppreference$"), mvcount(mvfilter(match(process, "^set-mppreference$"))), 0), unusual_cmdline_feature_terminal=if(match(process, "^terminal$"), mvcount(mvfilter(match(process, "^terminal$"))), 0), unusual_cmdline_feature_-name=if(match(process, "^-name$"), mvcount(mvfilter(match(process, "^-name$"))), 0), unusual_cmdline_feature_catch=if(match(process, "^catch$"), mvcount(mvfilter(match(process, "^catch$"))), 0), unusual_cmdline_feature_get-wmiobject=if(match(process, "^get-wmiobject$"), mvcount(mvfilter(match(process, "^get-wmiobject$"))), 0), unusual_cmdline_feature_hklm=if(match(process, "^hklm$"), mvcount(mvfilter(match(process, "^hklm$"))), 0), unusual_cmdline_feature_streamreader=if(match(process, "^streamreader$"), mvcount(mvfilter(match(process, "^streamreader$"))), 0), unusual_cmdline_feature_system32=if(match(process, "^system32$"), mvcount(mvfilter(match(process, "^system32$"))), 0), unusual_cmdline_feature_username=if(match(process, "^username$"), mvcount(mvfilter(match(process, "^username$"))), 0), unusual_cmdline_feature_webrequest=if(match(process, "^webrequest$"), mvcount(mvfilter(match(process, "^webrequest$"))), 0), unusual_cmdline_feature_count=if(match(process, "^count$"), mvcount(mvfilter(match(process, "^count$"))), 0), unusual_cmdline_feature_webclient=if(match(process, "^webclient$"), mvcount(mvfilter(match(process, "^webclient$"))), 0), unusual_cmdline_feature_writeallbytes=if(match(process, "^writeallbytes$"), mvcount(mvfilter(match(process, "^writeallbytes$"))), 0), unusual_cmdline_feature_convert=if(match(process, "^convert$"), mvcount(mvfilter(match(process, "^convert$"))), 0), unusual_cmdline_feature_create=if(match(process, "^create$"), mvcount(mvfilter(match(process, "^create$"))), 0), unusual_cmdline_feature_function=if(match(process, "^function$"), mvcount(mvfilter(match(process, "^function$"))), 0), unusual_cmdline_feature_net=if(match(process, "^net$"), mvcount(mvfilter(match(process, "^net$"))), 0), unusual_cmdline_feature_com=if(match(process, "^com$"), mvcount(mvfilter(match(process, "^com$"))), 0), unusual_cmdline_feature_http=if(match(process, "^http$"), mvcount(mvfilter(match(process, "^http$"))), 0), unusual_cmdline_feature_io=if(match(process, "^io$"), mvcount(mvfilter(match(process, "^io$"))), 0), unusual_cmdline_feature_system=if(match(process, "^system$"), mvcount(mvfilter(match(process, "^system$"))), 0), unusual_cmdline_feature_new-object=if(match(process, "^new-object$"), mvcount(mvfilter(match(process, "^new-object$"))), 0), unusual_cmdline_feature_if=if(match(process, "^if$"), mvcount(mvfilter(match(process, "^if$"))), 0), unusual_cmdline_feature_threading=if(match(process, "^threading$"), mvcount(mvfilter(match(process, "^threading$"))), 0), unusual_cmdline_feature_mutex=if(match(process, "^mutex$"), mvcount(mvfilter(match(process, "^mutex$"))), 0), unusual_cmdline_feature_cryptography=if(match(process, "^cryptography$"), mvcount(mvfilter(match(process, "^cryptography$"))), 0), unusual_cmdline_feature_computehash=if(match(process, "^computehash$"), mvcount(mvfilter(match(process, "^computehash$"))), 0) | apply unusual_commandline_detection | eval score='predicted(unusual_cmdline_logits)', process=orig_process | fields - unusual_cmdline* predicted(unusual_cmdline_logits) orig_process +description: Performs the tokenization and application of the malicious commandline classifier +name: potentially_malicious_code_on_cmdline_tokenize_score \ No newline at end of file diff --git a/tests/endpoint/potentially_malicious_code_on_commandline.test.yml b/tests/endpoint/potentially_malicious_code_on_commandline.test.yml new file mode 100644 index 0000000000..2f26f5d856 --- /dev/null +++ b/tests/endpoint/potentially_malicious_code_on_commandline.test.yml @@ -0,0 +1,12 @@ +name: Potentially malicious code on commandline Unit Test +tests: +- name: Potentially malicious code on commandline + file: endpoint/potentially_malicious_code_on_commandline.yml + pass_condition: '| stats count | where count > 0' + earliest_time: '-24h' + latest_time: 'now' + attack_data: + - file_name: UPDATE_FILE_NAME + data: UPDATE_DATASET_URL + source: UPDATE_SPLUNK_SOURCE + sourcetype: UPDATE_SPLUNK_SOURCETYPE \ No newline at end of file From 82e6efb4662f9d1a5fc899b0b82a356995041f17 Mon Sep 17 00:00:00 2001 From: Michael Hart Date: Wed, 19 Jan 2022 20:04:16 -0500 Subject: [PATCH 12/32] Adding in model lookup file --- lookups/__mlspl_unusual_commandline_detection.mlmodel | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 lookups/__mlspl_unusual_commandline_detection.mlmodel diff --git a/lookups/__mlspl_unusual_commandline_detection.mlmodel b/lookups/__mlspl_unusual_commandline_detection.mlmodel new file mode 100644 index 0000000000..d561509925 --- /dev/null +++ b/lookups/__mlspl_unusual_commandline_detection.mlmodel @@ -0,0 +1,2 @@ +algo,model,options +LinearRegression,"{""__mlspl_type"": [""algos.LinearRegression"", ""LinearRegression""], ""dict"": {""estimator"": {""__mlspl_type"": [""sklearn.linear_model.base"", ""LinearRegression""], ""dict"": {""fit_intercept"": true, ""normalize"": false, ""copy_X"": true, ""n_jobs"": null, ""intercept_"": -1.2124304031951825, ""coef_"": {""__mlspl_type"": [""numpy"", ""ndarray""], ""npy"": ""k05VTVBZAQB2AHsnZGVzY3InOiAnPGY4JywgJ2ZvcnRyYW5fb3JkZXInOiBGYWxzZSwgJ3NoYXBlJzogKDM2LCksIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIApreM9kKtnhP0TDf2w1t+I/3qDHjxK61j8UkPlxGST1v/rMDbO+a8e/iv8JpC2l5T+6dz+pdS3nP0mN7wQ8eO0/UqU3sakDyD9ncnkR3LHzP/6iGnNrQO2/z3R1+fFX9D/5ZfOERzTQv+rvqnTxzfO/979MJJkR378n6CfDQdDYP2XRpM7gmNi/pOwWahfc5j+sabiuJ0vyv8l3R09uZf+/tJflJH4LC0AXzFbk2d7RP61rdIKV+AHAtoJRDnX89b8AAAAAAAAAAHjIjMQz+ec/tHGBbk/z8r8epfEwzMwNwFdDZaNuDOI/9b/zguLg5z/5me57PV71vy3iI7chKeg/aPI+jdvl6z94yIzEM/nnP1kSQcEw/NE/TItteBKa4T8=""}}}, ""columns"": [""unusual_cmdline_feature_for"", ""unusual_cmdline_feature_netsh"", ""unusual_cmdline_feature_readbytes"", ""unusual_cmdline_feature_set"", ""unusual_cmdline_feature_unrestricted"", ""unusual_cmdline_feature_winstations"", ""unusual_cmdline_feature_-value"", ""unusual_cmdline_feature_compression"", ""unusual_cmdline_feature_server"", ""unusual_cmdline_feature_set-mppreference"", ""unusual_cmdline_feature_terminal"", ""unusual_cmdline_feature_-name"", ""unusual_cmdline_feature_catch"", ""unusual_cmdline_feature_get-wmiobject"", ""unusual_cmdline_feature_hklm"", ""unusual_cmdline_feature_streamreader"", ""unusual_cmdline_feature_system32"", ""unusual_cmdline_feature_username"", ""unusual_cmdline_feature_webrequest"", ""unusual_cmdline_feature_count"", ""unusual_cmdline_feature_webclient"", ""unusual_cmdline_feature_writeallbytes"", ""unusual_cmdline_feature_convert"", ""unusual_cmdline_feature_create"", ""unusual_cmdline_feature_function"", ""unusual_cmdline_feature_net"", ""unusual_cmdline_feature_com"", ""unusual_cmdline_feature_http"", ""unusual_cmdline_feature_io"", ""unusual_cmdline_feature_system"", ""unusual_cmdline_feature_new-object"", ""unusual_cmdline_feature_if"", ""unusual_cmdline_feature_threading"", ""unusual_cmdline_feature_mutex"", ""unusual_cmdline_feature_cryptography"", ""unusual_cmdline_feature_computehash""], ""target_variable"": ""unusual_cmdline_logits"", ""feature_variables"": [""unusual_cmdline_feature_for"", ""unusual_cmdline_feature_netsh"", ""unusual_cmdline_feature_readbytes"", ""unusual_cmdline_feature_set"", ""unusual_cmdline_feature_unrestricted"", ""unusual_cmdline_feature_winstations"", ""unusual_cmdline_feature_-value"", ""unusual_cmdline_feature_compression"", ""unusual_cmdline_feature_server"", ""unusual_cmdline_feature_set-mppreference"", ""unusual_cmdline_feature_terminal"", ""unusual_cmdline_feature_-name"", ""unusual_cmdline_feature_catch"", ""unusual_cmdline_feature_get-wmiobject"", ""unusual_cmdline_feature_hklm"", ""unusual_cmdline_feature_streamreader"", ""unusual_cmdline_feature_system32"", ""unusual_cmdline_feature_username"", ""unusual_cmdline_feature_webrequest"", ""unusual_cmdline_feature_count"", ""unusual_cmdline_feature_webclient"", ""unusual_cmdline_feature_writeallbytes"", ""unusual_cmdline_feature_convert"", ""unusual_cmdline_feature_create"", ""unusual_cmdline_feature_function"", ""unusual_cmdline_feature_net"", ""unusual_cmdline_feature_com"", ""unusual_cmdline_feature_http"", ""unusual_cmdline_feature_io"", ""unusual_cmdline_feature_system"", ""unusual_cmdline_feature_new-object"", ""unusual_cmdline_feature_if"", ""unusual_cmdline_feature_threading"", ""unusual_cmdline_feature_mutex"", ""unusual_cmdline_feature_cryptography"", ""unusual_cmdline_feature_computehash""]}}","{""args"": [""unusual_cmdline_logits"", ""unusual_cmdline_feature_for"", ""unusual_cmdline_feature_netsh"", ""unusual_cmdline_feature_readbytes"", ""unusual_cmdline_feature_set"", ""unusual_cmdline_feature_unrestricted"", ""unusual_cmdline_feature_winstations"", ""unusual_cmdline_feature_-value"", ""unusual_cmdline_feature_compression"", ""unusual_cmdline_feature_server"", ""unusual_cmdline_feature_set-mppreference"", ""unusual_cmdline_feature_terminal"", ""unusual_cmdline_feature_-name"", ""unusual_cmdline_feature_catch"", ""unusual_cmdline_feature_get-wmiobject"", ""unusual_cmdline_feature_hklm"", ""unusual_cmdline_feature_streamreader"", ""unusual_cmdline_feature_system32"", ""unusual_cmdline_feature_username"", ""unusual_cmdline_feature_webrequest"", ""unusual_cmdline_feature_count"", ""unusual_cmdline_feature_webclient"", ""unusual_cmdline_feature_writeallbytes"", ""unusual_cmdline_feature_convert"", ""unusual_cmdline_feature_create"", ""unusual_cmdline_feature_function"", ""unusual_cmdline_feature_net"", ""unusual_cmdline_feature_com"", ""unusual_cmdline_feature_http"", ""unusual_cmdline_feature_io"", ""unusual_cmdline_feature_system"", ""unusual_cmdline_feature_new-object"", ""unusual_cmdline_feature_if"", ""unusual_cmdline_feature_threading"", ""unusual_cmdline_feature_mutex"", ""unusual_cmdline_feature_cryptography"", ""unusual_cmdline_feature_computehash""], ""target_variable"": [""unusual_cmdline_logits""], ""feature_variables"": [""unusual_cmdline_feature_for"", ""unusual_cmdline_feature_netsh"", ""unusual_cmdline_feature_readbytes"", ""unusual_cmdline_feature_set"", ""unusual_cmdline_feature_unrestricted"", ""unusual_cmdline_feature_winstations"", ""unusual_cmdline_feature_-value"", ""unusual_cmdline_feature_compression"", ""unusual_cmdline_feature_server"", ""unusual_cmdline_feature_set-mppreference"", ""unusual_cmdline_feature_terminal"", ""unusual_cmdline_feature_-name"", ""unusual_cmdline_feature_catch"", ""unusual_cmdline_feature_get-wmiobject"", ""unusual_cmdline_feature_hklm"", ""unusual_cmdline_feature_streamreader"", ""unusual_cmdline_feature_system32"", ""unusual_cmdline_feature_username"", ""unusual_cmdline_feature_webrequest"", ""unusual_cmdline_feature_count"", ""unusual_cmdline_feature_webclient"", ""unusual_cmdline_feature_writeallbytes"", ""unusual_cmdline_feature_convert"", ""unusual_cmdline_feature_create"", ""unusual_cmdline_feature_function"", ""unusual_cmdline_feature_net"", ""unusual_cmdline_feature_com"", ""unusual_cmdline_feature_http"", ""unusual_cmdline_feature_io"", ""unusual_cmdline_feature_system"", ""unusual_cmdline_feature_new-object"", ""unusual_cmdline_feature_if"", ""unusual_cmdline_feature_threading"", ""unusual_cmdline_feature_mutex"", ""unusual_cmdline_feature_cryptography"", ""unusual_cmdline_feature_computehash""], ""model_name"": ""lm_avg_char_prob"", ""algo_name"": ""LinearRegression"", ""mlspl_limits"": {""handle_new_cat"": ""default"", ""max_distinct_cat_values"": ""100"", ""max_distinct_cat_values_for_classifiers"": ""100"", ""max_distinct_cat_values_for_scoring"": ""100"", ""max_fit_time"": ""600"", ""max_inputs"": ""100000"", ""max_memory_usage_mb"": ""1000"", ""max_model_size_mb"": ""15"", ""max_score_time"": ""600"", ""streaming_apply"": ""false"", ""use_sampling"": ""true""}, ""kfold_cv"": null}" From c3f59cb75072c5d49ce2f8429fbee85b8e179b92 Mon Sep 17 00:00:00 2001 From: Michael Hart Date: Wed, 19 Jan 2022 20:08:39 -0500 Subject: [PATCH 13/32] Renaming the macro --- .../endpoint/potentially_malicious_code_on_commandline.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/detections/endpoint/potentially_malicious_code_on_commandline.yml b/detections/endpoint/potentially_malicious_code_on_commandline.yml index 95fcec5db7..2c779438cc 100644 --- a/detections/endpoint/potentially_malicious_code_on_commandline.yml +++ b/detections/endpoint/potentially_malicious_code_on_commandline.yml @@ -7,7 +7,7 @@ type: Anomaly datamodel: - Endpoint description: Uses machine learning to detect potentially malicious command lines -search: '| tstats count from datamodel="Endpoint.Processes" by Processes.process | `drop_dm_object_name(Processes)` | `unusual_commandline_detection_tokenizer`' +search: '| tstats count from datamodel="Endpoint.Processes" by Processes.process | `drop_dm_object_name(Processes)` | `potentially_malicious_code_on_cmdline_tokenize_score`' how_to_implement: UPDATE_HOW_TO_IMPLEMENT known_false_positives: UPDATE_KNOWN_FALSE_POSITIVES references: From 0f2eae31081b5e87163e5686cb5500dfe8fd47eb Mon Sep 17 00:00:00 2001 From: Michael Hart Date: Wed, 19 Jan 2022 20:14:28 -0500 Subject: [PATCH 14/32] Fixing missing filter statement --- .../endpoint/potentially_malicious_code_on_commandline.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/detections/endpoint/potentially_malicious_code_on_commandline.yml b/detections/endpoint/potentially_malicious_code_on_commandline.yml index 2c779438cc..aed78fecb1 100644 --- a/detections/endpoint/potentially_malicious_code_on_commandline.yml +++ b/detections/endpoint/potentially_malicious_code_on_commandline.yml @@ -7,7 +7,7 @@ type: Anomaly datamodel: - Endpoint description: Uses machine learning to detect potentially malicious command lines -search: '| tstats count from datamodel="Endpoint.Processes" by Processes.process | `drop_dm_object_name(Processes)` | `potentially_malicious_code_on_cmdline_tokenize_score`' +search: '| tstats count from datamodel="Endpoint.Processes" by Processes.process | `drop_dm_object_name(Processes)` | `potentially_malicious_code_on_cmdline_tokenize_score` | `potentially_malicious_code_on_commandline_filter`' how_to_implement: UPDATE_HOW_TO_IMPLEMENT known_false_positives: UPDATE_KNOWN_FALSE_POSITIVES references: From 5798dd291db1d87c79916be924341c8a03ab48c2 Mon Sep 17 00:00:00 2001 From: Michael Hart Date: Wed, 19 Jan 2022 21:01:08 -0500 Subject: [PATCH 15/32] Fixing references issue --- .../endpoint/potentially_malicious_code_on_commandline.yml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/detections/endpoint/potentially_malicious_code_on_commandline.yml b/detections/endpoint/potentially_malicious_code_on_commandline.yml index aed78fecb1..d323306e36 100644 --- a/detections/endpoint/potentially_malicious_code_on_commandline.yml +++ b/detections/endpoint/potentially_malicious_code_on_commandline.yml @@ -8,10 +8,9 @@ datamodel: - Endpoint description: Uses machine learning to detect potentially malicious command lines search: '| tstats count from datamodel="Endpoint.Processes" by Processes.process | `drop_dm_object_name(Processes)` | `potentially_malicious_code_on_cmdline_tokenize_score` | `potentially_malicious_code_on_commandline_filter`' -how_to_implement: UPDATE_HOW_TO_IMPLEMENT -known_false_positives: UPDATE_KNOWN_FALSE_POSITIVES -references: -- +how_to_implement: Need endpoint model +known_false_positives: This model can output false positives +references: [] tags: analytic_story: - Suspicious Command-Line Executions From 6cbf5b67d965135782b5f7816bcd787f9e16f9cf Mon Sep 17 00:00:00 2001 From: Michael Hart Date: Wed, 19 Jan 2022 21:15:51 -0500 Subject: [PATCH 16/32] Updated detection logic --- .../endpoint/potentially_malicious_code_on_commandline.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/detections/endpoint/potentially_malicious_code_on_commandline.yml b/detections/endpoint/potentially_malicious_code_on_commandline.yml index d323306e36..0739fd7a43 100644 --- a/detections/endpoint/potentially_malicious_code_on_commandline.yml +++ b/detections/endpoint/potentially_malicious_code_on_commandline.yml @@ -7,7 +7,7 @@ type: Anomaly datamodel: - Endpoint description: Uses machine learning to detect potentially malicious command lines -search: '| tstats count from datamodel="Endpoint.Processes" by Processes.process | `drop_dm_object_name(Processes)` | `potentially_malicious_code_on_cmdline_tokenize_score` | `potentially_malicious_code_on_commandline_filter`' +search: '| tstats `security_content_summariesonly` count min(_time) as firstTime max(_time) as lastTime from datamodel="Endpoint.Processes" by Processes.parent_process_name Processes.process_name Processes.process Processes.user Processes.dest | `drop_dm_object_name(Processes)` | `potentially_malicious_code_on_cmdline_tokenize_score` | where score > 2.5 | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)` | `potentially_malicious_code_on_commandline_filter`' how_to_implement: Need endpoint model known_false_positives: This model can output false positives references: [] @@ -34,7 +34,7 @@ tags: context: - source:endpoint - stage:Execution - message: Unusual commandline execution with hallmarks of malicious activity found $Message$ + message: Unusual commandline execution with hallmarks of malicious activity found on $dest$ with commandline $process$ observable: - name: ComputerName type: Hostname From c6d4e40abf5d1a4e8fab8c2526e361051be73f94 Mon Sep 17 00:00:00 2001 From: Michael Hart Date: Wed, 19 Jan 2022 21:36:46 -0500 Subject: [PATCH 17/32] Adding in attack data --- .../potentially_malicious_code_on_commandline.test.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/endpoint/potentially_malicious_code_on_commandline.test.yml b/tests/endpoint/potentially_malicious_code_on_commandline.test.yml index 2f26f5d856..0ca0c9ef5c 100644 --- a/tests/endpoint/potentially_malicious_code_on_commandline.test.yml +++ b/tests/endpoint/potentially_malicious_code_on_commandline.test.yml @@ -6,7 +6,7 @@ tests: earliest_time: '-24h' latest_time: 'now' attack_data: - - file_name: UPDATE_FILE_NAME - data: UPDATE_DATASET_URL - source: UPDATE_SPLUNK_SOURCE - sourcetype: UPDATE_SPLUNK_SOURCETYPE \ No newline at end of file + - file_name: windows-sysmon.log + data: https://github.com/splunk/attack_data/blob/master/datasets/attack_techniques/T1059.001/malicious_cmd_line_samples/windows-sysmon.log + source: XmlWinEventLog:Microsoft-Windows-Sysmon/Operational + sourcetype: xmlwineventlog \ No newline at end of file From 14db58ca1946603a6c18696e7d4b7325fb26722f Mon Sep 17 00:00:00 2001 From: Michael Hart Date: Thu, 20 Jan 2022 08:32:39 -0500 Subject: [PATCH 18/32] Adding a yaml file to ensure that contentctl copies the mlmodel file to the right place --- lookups/__mlspl_unusual_commandline_detection.yml | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 lookups/__mlspl_unusual_commandline_detection.yml diff --git a/lookups/__mlspl_unusual_commandline_detection.yml b/lookups/__mlspl_unusual_commandline_detection.yml new file mode 100644 index 0000000000..9f2ae31129 --- /dev/null +++ b/lookups/__mlspl_unusual_commandline_detection.yml @@ -0,0 +1,3 @@ +description: An MLTK model for detecting malicious commandlines +filename: __mlspl_unusual_commandline_detection.mlmodel +name: __mlspl_unusual_commandline_detection \ No newline at end of file From 1fb3fb8064be77cae82eae140f1cab1a97a0ab16 Mon Sep 17 00:00:00 2001 From: Michael Hart Date: Thu, 20 Jan 2022 08:47:34 -0500 Subject: [PATCH 19/32] Adding required fields and fixing URL in test --- .../endpoint/potentially_malicious_code_on_commandline.yml | 6 ++++++ .../potentially_malicious_code_on_commandline.test.yml | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/detections/endpoint/potentially_malicious_code_on_commandline.yml b/detections/endpoint/potentially_malicious_code_on_commandline.yml index 0739fd7a43..79804ee67a 100644 --- a/detections/endpoint/potentially_malicious_code_on_commandline.yml +++ b/detections/endpoint/potentially_malicious_code_on_commandline.yml @@ -27,6 +27,12 @@ tags: - Splunk Cloud required_fields: - _time + - Processes.process + - Processes.parent_process_name + - Processes.process_name + - Processes.parent_process + - Processes.user + - Processes.dest security_domain: endpoint impact: 60 confidence: 20 diff --git a/tests/endpoint/potentially_malicious_code_on_commandline.test.yml b/tests/endpoint/potentially_malicious_code_on_commandline.test.yml index 0ca0c9ef5c..9c8bc590de 100644 --- a/tests/endpoint/potentially_malicious_code_on_commandline.test.yml +++ b/tests/endpoint/potentially_malicious_code_on_commandline.test.yml @@ -7,6 +7,6 @@ tests: latest_time: 'now' attack_data: - file_name: windows-sysmon.log - data: https://github.com/splunk/attack_data/blob/master/datasets/attack_techniques/T1059.001/malicious_cmd_line_samples/windows-sysmon.log + data: https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1059.001/malicious_cmd_line_samples/windows-sysmon.log source: XmlWinEventLog:Microsoft-Windows-Sysmon/Operational sourcetype: xmlwineventlog \ No newline at end of file From 4a7435f998858c6055f8716ef2007893823e7ac9 Mon Sep 17 00:00:00 2001 From: Michael Hart Date: Thu, 20 Jan 2022 11:32:55 -0500 Subject: [PATCH 20/32] Temporarily changing location for samples --- .../endpoint/potentially_malicious_code_on_commandline.test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/endpoint/potentially_malicious_code_on_commandline.test.yml b/tests/endpoint/potentially_malicious_code_on_commandline.test.yml index 9c8bc590de..88c87c2f80 100644 --- a/tests/endpoint/potentially_malicious_code_on_commandline.test.yml +++ b/tests/endpoint/potentially_malicious_code_on_commandline.test.yml @@ -7,6 +7,6 @@ tests: latest_time: 'now' attack_data: - file_name: windows-sysmon.log - data: https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1059.001/malicious_cmd_line_samples/windows-sysmon.log + data: https://media.githubusercontent.com/media/splunk/attack_data/malicious_cmd_line_samples/datasets/attack_techniques/T1059.001/malicious_cmd_line_samples/windows-sysmon.log source: XmlWinEventLog:Microsoft-Windows-Sysmon/Operational sourcetype: xmlwineventlog \ No newline at end of file From 2f9d410caf67100cd5a5c32d87b11e987b93d914 Mon Sep 17 00:00:00 2001 From: Michael Hart Date: Thu, 20 Jan 2022 16:14:44 -0500 Subject: [PATCH 21/32] Updating test interval --- .../endpoint/potentially_malicious_code_on_commandline.test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/endpoint/potentially_malicious_code_on_commandline.test.yml b/tests/endpoint/potentially_malicious_code_on_commandline.test.yml index 88c87c2f80..71a36c8d5d 100644 --- a/tests/endpoint/potentially_malicious_code_on_commandline.test.yml +++ b/tests/endpoint/potentially_malicious_code_on_commandline.test.yml @@ -3,7 +3,7 @@ tests: - name: Potentially malicious code on commandline file: endpoint/potentially_malicious_code_on_commandline.yml pass_condition: '| stats count | where count > 0' - earliest_time: '-24h' + earliest_time: '-10y' latest_time: 'now' attack_data: - file_name: windows-sysmon.log From 906f0ee3388b1db5e4243e22a8cb9cd9343e018a Mon Sep 17 00:00:00 2001 From: Michael Hart Date: Thu, 20 Jan 2022 21:09:22 -0500 Subject: [PATCH 22/32] Changing the test dataset to the main branch --- .../endpoint/potentially_malicious_code_on_commandline.test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/endpoint/potentially_malicious_code_on_commandline.test.yml b/tests/endpoint/potentially_malicious_code_on_commandline.test.yml index 71a36c8d5d..d44871aef0 100644 --- a/tests/endpoint/potentially_malicious_code_on_commandline.test.yml +++ b/tests/endpoint/potentially_malicious_code_on_commandline.test.yml @@ -7,6 +7,6 @@ tests: latest_time: 'now' attack_data: - file_name: windows-sysmon.log - data: https://media.githubusercontent.com/media/splunk/attack_data/malicious_cmd_line_samples/datasets/attack_techniques/T1059.001/malicious_cmd_line_samples/windows-sysmon.log + data: https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1059.001/malicious_cmd_line_samples/windows-sysmon.log source: XmlWinEventLog:Microsoft-Windows-Sysmon/Operational sourcetype: xmlwineventlog \ No newline at end of file From 3ad47776fb219bb65329ee6a86921ac629fd3edb Mon Sep 17 00:00:00 2001 From: Lou Stella Date: Fri, 21 Jan 2022 14:16:51 -0600 Subject: [PATCH 23/32] Moving to experimental --- .../endpoint/ssa___anomalous_usage_of_account_credentials.yml | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename detections/{ => experimental}/endpoint/ssa___anomalous_usage_of_account_credentials.yml (100%) diff --git a/detections/endpoint/ssa___anomalous_usage_of_account_credentials.yml b/detections/experimental/endpoint/ssa___anomalous_usage_of_account_credentials.yml similarity index 100% rename from detections/endpoint/ssa___anomalous_usage_of_account_credentials.yml rename to detections/experimental/endpoint/ssa___anomalous_usage_of_account_credentials.yml From a81fbaef75963e1ef9b1dead38816ac96e634576 Mon Sep 17 00:00:00 2001 From: Michael Hart Date: Fri, 21 Jan 2022 19:31:02 -0500 Subject: [PATCH 24/32] Finalizing the documentation --- .../potentially_malicious_code_on_commandline.yml | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/detections/endpoint/potentially_malicious_code_on_commandline.yml b/detections/endpoint/potentially_malicious_code_on_commandline.yml index 79804ee67a..f5f0efb218 100644 --- a/detections/endpoint/potentially_malicious_code_on_commandline.yml +++ b/detections/endpoint/potentially_malicious_code_on_commandline.yml @@ -6,20 +6,19 @@ author: Michael Hart, Splunk type: Anomaly datamodel: - Endpoint -description: Uses machine learning to detect potentially malicious command lines -search: '| tstats `security_content_summariesonly` count min(_time) as firstTime max(_time) as lastTime from datamodel="Endpoint.Processes" by Processes.parent_process_name Processes.process_name Processes.process Processes.user Processes.dest | `drop_dm_object_name(Processes)` | `potentially_malicious_code_on_cmdline_tokenize_score` | where score > 2.5 | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)` | `potentially_malicious_code_on_commandline_filter`' -how_to_implement: Need endpoint model -known_false_positives: This model can output false positives +description: The following analytic uses a pretrained machine learning text classifier to detect potentially malicious commandlines. The model identifies unusual combinations of keywords found in samples of commandlines where adversaries executed code, primarily for C2 communication. These combinations of keywords are not typically found in normal usage of the commandline. +search: '| tstats `security_content_summariesonly` count min(_time) as firstTime max(_time) as lastTime from datamodel="Endpoint.Processes" by Processes.parent_process_name Processes.process_name Processes.process Processes.user Processes.dest | `drop_dm_object_name(Processes)` | where len(process) > 200 | `potentially_malicious_code_on_cmdline_tokenize_score` | where score > 1.0 | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)` | `potentially_malicious_code_on_commandline_filter`' +how_to_implement: To successfully implement this search, you need to be ingesting logs with the process name, parent process, and command-line executions from your endpoints. If you are using Sysmon, you must have at least version 6.0.4 of the Sysmon TA. You will also need to install the Machine Learning Toolkit to apply the pretrained model. +known_false_positives: This model is an anomaly detector that identifies usage of APIs and scripting constructs that are correllated with malicious activity. These APIs and scripting constructs are part of the programming langauge and advanced scripts may generate false positives. references: [] tags: analytic_story: - Suspicious Command-Line Executions dataset: - - https://github.com/splunk/attack_data/blob/master/datasets/attack_techniques/T1059.001/malicious_cmd_line_samples/windows-sysmon.log + - https://media.githubusercontent.com/media/splunk/attack_data/master/datasets/attack_techniques/T1059.001/malicious_cmd_line_samples/windows-sysmon.log kill_chain_phases: - Exploitation mitre_attack_id: - - T1059.001 - T1059.003 product: - Splunk Enterprise @@ -40,7 +39,7 @@ tags: context: - source:endpoint - stage:Execution - message: Unusual commandline execution with hallmarks of malicious activity found on $dest$ with commandline $process$ + message: Unusual commandline execution with hallmarks of malicious activity run by $user$ found on $dest$ with commandline $process$ observable: - name: ComputerName type: Hostname From cca42c0009295cda7189b9bfb5b9838b2d643323 Mon Sep 17 00:00:00 2001 From: patel-bhavin Date: Mon, 24 Jan 2022 15:31:15 -0800 Subject: [PATCH 25/32] moving to expermental --- .../ssa___disable_defender_antivirus_registry.yml | 0 .../endpoint/ssa___disable_defender_antivirus_registry.test.yml | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename detections/{endpoint => experimental}/ssa___disable_defender_antivirus_registry.yml (100%) rename tests/{ => experimental}/endpoint/ssa___disable_defender_antivirus_registry.test.yml (100%) diff --git a/detections/endpoint/ssa___disable_defender_antivirus_registry.yml b/detections/experimental/ssa___disable_defender_antivirus_registry.yml similarity index 100% rename from detections/endpoint/ssa___disable_defender_antivirus_registry.yml rename to detections/experimental/ssa___disable_defender_antivirus_registry.yml diff --git a/tests/endpoint/ssa___disable_defender_antivirus_registry.test.yml b/tests/experimental/endpoint/ssa___disable_defender_antivirus_registry.test.yml similarity index 100% rename from tests/endpoint/ssa___disable_defender_antivirus_registry.test.yml rename to tests/experimental/endpoint/ssa___disable_defender_antivirus_registry.test.yml From 39d7121dcd703ebddf0dd1729ae42d1df4114b0e Mon Sep 17 00:00:00 2001 From: Michael Hart Date: Tue, 25 Jan 2022 21:42:16 -0500 Subject: [PATCH 26/32] Updating mlmodel to 5.3.x specification as well as the test apparatus --- .../test_config_github_actions.json | 264 +++++++++--------- ...lspl_unusual_commandline_detection.mlmodel | 2 +- 2 files changed, 133 insertions(+), 133 deletions(-) diff --git a/bin/automated_detection_testing/ci/detection_testing_batch/test_config_github_actions.json b/bin/automated_detection_testing/ci/detection_testing_batch/test_config_github_actions.json index cf84556d02..70ba5473a2 100644 --- a/bin/automated_detection_testing/ci/detection_testing_batch/test_config_github_actions.json +++ b/bin/automated_detection_testing/ci/detection_testing_batch/test_config_github_actions.json @@ -1,135 +1,135 @@ { - "branch": "BRANCH_DOES_NOT_EXIST_USE_CLI_ARGUMENT", - "commit_hash": null, - "container_tag": "latest", - "detections_file": null, - "detections_list": null, - "folders": [ - "endpoint", - "cloud", - "network", - "web" - ], - "interactive": false, - "local_apps": { - "SPLUNK_ADD_ON_FOR_AMAZON_KINESIS_FIREHOSE": { - "app_number": 12, - "app_version": null, - "http_path": "https://attack-range-appbinaries.s3-us-west-2.amazonaws.com/splunk-add-on-for-amazon-kinesis-firehose_131r7d1d093.tgz" - }, - "SPLUNK_ADD_ON_FOR_MICROSOFT_OFFICE_365": { - "app_number": 13, - "app_version": null, - "http_path": "https://attack-range-appbinaries.s3-us-west-2.amazonaws.com/splunk-add-on-for-microsoft-office-365_202.tgz" - }, - "SPLUNK_ADD_ON_FOR_STREAM_FORWARDERS": { - "app_number": 9, - "app_version": null, - "http_path": "https://attack-range-appbinaries.s3-us-west-2.amazonaws.com/splunk-add-on-for-stream-forwarders_730.tgz" - }, - "SPLUNK_ADD_ON_FOR_STREAM_WIRE_DATA": { - "app_number": 8, - "app_version": null, - "http_path": "https://attack-range-appbinaries.s3-us-west-2.amazonaws.com/splunk-add-on-for-stream-wire-data_730.tgz" - }, - "SPLUNK_ADD_ON_FOR_SYSMON_OLD": { - "app_number": 1, - "app_version": null, - "http_path": "https://attack-range-appbinaries.s3-us-west-2.amazonaws.com/splunk-add-on-for-microsoft-sysmon_1062.tgz" - }, - "SPLUNK_ADD_ON_FOR_ZEEK_AKA_BRO": { - "app_number": 11, - "app_version": null, - "http_path": "https://attack-range-appbinaries.s3-us-west-2.amazonaws.com/splunk-add-on-for-zeek-aka-bro_400.tgz" - }, - "SPLUNK_ASX_APP": { - "app_number": 17, - "app_version": null, - "http_path": "https://attack-range-appbinaries.s3-us-west-2.amazonaws.com/Splunk_ASX-latest.tar.gz" - }, - "SPLUNK_AWS_TA": { - "app_number": 4, - "app_version": null, - "http_path": "https://attack-range-appbinaries.s3-us-west-2.amazonaws.com/splunk-add-on-for-amazon-web-services_510.tgz" - }, - "SPLUNK_CIM_APP": { - "app_number": 3, - "app_version": null, - "http_path": "https://attack-range-appbinaries.s3-us-west-2.amazonaws.com/splunk-common-information-model-cim_4200.tgz" - }, - "SPLUNK_ES_CONTENT_UPDATE": { - "app_number": 3449, - "app_version": null, - "local_path": null - }, - "SPLUNK_LINUX_TA": { - "app_number": 14, - "app_version": null, - "http_path": "https://attack-range-appbinaries.s3-us-west-2.amazonaws.com/splunk-add-on-for-unix-and-linux_820.tgz" - }, - "SPLUNK_MLTK_APP": { - "app_number": 6, - "app_version": null, - "http_path": "https://attack-range-appbinaries.s3-us-west-2.amazonaws.com/splunk-machine-learning-toolkit_521.tgz" - }, - "SPLUNK_NGINX_TA": { - "app_number": 15, - "app_version": null, - "http_path": "https://attack-range-appbinaries.s3-us-west-2.amazonaws.com/splunk-add-on-for-nginx_310.tgz" - }, - "SPLUNK_PYTHON_APP": { - "app_number": 5, - "app_version": null, - "http_path": "https://attack-range-appbinaries.s3-us-west-2.amazonaws.com/python-for-scientific-computing-for-linux-64-bit_202.tgz" - }, - "SPLUNK_SECURITY_ESSENTIALS": { - "app_number": 10, - "app_version": null, - "http_path": "https://attack-range-appbinaries.s3-us-west-2.amazonaws.com/splunk-security-essentials_333.tgz" - }, - "SPLUNK_STREAM_APP": { - "app_number": 7, - "app_version": null, - "http_path": "https://attack-range-appbinaries.s3-us-west-2.amazonaws.com/splunk-app-for-stream_730.tgz" - }, - "SPLUNK_SYSMON_LINUX_TA_PATCHED": { - "app_number": 2, - "app_version": null, - "http_path": "https://attack-range-appbinaries.s3-us-west-2.amazonaws.com/add-on-for-linux-sysmon_103_PATCHED.tgz" - }, - "SPLUNK_TA_FOR_ZEEK": { - "app_number": 16, - "app_version": null, - "http_path": "https://attack-range-appbinaries.s3-us-west-2.amazonaws.com/ta-for-zeek_105.tgz" - }, - "SPLUNK_WINDOWS_TA": { - "app_number": 0, - "app_version": null, - "http_path": "https://attack-range-appbinaries.s3-us-west-2.amazonaws.com/splunk-add-on-for-microsoft-windows_812.tgz" - } + "branch": "BRANCH_DOES_NOT_EXIST_USE_CLI_ARGUMENT", + "commit_hash": null, + "container_tag": "latest", + "detections_file": null, + "detections_list": null, + "folders": [ + "endpoint", + "cloud", + "network", + "web" + ], + "interactive": false, + "local_apps": { + "SPLUNK_ADD_ON_FOR_AMAZON_KINESIS_FIREHOSE": { + "app_number": 12, + "app_version": null, + "http_path": "https://attack-range-appbinaries.s3-us-west-2.amazonaws.com/splunk-add-on-for-amazon-kinesis-firehose_131r7d1d093.tgz" }, - "local_base_container_name": "splunk_test_%d", - "mock": false, - "mode": "changes", - "no_interactive_failure": true, - "num_containers": 10, - "persist_security_content": false, - "pr_number": null, - "reuse_image": true, - "show_splunk_app_password": false, - "splunk_app_password": null, - "splunk_container_apps_directory": "/opt/splunk/etc/apps", - "splunkbase_apps": { - "SPLUNK_ADD_ON_FOR_SYSMON": { - "app_number": 5709, - "app_version": "1.0.1" - } + "SPLUNK_ADD_ON_FOR_MICROSOFT_OFFICE_365": { + "app_number": 13, + "app_version": null, + "http_path": "https://attack-range-appbinaries.s3-us-west-2.amazonaws.com/splunk-add-on-for-microsoft-office-365_202.tgz" }, - "splunkbase_password": null, - "splunkbase_username": null, - "types": [ - "Anomaly", - "Hunting", - "TTP" - ] -} \ No newline at end of file + "SPLUNK_ADD_ON_FOR_STREAM_FORWARDERS": { + "app_number": 9, + "app_version": null, + "http_path": "https://attack-range-appbinaries.s3-us-west-2.amazonaws.com/splunk-add-on-for-stream-forwarders_730.tgz" + }, + "SPLUNK_ADD_ON_FOR_STREAM_WIRE_DATA": { + "app_number": 8, + "app_version": null, + "http_path": "https://attack-range-appbinaries.s3-us-west-2.amazonaws.com/splunk-add-on-for-stream-wire-data_730.tgz" + }, + "SPLUNK_ADD_ON_FOR_SYSMON_OLD": { + "app_number": 1, + "app_version": null, + "http_path": "https://attack-range-appbinaries.s3-us-west-2.amazonaws.com/splunk-add-on-for-microsoft-sysmon_1062.tgz" + }, + "SPLUNK_ADD_ON_FOR_ZEEK_AKA_BRO": { + "app_number": 11, + "app_version": null, + "http_path": "https://attack-range-appbinaries.s3-us-west-2.amazonaws.com/splunk-add-on-for-zeek-aka-bro_400.tgz" + }, + "SPLUNK_ASX_APP": { + "app_number": 17, + "app_version": null, + "http_path": "https://attack-range-appbinaries.s3-us-west-2.amazonaws.com/Splunk_ASX-latest.tar.gz" + }, + "SPLUNK_AWS_TA": { + "app_number": 4, + "app_version": null, + "http_path": "https://attack-range-appbinaries.s3-us-west-2.amazonaws.com/splunk-add-on-for-amazon-web-services_510.tgz" + }, + "SPLUNK_CIM_APP": { + "app_number": 3, + "app_version": null, + "http_path": "https://attack-range-appbinaries.s3-us-west-2.amazonaws.com/splunk-common-information-model-cim_4200.tgz" + }, + "SPLUNK_ES_CONTENT_UPDATE": { + "app_number": 3449, + "app_version": null, + "local_path": null + }, + "SPLUNK_LINUX_TA": { + "app_number": 14, + "app_version": null, + "http_path": "https://attack-range-appbinaries.s3-us-west-2.amazonaws.com/splunk-add-on-for-unix-and-linux_820.tgz" + }, + "SPLUNK_MLTK_APP": { + "app_number": 6, + "app_version": null, + "http_path": "https://attack-range-appbinaries.s3.us-west-2.amazonaws.com/splunk-machine-learning-toolkit_531.tgz" + }, + "SPLUNK_NGINX_TA": { + "app_number": 15, + "app_version": null, + "http_path": "https://attack-range-appbinaries.s3-us-west-2.amazonaws.com/splunk-add-on-for-nginx_310.tgz" + }, + "SPLUNK_PYTHON_APP": { + "app_number": 5, + "app_version": null, + "http_path": "https://attack-range-appbinaries.s3.us-west-2.amazonaws.com/python-for-scientific-computing-for-linux-64-bit_302.tgz" + }, + "SPLUNK_SECURITY_ESSENTIALS": { + "app_number": 10, + "app_version": null, + "http_path": "https://attack-range-appbinaries.s3-us-west-2.amazonaws.com/splunk-security-essentials_333.tgz" + }, + "SPLUNK_STREAM_APP": { + "app_number": 7, + "app_version": null, + "http_path": "https://attack-range-appbinaries.s3-us-west-2.amazonaws.com/splunk-app-for-stream_730.tgz" + }, + "SPLUNK_SYSMON_LINUX_TA_PATCHED": { + "app_number": 2, + "app_version": null, + "http_path": "https://attack-range-appbinaries.s3-us-west-2.amazonaws.com/add-on-for-linux-sysmon_103_PATCHED.tgz" + }, + "SPLUNK_TA_FOR_ZEEK": { + "app_number": 16, + "app_version": null, + "http_path": "https://attack-range-appbinaries.s3-us-west-2.amazonaws.com/ta-for-zeek_105.tgz" + }, + "SPLUNK_WINDOWS_TA": { + "app_number": 0, + "app_version": null, + "http_path": "https://attack-range-appbinaries.s3-us-west-2.amazonaws.com/splunk-add-on-for-microsoft-windows_812.tgz" + } + }, + "local_base_container_name": "splunk_test_%d", + "mock": false, + "mode": "changes", + "no_interactive_failure": true, + "num_containers": 10, + "persist_security_content": false, + "pr_number": null, + "reuse_image": true, + "show_splunk_app_password": false, + "splunk_app_password": null, + "splunk_container_apps_directory": "/opt/splunk/etc/apps", + "splunkbase_apps": { + "SPLUNK_ADD_ON_FOR_SYSMON": { + "app_number": 5709, + "app_version": "1.0.1" + } + }, + "splunkbase_password": null, + "splunkbase_username": null, + "types": [ + "Anomaly", + "Hunting", + "TTP" + ] +} diff --git a/lookups/__mlspl_unusual_commandline_detection.mlmodel b/lookups/__mlspl_unusual_commandline_detection.mlmodel index d561509925..e214415ae0 100644 --- a/lookups/__mlspl_unusual_commandline_detection.mlmodel +++ b/lookups/__mlspl_unusual_commandline_detection.mlmodel @@ -1,2 +1,2 @@ algo,model,options -LinearRegression,"{""__mlspl_type"": [""algos.LinearRegression"", ""LinearRegression""], ""dict"": {""estimator"": {""__mlspl_type"": [""sklearn.linear_model.base"", ""LinearRegression""], ""dict"": {""fit_intercept"": true, ""normalize"": false, ""copy_X"": true, ""n_jobs"": null, ""intercept_"": -1.2124304031951825, ""coef_"": {""__mlspl_type"": [""numpy"", ""ndarray""], ""npy"": ""k05VTVBZAQB2AHsnZGVzY3InOiAnPGY4JywgJ2ZvcnRyYW5fb3JkZXInOiBGYWxzZSwgJ3NoYXBlJzogKDM2LCksIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIApreM9kKtnhP0TDf2w1t+I/3qDHjxK61j8UkPlxGST1v/rMDbO+a8e/iv8JpC2l5T+6dz+pdS3nP0mN7wQ8eO0/UqU3sakDyD9ncnkR3LHzP/6iGnNrQO2/z3R1+fFX9D/5ZfOERzTQv+rvqnTxzfO/979MJJkR378n6CfDQdDYP2XRpM7gmNi/pOwWahfc5j+sabiuJ0vyv8l3R09uZf+/tJflJH4LC0AXzFbk2d7RP61rdIKV+AHAtoJRDnX89b8AAAAAAAAAAHjIjMQz+ec/tHGBbk/z8r8epfEwzMwNwFdDZaNuDOI/9b/zguLg5z/5me57PV71vy3iI7chKeg/aPI+jdvl6z94yIzEM/nnP1kSQcEw/NE/TItteBKa4T8=""}}}, ""columns"": [""unusual_cmdline_feature_for"", ""unusual_cmdline_feature_netsh"", ""unusual_cmdline_feature_readbytes"", ""unusual_cmdline_feature_set"", ""unusual_cmdline_feature_unrestricted"", ""unusual_cmdline_feature_winstations"", ""unusual_cmdline_feature_-value"", ""unusual_cmdline_feature_compression"", ""unusual_cmdline_feature_server"", ""unusual_cmdline_feature_set-mppreference"", ""unusual_cmdline_feature_terminal"", ""unusual_cmdline_feature_-name"", ""unusual_cmdline_feature_catch"", ""unusual_cmdline_feature_get-wmiobject"", ""unusual_cmdline_feature_hklm"", ""unusual_cmdline_feature_streamreader"", ""unusual_cmdline_feature_system32"", ""unusual_cmdline_feature_username"", ""unusual_cmdline_feature_webrequest"", ""unusual_cmdline_feature_count"", ""unusual_cmdline_feature_webclient"", ""unusual_cmdline_feature_writeallbytes"", ""unusual_cmdline_feature_convert"", ""unusual_cmdline_feature_create"", ""unusual_cmdline_feature_function"", ""unusual_cmdline_feature_net"", ""unusual_cmdline_feature_com"", ""unusual_cmdline_feature_http"", ""unusual_cmdline_feature_io"", ""unusual_cmdline_feature_system"", ""unusual_cmdline_feature_new-object"", ""unusual_cmdline_feature_if"", ""unusual_cmdline_feature_threading"", ""unusual_cmdline_feature_mutex"", ""unusual_cmdline_feature_cryptography"", ""unusual_cmdline_feature_computehash""], ""target_variable"": ""unusual_cmdline_logits"", ""feature_variables"": [""unusual_cmdline_feature_for"", ""unusual_cmdline_feature_netsh"", ""unusual_cmdline_feature_readbytes"", ""unusual_cmdline_feature_set"", ""unusual_cmdline_feature_unrestricted"", ""unusual_cmdline_feature_winstations"", ""unusual_cmdline_feature_-value"", ""unusual_cmdline_feature_compression"", ""unusual_cmdline_feature_server"", ""unusual_cmdline_feature_set-mppreference"", ""unusual_cmdline_feature_terminal"", ""unusual_cmdline_feature_-name"", ""unusual_cmdline_feature_catch"", ""unusual_cmdline_feature_get-wmiobject"", ""unusual_cmdline_feature_hklm"", ""unusual_cmdline_feature_streamreader"", ""unusual_cmdline_feature_system32"", ""unusual_cmdline_feature_username"", ""unusual_cmdline_feature_webrequest"", ""unusual_cmdline_feature_count"", ""unusual_cmdline_feature_webclient"", ""unusual_cmdline_feature_writeallbytes"", ""unusual_cmdline_feature_convert"", ""unusual_cmdline_feature_create"", ""unusual_cmdline_feature_function"", ""unusual_cmdline_feature_net"", ""unusual_cmdline_feature_com"", ""unusual_cmdline_feature_http"", ""unusual_cmdline_feature_io"", ""unusual_cmdline_feature_system"", ""unusual_cmdline_feature_new-object"", ""unusual_cmdline_feature_if"", ""unusual_cmdline_feature_threading"", ""unusual_cmdline_feature_mutex"", ""unusual_cmdline_feature_cryptography"", ""unusual_cmdline_feature_computehash""]}}","{""args"": [""unusual_cmdline_logits"", ""unusual_cmdline_feature_for"", ""unusual_cmdline_feature_netsh"", ""unusual_cmdline_feature_readbytes"", ""unusual_cmdline_feature_set"", ""unusual_cmdline_feature_unrestricted"", ""unusual_cmdline_feature_winstations"", ""unusual_cmdline_feature_-value"", ""unusual_cmdline_feature_compression"", ""unusual_cmdline_feature_server"", ""unusual_cmdline_feature_set-mppreference"", ""unusual_cmdline_feature_terminal"", ""unusual_cmdline_feature_-name"", ""unusual_cmdline_feature_catch"", ""unusual_cmdline_feature_get-wmiobject"", ""unusual_cmdline_feature_hklm"", ""unusual_cmdline_feature_streamreader"", ""unusual_cmdline_feature_system32"", ""unusual_cmdline_feature_username"", ""unusual_cmdline_feature_webrequest"", ""unusual_cmdline_feature_count"", ""unusual_cmdline_feature_webclient"", ""unusual_cmdline_feature_writeallbytes"", ""unusual_cmdline_feature_convert"", ""unusual_cmdline_feature_create"", ""unusual_cmdline_feature_function"", ""unusual_cmdline_feature_net"", ""unusual_cmdline_feature_com"", ""unusual_cmdline_feature_http"", ""unusual_cmdline_feature_io"", ""unusual_cmdline_feature_system"", ""unusual_cmdline_feature_new-object"", ""unusual_cmdline_feature_if"", ""unusual_cmdline_feature_threading"", ""unusual_cmdline_feature_mutex"", ""unusual_cmdline_feature_cryptography"", ""unusual_cmdline_feature_computehash""], ""target_variable"": [""unusual_cmdline_logits""], ""feature_variables"": [""unusual_cmdline_feature_for"", ""unusual_cmdline_feature_netsh"", ""unusual_cmdline_feature_readbytes"", ""unusual_cmdline_feature_set"", ""unusual_cmdline_feature_unrestricted"", ""unusual_cmdline_feature_winstations"", ""unusual_cmdline_feature_-value"", ""unusual_cmdline_feature_compression"", ""unusual_cmdline_feature_server"", ""unusual_cmdline_feature_set-mppreference"", ""unusual_cmdline_feature_terminal"", ""unusual_cmdline_feature_-name"", ""unusual_cmdline_feature_catch"", ""unusual_cmdline_feature_get-wmiobject"", ""unusual_cmdline_feature_hklm"", ""unusual_cmdline_feature_streamreader"", ""unusual_cmdline_feature_system32"", ""unusual_cmdline_feature_username"", ""unusual_cmdline_feature_webrequest"", ""unusual_cmdline_feature_count"", ""unusual_cmdline_feature_webclient"", ""unusual_cmdline_feature_writeallbytes"", ""unusual_cmdline_feature_convert"", ""unusual_cmdline_feature_create"", ""unusual_cmdline_feature_function"", ""unusual_cmdline_feature_net"", ""unusual_cmdline_feature_com"", ""unusual_cmdline_feature_http"", ""unusual_cmdline_feature_io"", ""unusual_cmdline_feature_system"", ""unusual_cmdline_feature_new-object"", ""unusual_cmdline_feature_if"", ""unusual_cmdline_feature_threading"", ""unusual_cmdline_feature_mutex"", ""unusual_cmdline_feature_cryptography"", ""unusual_cmdline_feature_computehash""], ""model_name"": ""lm_avg_char_prob"", ""algo_name"": ""LinearRegression"", ""mlspl_limits"": {""handle_new_cat"": ""default"", ""max_distinct_cat_values"": ""100"", ""max_distinct_cat_values_for_classifiers"": ""100"", ""max_distinct_cat_values_for_scoring"": ""100"", ""max_fit_time"": ""600"", ""max_inputs"": ""100000"", ""max_memory_usage_mb"": ""1000"", ""max_model_size_mb"": ""15"", ""max_score_time"": ""600"", ""streaming_apply"": ""false"", ""use_sampling"": ""true""}, ""kfold_cv"": null}" +LinearRegression,"{""__mlspl_type"": [""algos.LinearRegression"", ""LinearRegression""], ""dict"": {""estimator"": {""__mlspl_type"": [""sklearn.linear_model._base"", ""LinearRegression""], ""dict"": {""fit_intercept"": true, ""normalize"": false, ""copy_X"": true, ""n_jobs"": null, ""intercept_"": -1.2124304031951825, ""coef_"": {""__mlspl_type"": [""numpy"", ""ndarray""], ""npy"": ""k05VTVBZAQB2AHsnZGVzY3InOiAnPGY4JywgJ2ZvcnRyYW5fb3JkZXInOiBGYWxzZSwgJ3NoYXBlJzogKDM2LCksIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIApreM9kKtnhP0TDf2w1t+I/3qDHjxK61j8UkPlxGST1v/rMDbO+a8e/iv8JpC2l5T+6dz+pdS3nP0mN7wQ8eO0/UqU3sakDyD9ncnkR3LHzP/6iGnNrQO2/z3R1+fFX9D/5ZfOERzTQv+rvqnTxzfO/979MJJkR378n6CfDQdDYP2XRpM7gmNi/pOwWahfc5j+sabiuJ0vyv8l3R09uZf+/tJflJH4LC0AXzFbk2d7RP61rdIKV+AHAtoJRDnX89b8AAAAAAAAAAHjIjMQz+ec/tHGBbk/z8r8epfEwzMwNwFdDZaNuDOI/9b/zguLg5z/5me57PV71vy3iI7chKeg/aPI+jdvl6z94yIzEM/nnP1kSQcEw/NE/TItteBKa4T8=""}}}, ""columns"": [""unusual_cmdline_feature_for"", ""unusual_cmdline_feature_netsh"", ""unusual_cmdline_feature_readbytes"", ""unusual_cmdline_feature_set"", ""unusual_cmdline_feature_unrestricted"", ""unusual_cmdline_feature_winstations"", ""unusual_cmdline_feature_-value"", ""unusual_cmdline_feature_compression"", ""unusual_cmdline_feature_server"", ""unusual_cmdline_feature_set-mppreference"", ""unusual_cmdline_feature_terminal"", ""unusual_cmdline_feature_-name"", ""unusual_cmdline_feature_catch"", ""unusual_cmdline_feature_get-wmiobject"", ""unusual_cmdline_feature_hklm"", ""unusual_cmdline_feature_streamreader"", ""unusual_cmdline_feature_system32"", ""unusual_cmdline_feature_username"", ""unusual_cmdline_feature_webrequest"", ""unusual_cmdline_feature_count"", ""unusual_cmdline_feature_webclient"", ""unusual_cmdline_feature_writeallbytes"", ""unusual_cmdline_feature_convert"", ""unusual_cmdline_feature_create"", ""unusual_cmdline_feature_function"", ""unusual_cmdline_feature_net"", ""unusual_cmdline_feature_com"", ""unusual_cmdline_feature_http"", ""unusual_cmdline_feature_io"", ""unusual_cmdline_feature_system"", ""unusual_cmdline_feature_new-object"", ""unusual_cmdline_feature_if"", ""unusual_cmdline_feature_threading"", ""unusual_cmdline_feature_mutex"", ""unusual_cmdline_feature_cryptography"", ""unusual_cmdline_feature_computehash""], ""target_variable"": ""unusual_cmdline_logits"", ""feature_variables"": [""unusual_cmdline_feature_for"", ""unusual_cmdline_feature_netsh"", ""unusual_cmdline_feature_readbytes"", ""unusual_cmdline_feature_set"", ""unusual_cmdline_feature_unrestricted"", ""unusual_cmdline_feature_winstations"", ""unusual_cmdline_feature_-value"", ""unusual_cmdline_feature_compression"", ""unusual_cmdline_feature_server"", ""unusual_cmdline_feature_set-mppreference"", ""unusual_cmdline_feature_terminal"", ""unusual_cmdline_feature_-name"", ""unusual_cmdline_feature_catch"", ""unusual_cmdline_feature_get-wmiobject"", ""unusual_cmdline_feature_hklm"", ""unusual_cmdline_feature_streamreader"", ""unusual_cmdline_feature_system32"", ""unusual_cmdline_feature_username"", ""unusual_cmdline_feature_webrequest"", ""unusual_cmdline_feature_count"", ""unusual_cmdline_feature_webclient"", ""unusual_cmdline_feature_writeallbytes"", ""unusual_cmdline_feature_convert"", ""unusual_cmdline_feature_create"", ""unusual_cmdline_feature_function"", ""unusual_cmdline_feature_net"", ""unusual_cmdline_feature_com"", ""unusual_cmdline_feature_http"", ""unusual_cmdline_feature_io"", ""unusual_cmdline_feature_system"", ""unusual_cmdline_feature_new-object"", ""unusual_cmdline_feature_if"", ""unusual_cmdline_feature_threading"", ""unusual_cmdline_feature_mutex"", ""unusual_cmdline_feature_cryptography"", ""unusual_cmdline_feature_computehash""]}}","{""args"": [""unusual_cmdline_logits"", ""unusual_cmdline_feature_for"", ""unusual_cmdline_feature_netsh"", ""unusual_cmdline_feature_readbytes"", ""unusual_cmdline_feature_set"", ""unusual_cmdline_feature_unrestricted"", ""unusual_cmdline_feature_winstations"", ""unusual_cmdline_feature_-value"", ""unusual_cmdline_feature_compression"", ""unusual_cmdline_feature_server"", ""unusual_cmdline_feature_set-mppreference"", ""unusual_cmdline_feature_terminal"", ""unusual_cmdline_feature_-name"", ""unusual_cmdline_feature_catch"", ""unusual_cmdline_feature_get-wmiobject"", ""unusual_cmdline_feature_hklm"", ""unusual_cmdline_feature_streamreader"", ""unusual_cmdline_feature_system32"", ""unusual_cmdline_feature_username"", ""unusual_cmdline_feature_webrequest"", ""unusual_cmdline_feature_count"", ""unusual_cmdline_feature_webclient"", ""unusual_cmdline_feature_writeallbytes"", ""unusual_cmdline_feature_convert"", ""unusual_cmdline_feature_create"", ""unusual_cmdline_feature_function"", ""unusual_cmdline_feature_net"", ""unusual_cmdline_feature_com"", ""unusual_cmdline_feature_http"", ""unusual_cmdline_feature_io"", ""unusual_cmdline_feature_system"", ""unusual_cmdline_feature_new-object"", ""unusual_cmdline_feature_if"", ""unusual_cmdline_feature_threading"", ""unusual_cmdline_feature_mutex"", ""unusual_cmdline_feature_cryptography"", ""unusual_cmdline_feature_computehash""], ""target_variable"": [""unusual_cmdline_logits""], ""feature_variables"": [""unusual_cmdline_feature_for"", ""unusual_cmdline_feature_netsh"", ""unusual_cmdline_feature_readbytes"", ""unusual_cmdline_feature_set"", ""unusual_cmdline_feature_unrestricted"", ""unusual_cmdline_feature_winstations"", ""unusual_cmdline_feature_-value"", ""unusual_cmdline_feature_compression"", ""unusual_cmdline_feature_server"", ""unusual_cmdline_feature_set-mppreference"", ""unusual_cmdline_feature_terminal"", ""unusual_cmdline_feature_-name"", ""unusual_cmdline_feature_catch"", ""unusual_cmdline_feature_get-wmiobject"", ""unusual_cmdline_feature_hklm"", ""unusual_cmdline_feature_streamreader"", ""unusual_cmdline_feature_system32"", ""unusual_cmdline_feature_username"", ""unusual_cmdline_feature_webrequest"", ""unusual_cmdline_feature_count"", ""unusual_cmdline_feature_webclient"", ""unusual_cmdline_feature_writeallbytes"", ""unusual_cmdline_feature_convert"", ""unusual_cmdline_feature_create"", ""unusual_cmdline_feature_function"", ""unusual_cmdline_feature_net"", ""unusual_cmdline_feature_com"", ""unusual_cmdline_feature_http"", ""unusual_cmdline_feature_io"", ""unusual_cmdline_feature_system"", ""unusual_cmdline_feature_new-object"", ""unusual_cmdline_feature_if"", ""unusual_cmdline_feature_threading"", ""unusual_cmdline_feature_mutex"", ""unusual_cmdline_feature_cryptography"", ""unusual_cmdline_feature_computehash""], ""model_name"": ""lm_avg_char_prob"", ""algo_name"": ""LinearRegression"", ""mlspl_limits"": {""handle_new_cat"": ""default"", ""max_distinct_cat_values"": ""100"", ""max_distinct_cat_values_for_classifiers"": ""100"", ""max_distinct_cat_values_for_scoring"": ""100"", ""max_fit_time"": ""600"", ""max_inputs"": ""100000"", ""max_memory_usage_mb"": ""1000"", ""max_model_size_mb"": ""15"", ""max_score_time"": ""600"", ""streaming_apply"": ""false"", ""use_sampling"": ""true""}, ""kfold_cv"": null}" From a9c5017c63561872e07b06f988f4e6fc4c005341 Mon Sep 17 00:00:00 2001 From: Michael Hart Date: Tue, 25 Jan 2022 22:30:58 -0500 Subject: [PATCH 27/32] Reformatting YAML and calling out MLTK 5.3 dependency --- ...entially_malicious_code_on_commandline.yml | 25 ++++++++++++++++--- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/detections/endpoint/potentially_malicious_code_on_commandline.yml b/detections/endpoint/potentially_malicious_code_on_commandline.yml index f5f0efb218..023b9824ac 100644 --- a/detections/endpoint/potentially_malicious_code_on_commandline.yml +++ b/detections/endpoint/potentially_malicious_code_on_commandline.yml @@ -6,10 +6,27 @@ author: Michael Hart, Splunk type: Anomaly datamodel: - Endpoint -description: The following analytic uses a pretrained machine learning text classifier to detect potentially malicious commandlines. The model identifies unusual combinations of keywords found in samples of commandlines where adversaries executed code, primarily for C2 communication. These combinations of keywords are not typically found in normal usage of the commandline. -search: '| tstats `security_content_summariesonly` count min(_time) as firstTime max(_time) as lastTime from datamodel="Endpoint.Processes" by Processes.parent_process_name Processes.process_name Processes.process Processes.user Processes.dest | `drop_dm_object_name(Processes)` | where len(process) > 200 | `potentially_malicious_code_on_cmdline_tokenize_score` | where score > 1.0 | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)` | `potentially_malicious_code_on_commandline_filter`' -how_to_implement: To successfully implement this search, you need to be ingesting logs with the process name, parent process, and command-line executions from your endpoints. If you are using Sysmon, you must have at least version 6.0.4 of the Sysmon TA. You will also need to install the Machine Learning Toolkit to apply the pretrained model. -known_false_positives: This model is an anomaly detector that identifies usage of APIs and scripting constructs that are correllated with malicious activity. These APIs and scripting constructs are part of the programming langauge and advanced scripts may generate false positives. +description: The following analytic uses a pretrained machine learning text classifier + to detect potentially malicious commandlines. The model identifies unusual + combinations of keywords found in samples of commandlines where adversaries executed + code, primarily for C2 communication. These combinations of keywords are not + typically found in normal usage of the commandline. +search: '| tstats `security_content_summariesonly` count min(_time) as firstTime + max(_time) as lastTime from datamodel="Endpoint.Processes" by + Processes.parent_process_name Processes.process_name Processes.process + Processes.user Processes.dest | `drop_dm_object_name(Processes)` | where + len(process) > 200 | `potentially_malicious_code_on_cmdline_tokenize_score` | + where score > 1.0 | `security_content_ctime(firstTime)` | + `security_content_ctime(lastTime)` | `potentially_malicious_code_on_commandline_filter`' +how_to_implement: To successfully implement this search, you need to be ingesting logs + with the process name, parent process, and command-line executions from your endpoints. + If you are using Sysmon, you must have at least version 6.0.4 of the Sysmon TA. You + will also need to install the Machine Learning Toolkit version 5.3 or above to apply + the pretrained model. +known_false_positives: This model is an anomaly detector that identifies usage of APIs + and scripting constructs that are correllated with malicious activity. These APIs and + scripting constructs are part of the programming langauge and advanced scripts may + generate false positives. references: [] tags: analytic_story: From 67e413d0e033de0628dffba1102671006f5819c4 Mon Sep 17 00:00:00 2001 From: Michael Haag <5632822+MHaggis@users.noreply.github.com> Date: Wed, 26 Jan 2022 11:26:25 -0700 Subject: [PATCH 28/32] Update __mlspl_unusual_commandline_detection.yml --- lookups/__mlspl_unusual_commandline_detection.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lookups/__mlspl_unusual_commandline_detection.yml b/lookups/__mlspl_unusual_commandline_detection.yml index 9f2ae31129..7fd0faa546 100644 --- a/lookups/__mlspl_unusual_commandline_detection.yml +++ b/lookups/__mlspl_unusual_commandline_detection.yml @@ -1,3 +1,6 @@ description: An MLTK model for detecting malicious commandlines filename: __mlspl_unusual_commandline_detection.mlmodel -name: __mlspl_unusual_commandline_detection \ No newline at end of file +name: __mlspl_unusual_commandline_detection +case_sensitive_match: 'false' +min_matches: 1 +default_match: 'false' From b80af6f1515aba50b1b77f4177afe22acfd4ff59 Mon Sep 17 00:00:00 2001 From: Michael Hart Date: Wed, 26 Jan 2022 22:38:13 -0500 Subject: [PATCH 29/32] Editing the macro to put the apply statement into the search query so that it's clear that MLTK is being used --- .../endpoint/potentially_malicious_code_on_commandline.yml | 4 +++- .../potentially_malicious_code_on_cmdline_tokenize_score.yml | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/detections/endpoint/potentially_malicious_code_on_commandline.yml b/detections/endpoint/potentially_malicious_code_on_commandline.yml index 023b9824ac..e1963313bc 100644 --- a/detections/endpoint/potentially_malicious_code_on_commandline.yml +++ b/detections/endpoint/potentially_malicious_code_on_commandline.yml @@ -16,7 +16,9 @@ search: '| tstats `security_content_summariesonly` count min(_time) as firstTime Processes.parent_process_name Processes.process_name Processes.process Processes.user Processes.dest | `drop_dm_object_name(Processes)` | where len(process) > 200 | `potentially_malicious_code_on_cmdline_tokenize_score` | - where score > 1.0 | `security_content_ctime(firstTime)` | + apply unusual_commandline_detection | eval score=''predicted(unusual_cmdline_logits)'', + process=orig_process | fields - unusual_cmdline* predicted(unusual_cmdline_logits) orig_process | + where score > 0.5 | `security_content_ctime(firstTime)` | `security_content_ctime(lastTime)` | `potentially_malicious_code_on_commandline_filter`' how_to_implement: To successfully implement this search, you need to be ingesting logs with the process name, parent process, and command-line executions from your endpoints. diff --git a/macros/potentially_malicious_code_on_cmdline_tokenize_score.yml b/macros/potentially_malicious_code_on_cmdline_tokenize_score.yml index 2eaa5b0ee6..65619a328a 100644 --- a/macros/potentially_malicious_code_on_cmdline_tokenize_score.yml +++ b/macros/potentially_malicious_code_on_cmdline_tokenize_score.yml @@ -1,3 +1,3 @@ -definition: eval orig_process=process, process=replace(lower(process), "`", "") | makemv tokenizer="([\w\d\-]+)" process | eval unusual_cmdline_feature_for=if(match(process, "^for$"), mvcount(mvfilter(match(process, "^for$"))), 0), unusual_cmdline_feature_netsh=if(match(process, "^netsh$"), mvcount(mvfilter(match(process, "^netsh$"))), 0), unusual_cmdline_feature_readbytes=if(match(process, "^readbytes$"), mvcount(mvfilter(match(process, "^readbytes$"))), 0), unusual_cmdline_feature_set=if(match(process, "^set$"), mvcount(mvfilter(match(process, "^set$"))), 0), unusual_cmdline_feature_unrestricted=if(match(process, "^unrestricted$"), mvcount(mvfilter(match(process, "^unrestricted$"))), 0), unusual_cmdline_feature_winstations=if(match(process, "^winstations$"), mvcount(mvfilter(match(process, "^winstations$"))), 0), unusual_cmdline_feature_-value=if(match(process, "^-value$"), mvcount(mvfilter(match(process, "^-value$"))), 0), unusual_cmdline_feature_compression=if(match(process, "^compression$"), mvcount(mvfilter(match(process, "^compression$"))), 0), unusual_cmdline_feature_server=if(match(process, "^server$"), mvcount(mvfilter(match(process, "^server$"))), 0), unusual_cmdline_feature_set-mppreference=if(match(process, "^set-mppreference$"), mvcount(mvfilter(match(process, "^set-mppreference$"))), 0), unusual_cmdline_feature_terminal=if(match(process, "^terminal$"), mvcount(mvfilter(match(process, "^terminal$"))), 0), unusual_cmdline_feature_-name=if(match(process, "^-name$"), mvcount(mvfilter(match(process, "^-name$"))), 0), unusual_cmdline_feature_catch=if(match(process, "^catch$"), mvcount(mvfilter(match(process, "^catch$"))), 0), unusual_cmdline_feature_get-wmiobject=if(match(process, "^get-wmiobject$"), mvcount(mvfilter(match(process, "^get-wmiobject$"))), 0), unusual_cmdline_feature_hklm=if(match(process, "^hklm$"), mvcount(mvfilter(match(process, "^hklm$"))), 0), unusual_cmdline_feature_streamreader=if(match(process, "^streamreader$"), mvcount(mvfilter(match(process, "^streamreader$"))), 0), unusual_cmdline_feature_system32=if(match(process, "^system32$"), mvcount(mvfilter(match(process, "^system32$"))), 0), unusual_cmdline_feature_username=if(match(process, "^username$"), mvcount(mvfilter(match(process, "^username$"))), 0), unusual_cmdline_feature_webrequest=if(match(process, "^webrequest$"), mvcount(mvfilter(match(process, "^webrequest$"))), 0), unusual_cmdline_feature_count=if(match(process, "^count$"), mvcount(mvfilter(match(process, "^count$"))), 0), unusual_cmdline_feature_webclient=if(match(process, "^webclient$"), mvcount(mvfilter(match(process, "^webclient$"))), 0), unusual_cmdline_feature_writeallbytes=if(match(process, "^writeallbytes$"), mvcount(mvfilter(match(process, "^writeallbytes$"))), 0), unusual_cmdline_feature_convert=if(match(process, "^convert$"), mvcount(mvfilter(match(process, "^convert$"))), 0), unusual_cmdline_feature_create=if(match(process, "^create$"), mvcount(mvfilter(match(process, "^create$"))), 0), unusual_cmdline_feature_function=if(match(process, "^function$"), mvcount(mvfilter(match(process, "^function$"))), 0), unusual_cmdline_feature_net=if(match(process, "^net$"), mvcount(mvfilter(match(process, "^net$"))), 0), unusual_cmdline_feature_com=if(match(process, "^com$"), mvcount(mvfilter(match(process, "^com$"))), 0), unusual_cmdline_feature_http=if(match(process, "^http$"), mvcount(mvfilter(match(process, "^http$"))), 0), unusual_cmdline_feature_io=if(match(process, "^io$"), mvcount(mvfilter(match(process, "^io$"))), 0), unusual_cmdline_feature_system=if(match(process, "^system$"), mvcount(mvfilter(match(process, "^system$"))), 0), unusual_cmdline_feature_new-object=if(match(process, "^new-object$"), mvcount(mvfilter(match(process, "^new-object$"))), 0), unusual_cmdline_feature_if=if(match(process, "^if$"), mvcount(mvfilter(match(process, "^if$"))), 0), unusual_cmdline_feature_threading=if(match(process, "^threading$"), mvcount(mvfilter(match(process, "^threading$"))), 0), unusual_cmdline_feature_mutex=if(match(process, "^mutex$"), mvcount(mvfilter(match(process, "^mutex$"))), 0), unusual_cmdline_feature_cryptography=if(match(process, "^cryptography$"), mvcount(mvfilter(match(process, "^cryptography$"))), 0), unusual_cmdline_feature_computehash=if(match(process, "^computehash$"), mvcount(mvfilter(match(process, "^computehash$"))), 0) | apply unusual_commandline_detection | eval score='predicted(unusual_cmdline_logits)', process=orig_process | fields - unusual_cmdline* predicted(unusual_cmdline_logits) orig_process +definition: eval orig_process=process, process=replace(lower(process), "`", "") | makemv tokenizer="([\w\d\-]+)" process | eval unusual_cmdline_feature_for=if(match(process, "^for$"), mvcount(mvfilter(match(process, "^for$"))), 0), unusual_cmdline_feature_netsh=if(match(process, "^netsh$"), mvcount(mvfilter(match(process, "^netsh$"))), 0), unusual_cmdline_feature_readbytes=if(match(process, "^readbytes$"), mvcount(mvfilter(match(process, "^readbytes$"))), 0), unusual_cmdline_feature_set=if(match(process, "^set$"), mvcount(mvfilter(match(process, "^set$"))), 0), unusual_cmdline_feature_unrestricted=if(match(process, "^unrestricted$"), mvcount(mvfilter(match(process, "^unrestricted$"))), 0), unusual_cmdline_feature_winstations=if(match(process, "^winstations$"), mvcount(mvfilter(match(process, "^winstations$"))), 0), unusual_cmdline_feature_-value=if(match(process, "^-value$"), mvcount(mvfilter(match(process, "^-value$"))), 0), unusual_cmdline_feature_compression=if(match(process, "^compression$"), mvcount(mvfilter(match(process, "^compression$"))), 0), unusual_cmdline_feature_server=if(match(process, "^server$"), mvcount(mvfilter(match(process, "^server$"))), 0), unusual_cmdline_feature_set-mppreference=if(match(process, "^set-mppreference$"), mvcount(mvfilter(match(process, "^set-mppreference$"))), 0), unusual_cmdline_feature_terminal=if(match(process, "^terminal$"), mvcount(mvfilter(match(process, "^terminal$"))), 0), unusual_cmdline_feature_-name=if(match(process, "^-name$"), mvcount(mvfilter(match(process, "^-name$"))), 0), unusual_cmdline_feature_catch=if(match(process, "^catch$"), mvcount(mvfilter(match(process, "^catch$"))), 0), unusual_cmdline_feature_get-wmiobject=if(match(process, "^get-wmiobject$"), mvcount(mvfilter(match(process, "^get-wmiobject$"))), 0), unusual_cmdline_feature_hklm=if(match(process, "^hklm$"), mvcount(mvfilter(match(process, "^hklm$"))), 0), unusual_cmdline_feature_streamreader=if(match(process, "^streamreader$"), mvcount(mvfilter(match(process, "^streamreader$"))), 0), unusual_cmdline_feature_system32=if(match(process, "^system32$"), mvcount(mvfilter(match(process, "^system32$"))), 0), unusual_cmdline_feature_username=if(match(process, "^username$"), mvcount(mvfilter(match(process, "^username$"))), 0), unusual_cmdline_feature_webrequest=if(match(process, "^webrequest$"), mvcount(mvfilter(match(process, "^webrequest$"))), 0), unusual_cmdline_feature_count=if(match(process, "^count$"), mvcount(mvfilter(match(process, "^count$"))), 0), unusual_cmdline_feature_webclient=if(match(process, "^webclient$"), mvcount(mvfilter(match(process, "^webclient$"))), 0), unusual_cmdline_feature_writeallbytes=if(match(process, "^writeallbytes$"), mvcount(mvfilter(match(process, "^writeallbytes$"))), 0), unusual_cmdline_feature_convert=if(match(process, "^convert$"), mvcount(mvfilter(match(process, "^convert$"))), 0), unusual_cmdline_feature_create=if(match(process, "^create$"), mvcount(mvfilter(match(process, "^create$"))), 0), unusual_cmdline_feature_function=if(match(process, "^function$"), mvcount(mvfilter(match(process, "^function$"))), 0), unusual_cmdline_feature_net=if(match(process, "^net$"), mvcount(mvfilter(match(process, "^net$"))), 0), unusual_cmdline_feature_com=if(match(process, "^com$"), mvcount(mvfilter(match(process, "^com$"))), 0), unusual_cmdline_feature_http=if(match(process, "^http$"), mvcount(mvfilter(match(process, "^http$"))), 0), unusual_cmdline_feature_io=if(match(process, "^io$"), mvcount(mvfilter(match(process, "^io$"))), 0), unusual_cmdline_feature_system=if(match(process, "^system$"), mvcount(mvfilter(match(process, "^system$"))), 0), unusual_cmdline_feature_new-object=if(match(process, "^new-object$"), mvcount(mvfilter(match(process, "^new-object$"))), 0), unusual_cmdline_feature_if=if(match(process, "^if$"), mvcount(mvfilter(match(process, "^if$"))), 0), unusual_cmdline_feature_threading=if(match(process, "^threading$"), mvcount(mvfilter(match(process, "^threading$"))), 0), unusual_cmdline_feature_mutex=if(match(process, "^mutex$"), mvcount(mvfilter(match(process, "^mutex$"))), 0), unusual_cmdline_feature_cryptography=if(match(process, "^cryptography$"), mvcount(mvfilter(match(process, "^cryptography$"))), 0), unusual_cmdline_feature_computehash=if(match(process, "^computehash$"), mvcount(mvfilter(match(process, "^computehash$"))), 0) description: Performs the tokenization and application of the malicious commandline classifier name: potentially_malicious_code_on_cmdline_tokenize_score \ No newline at end of file From f71e3fe2020e6baacb8c7d2afc39cef7a6e6bfbc Mon Sep 17 00:00:00 2001 From: Michael Hart Date: Thu, 27 Jan 2022 13:13:42 -0500 Subject: [PATCH 30/32] Adding references --- .../endpoint/potentially_malicious_code_on_commandline.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/detections/endpoint/potentially_malicious_code_on_commandline.yml b/detections/endpoint/potentially_malicious_code_on_commandline.yml index e1963313bc..d1c12f8291 100644 --- a/detections/endpoint/potentially_malicious_code_on_commandline.yml +++ b/detections/endpoint/potentially_malicious_code_on_commandline.yml @@ -29,7 +29,9 @@ known_false_positives: This model is an anomaly detector that identifies usage o and scripting constructs that are correllated with malicious activity. These APIs and scripting constructs are part of the programming langauge and advanced scripts may generate false positives. -references: [] +references: + - https://attack.mitre.org/techniques/T1059/003/ + - https://github.com/redcanaryco/atomic-red-team/blob/master/atomics/T1059.001/T1059.001.md tags: analytic_story: - Suspicious Command-Line Executions From c5db61e52dcbdff7edeea5883277afcb4e08cc2d Mon Sep 17 00:00:00 2001 From: Michael Haag <5632822+MHaggis@users.noreply.github.com> Date: Fri, 28 Jan 2022 12:49:03 -0700 Subject: [PATCH 31/32] Quick fix --- .../endpoint/potentially_malicious_code_on_commandline.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/detections/endpoint/potentially_malicious_code_on_commandline.yml b/detections/endpoint/potentially_malicious_code_on_commandline.yml index d1c12f8291..8f1590589b 100644 --- a/detections/endpoint/potentially_malicious_code_on_commandline.yml +++ b/detections/endpoint/potentially_malicious_code_on_commandline.yml @@ -60,13 +60,13 @@ tags: context: - source:endpoint - stage:Execution - message: Unusual commandline execution with hallmarks of malicious activity run by $user$ found on $dest$ with commandline $process$ + message: Unusual command-line execution with hallmarks of malicious activity run by $user$ found on $dest$ with commandline $process$ observable: - - name: ComputerName + - name: dest type: Hostname role: - Victim - - name: User + - name: user type: User role: - Victim \ No newline at end of file From 0911746b039cdb6df457d85ac554b287ddad3ea8 Mon Sep 17 00:00:00 2001 From: Michael Hart Date: Fri, 28 Jan 2022 16:08:25 -0500 Subject: [PATCH 32/32] Adding more detail to the description on how scoring works --- .../potentially_malicious_code_on_commandline.yml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/detections/endpoint/potentially_malicious_code_on_commandline.yml b/detections/endpoint/potentially_malicious_code_on_commandline.yml index 8f1590589b..379e346161 100644 --- a/detections/endpoint/potentially_malicious_code_on_commandline.yml +++ b/detections/endpoint/potentially_malicious_code_on_commandline.yml @@ -9,8 +9,13 @@ datamodel: description: The following analytic uses a pretrained machine learning text classifier to detect potentially malicious commandlines. The model identifies unusual combinations of keywords found in samples of commandlines where adversaries executed - code, primarily for C2 communication. These combinations of keywords are not - typically found in normal usage of the commandline. + powershell code, primarily for C2 communication. For example, adversaries will leverage + IO capabilities such as "streamreader" and "webclient", threading capabilties such as + "mutex" locks, programmatic constructs like "function" and "catch", and cryptographic + operations like "computehash". Although observing one of these keywords in a commandline + script is possible, combinations of keywords observed in attack data are not typically + found in normal usage of the commandline. The model will output a score where all values + above zero are suspicious, anything greater than one particularly so. search: '| tstats `security_content_summariesonly` count min(_time) as firstTime max(_time) as lastTime from datamodel="Endpoint.Processes" by Processes.parent_process_name Processes.process_name Processes.process