From 13e49e6589b1160928ec85678884da0e72e986f3 Mon Sep 17 00:00:00 2001 From: andrea-youwakim <117778222+andrea-youwakim@users.noreply.github.com> Date: Wed, 19 Jul 2023 15:24:08 -0600 Subject: [PATCH] New: Tailscale Detections and Pack (#852) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * New: Tailscale Detections and Pack * fix: fmt * fix: tailscale log events seem to have an 'event' attribute that wraps everything other than 'fields' (#853) --------- Co-authored-by: Ed⁦ --- global_helpers/global_filter_tailscale.py | 2 +- global_helpers/global_helpers_test.py | 23 ++-- global_helpers/panther_tailscale_helpers.py | 6 +- packs/tailscale.yml | 13 +++ .../tailscale_https_disabled.py | 35 ++++++ .../tailscale_https_disabled.yml | 99 +++++++++++++++++ ..._machine_approval_requirements_disabled.py | 34 ++++++ ...machine_approval_requirements_disabled.yml | 100 ++++++++++++++++++ .../tailscale_magicdns_disabled.py | 35 ++++++ .../tailscale_magicdns_disabled.yml | 99 +++++++++++++++++ 10 files changed, 432 insertions(+), 14 deletions(-) create mode 100644 packs/tailscale.yml create mode 100644 rules/tailscale_rules/tailscale_https_disabled.py create mode 100644 rules/tailscale_rules/tailscale_https_disabled.yml create mode 100644 rules/tailscale_rules/tailscale_machine_approval_requirements_disabled.py create mode 100644 rules/tailscale_rules/tailscale_machine_approval_requirements_disabled.yml create mode 100644 rules/tailscale_rules/tailscale_magicdns_disabled.py create mode 100644 rules/tailscale_rules/tailscale_magicdns_disabled.yml diff --git a/global_helpers/global_filter_tailscale.py b/global_helpers/global_filter_tailscale.py index 42e9b5978..4ab47fe63 100644 --- a/global_helpers/global_filter_tailscale.py +++ b/global_helpers/global_filter_tailscale.py @@ -17,7 +17,7 @@ def filter_include_event(event) -> bool: # pylint: disable=unused-argument # # # example: event.origin # # if we don't know the event_origin, we want default behavior to be to alert on this event. - # event_origin = deep_get(event, "origin", default="") + # event_origin = deep_get(event, "event", "origin", default="") # return event_origin in ["ADMIN_CONSOLE", ""] # return True diff --git a/global_helpers/global_helpers_test.py b/global_helpers/global_helpers_test.py index 29324895e..55c07471c 100755 --- a/global_helpers/global_helpers_test.py +++ b/global_helpers/global_helpers_test.py @@ -1879,17 +1879,20 @@ class TestTailscaleHelpers(unittest.TestCase): def setUp(self): self.event = ImmutableCaseInsensitiveDict( { - "action": "CREATE", - "actor": { - "displayName": "Homer Simpson", - "id": "uodc9f3CNTRL", - "loginName": "homer.simpson@yourcompany.io", - "type": "USER", + "event": { + "action": "CREATE", + "actor": { + "displayName": "Homer Simpson", + "id": "uodc9f3CNTRL", + "loginName": "homer.simpson@yourcompany.io", + "type": "USER", + }, + "eventGroupID": "9f880e02981e341447958344b7b4071f", + "new": {}, + "origin": "ADMIN_CONSOLE", + "target": {"id": "k6r3fm3CNTRL", "name": "API key", "type": "API_KEY"}, }, - "eventGroupID": "9f880e02981e341447958344b7b4071f", - "new": {}, - "origin": "ADMIN_CONSOLE", - "target": {"id": "k6r3fm3CNTRL", "name": "API key", "type": "API_KEY"}, + "fields": {"recorded": "2023-07-19 16:10:48.385283827"}, } ) diff --git a/global_helpers/panther_tailscale_helpers.py b/global_helpers/panther_tailscale_helpers.py index 39062a99c..2f4bdbada 100644 --- a/global_helpers/panther_tailscale_helpers.py +++ b/global_helpers/panther_tailscale_helpers.py @@ -3,11 +3,11 @@ def tailscale_alert_context(event) -> dict: a_c = {} - a_c["actor"] = deep_get(event, "actor", default="") - a_c["action"] = deep_get(event, "action", default="") + a_c["actor"] = deep_get(event, "event", "actor", default="") + a_c["action"] = deep_get(event, "event", "action", default="") return a_c def is_tailscale_admin_console_event(event): - origin = deep_get(event, "origin", default="") + origin = deep_get(event, "event", "origin", default="") return origin == "ADMIN_CONSOLE" diff --git a/packs/tailscale.yml b/packs/tailscale.yml new file mode 100644 index 000000000..be101abab --- /dev/null +++ b/packs/tailscale.yml @@ -0,0 +1,13 @@ +AnalysisType: pack +PackID: PantherManaged.Tailscale +Description: Group of all Tailscale detections +PackDefinition: + IDs: + - Tailscale.Magic.DNS.Disabled + - Tailscale.HTTPS.Disabled + - Tailscale.Machine.Approval.Requirements.Disabled + # Globals used in these detections + - panther_base_helpers + - panther_tailscale_helpers + - global_filter_tailscale +DisplayName: "Panther Tailscale Pack" diff --git a/rules/tailscale_rules/tailscale_https_disabled.py b/rules/tailscale_rules/tailscale_https_disabled.py new file mode 100644 index 000000000..d69eac9f4 --- /dev/null +++ b/rules/tailscale_rules/tailscale_https_disabled.py @@ -0,0 +1,35 @@ +from global_filter_tailscale import filter_include_event +from panther_base_helpers import deep_get +from panther_tailscale_helpers import ( + is_tailscale_admin_console_event, + tailscale_alert_context, +) + + +def rule(event): + if not filter_include_event(event): + return False + action = deep_get(event, "event", "action", default="") + target_property = deep_get( + event, "event", "target", "property", default="" + ) + return all( + [ + action == "DISABLE", + target_property == "HTTPS", + is_tailscale_admin_console_event(event), + ] + ) + + +def title(event): + user = deep_get(event, "event", "actor", "loginName", default="") + target_id = deep_get(event, "event", "target", "id", default="") + return ( + f"Tailscale user [{user}] disabled HTTPS for " + f"[{target_id}] in your organization’s tenant." + ) + + +def alert_context(event): + return tailscale_alert_context(event) diff --git a/rules/tailscale_rules/tailscale_https_disabled.yml b/rules/tailscale_rules/tailscale_https_disabled.yml new file mode 100644 index 000000000..15dd0a239 --- /dev/null +++ b/rules/tailscale_rules/tailscale_https_disabled.yml @@ -0,0 +1,99 @@ +AnalysisType: rule +Description: A Tailscale User disabled HTTPS settings in your organization's tenant. +DisplayName: "Tailscale HTTPS Disabled" +Enabled: true +Filename: tailscale_https_disabled.py +Runbook: Assess if this was done by the user for a valid business reason. Be vigilant to re-enable this setting as it's in the best security interest for your organization's security posture. +Severity: High +Tests: + - ExpectedResult: true + Log: + { + "event": { + "action": "DISABLE", + "actor": { + "displayName": "Homer Simpson", + "id": "uodc9f3CNTRL", + "loginName": "homer.simpson@yourcompany.io", + "type": "USER" + }, + "eventGroupID": "1770eb26fb58fbf67fd8fbfcc2056e66", + "origin": "ADMIN_CONSOLE", + "target": { + "id": "yoururl.com", + "name": "yoururl.com", + "property": "HTTPS", + "type": "TAILNET" + }, + }, + "fields": { + "recorded": "2023-07-19 16:10:48.385283827" + }, + "p_any_actor_ids": [ + "uodc9f3CNTRL" + ], + "p_any_emails": [ + "homer.simpson@yourcompany.io" + ], + "p_any_usernames": [ + "andrea.youwakim" + ], + "p_event_time": "2023-07-19 16:10:48.172000", + "p_log_type": "Tailscale.Audit", + "p_parse_time": "2023-07-19 16:13:56.849092", + "p_row_id": "5e197fb53834e39eeab7feb9198d04", + "p_schema_version": 0, + "p_source_id": "5d65e24a-7ebb-403b-803c-51396e03d201", + "p_source_label": "Tailscale Audit and Network Logs", + "p_udm": {}, + "time": "2023-07-19 16:10:48.172000000" + } + Name: HTTPS Disabled + - ExpectedResult: false + Log: + { + "event": { + "action": "CREATE", + "actor": { + "displayName": "Homer Simpson", + "id": "uodc9f3CNTRL", + "loginName": "homer.simpson@yourcompany.io", + "type": "USER" + }, + "eventGroupID": "9f880e02981e341447958344b7b4071f", + "new": {}, + "origin": "ADMIN_CONSOLE", + "target": { + "id": "k6r3fm3CNTRL", + "name": "API key", + "type": "API_KEY" + }, + }, + "fields": { + "recorded": "2023-07-19 16:11:41.778839718" + }, + "p_any_actor_ids": [ + "uodc9f3CNTRL" + ], + "p_any_emails": [ + "homer.simpson@yourcompany.io" + ], + "p_any_usernames": [ + "homersimpson" + ], + "p_event_time": "2023-07-19 16:11:41.601000", + "p_log_type": "Tailscale.Audit", + "p_parse_time": "2023-07-19 16:14:56.865276", + "p_row_id": "02eaf97ec9caaaabff8882ba19ad1d", + "p_schema_version": 0, + "p_source_id": "5d65e24a-7ebb-403b-803c-51396e03d201", + "p_source_label": "Tailscale Audit and Network Logs", + "p_udm": {}, + "time": "2023-07-19 16:11:41.601000000" + } + Name: Other Event +DedupPeriodMinutes: 60 +LogTypes: + - Tailscale.Audit +RuleID: "Tailscale.HTTPS.Disabled" +Threshold: 1 diff --git a/rules/tailscale_rules/tailscale_machine_approval_requirements_disabled.py b/rules/tailscale_rules/tailscale_machine_approval_requirements_disabled.py new file mode 100644 index 000000000..ee8f08e93 --- /dev/null +++ b/rules/tailscale_rules/tailscale_machine_approval_requirements_disabled.py @@ -0,0 +1,34 @@ +from global_filter_tailscale import filter_include_event +from panther_base_helpers import deep_get +from panther_tailscale_helpers import ( + is_tailscale_admin_console_event, + tailscale_alert_context, +) + + +def rule(event): + if not filter_include_event(event): + return False + action = deep_get(event, "event", "action", default="") + target_property = deep_get( + event, "event", "target", "property", default="" + ) + return all( + [ + action == "DISABLE", + target_property == "MACHINE_APPROVAL_NEEDED", + is_tailscale_admin_console_event(event), + ] + ) + + +def title(event): + user = deep_get(event, "event", "actor", "loginName", default="") + return ( + f"Tailscale user [{user}] disabled device approval requirements " + f"for new devices accessing your organization’s network." + ) + + +def alert_context(event): + return tailscale_alert_context(event) diff --git a/rules/tailscale_rules/tailscale_machine_approval_requirements_disabled.yml b/rules/tailscale_rules/tailscale_machine_approval_requirements_disabled.yml new file mode 100644 index 000000000..268e95db4 --- /dev/null +++ b/rules/tailscale_rules/tailscale_machine_approval_requirements_disabled.yml @@ -0,0 +1,100 @@ +AnalysisType: rule +Description: A Tailscale User disabled machine approval requirement settings in your organization's tenant. This means devices can access your network without requiring approval. +DisplayName: "Tailscale Machine Approval Requirements Disabled" +Enabled: true +Filename: tailscale_machine_approval_requirements_disabled.py +Runbook: Assess if this was done by the user for a valid business reason. Be vigilant to re-enable this setting as it's in the best security interest for your organization's security posture. +Severity: High +Tests: + - ExpectedResult: true + Log: + { + "event": { + "action": "DISABLE", + "actor": { + "displayName": "Homer Simpson", + "id": "uhfQwM4CNTRL", + "loginName": "homer.simpson@yourcompany.io", + "type": "USER" + }, + "eventGroupID": "6dae044c7a8998599e94657b511d28f9", + "origin": "ADMIN_CONSOLE", + "target": { + "id": "panther.com", + "name": "panther.com", + "property": "MACHINE_APPROVAL_NEEDED", + "type": "TAILNET" + }, + }, + "fields": { + "recorded": "2023-06-27 22:58:15.824694387" + }, + "p_any_emails": [ + "homer.simpson@yourcompany.io" + ], + "p_any_md5_hashes": [ + "6dae044c7a8998599e94657b511d28f9" + ], + "p_any_usernames": [ + "homersimpson" + ], + "p_event_time": "2023-06-27 23:02:08.54", + "p_log_type": "Custom.TailscaleAudit", + "p_parse_time": "2023-06-27 23:02:08.54", + "p_row_id": "8ec49771e630f6e8e5fdb28319d95c", + "p_schema_version": 4, + "p_source_id": "3acfbe1d-f7b2-4c3f-a26e-8da418fd29ef", + "p_source_label": "Custom Tailscale Audit", + "p_timeline": "2023-06-27 23:02:08.54", + "p_udm": {}, + "time": 1687906694.915 + } + Name: Machine Approval Requirements Disabled + - ExpectedResult: false + Log: + { + "event": { + "action": "CREATE", + "actor": { + "displayName": "Homer Simpson", + "id": "uodc9f3CNTRL", + "loginName": "homer.simpson@yourcompany.io", + "type": "USER" + }, + "eventGroupID": "9f880e02981e341447958344b7b4071f", + "new": {}, + "origin": "ADMIN_CONSOLE", + "target": { + "id": "k6r3fm3CNTRL", + "name": "API key", + "type": "API_KEY" + }, + }, + "fields": { + "recorded": "2023-07-19 16:11:41.778839718" + }, + "p_any_actor_ids": [ + "uodc9f3CNTRL" + ], + "p_any_emails": [ + "homer.simpson@yourcompany.io" + ], + "p_any_usernames": [ + "homersimpson" + ], + "p_event_time": "2023-07-19 16:11:41.601000", + "p_log_type": "Tailscale.Audit", + "p_parse_time": "2023-07-19 16:14:56.865276", + "p_row_id": "02eaf97ec9caaaabff8882ba19ad1d", + "p_schema_version": 0, + "p_source_id": "5d65e24a-7ebb-403b-803c-51396e03d201", + "p_source_label": "Tailscale Audit and Network Logs", + "p_udm": {}, + "time": "2023-07-19 16:11:41.601000000" + } + Name: Other Event +DedupPeriodMinutes: 60 +LogTypes: + - Tailscale.Audit +RuleID: "Tailscale.Machine.Approval.Requirements.Disabled" +Threshold: 1 diff --git a/rules/tailscale_rules/tailscale_magicdns_disabled.py b/rules/tailscale_rules/tailscale_magicdns_disabled.py new file mode 100644 index 000000000..1f1f499ad --- /dev/null +++ b/rules/tailscale_rules/tailscale_magicdns_disabled.py @@ -0,0 +1,35 @@ +from global_filter_tailscale import filter_include_event +from panther_base_helpers import deep_get +from panther_tailscale_helpers import ( + is_tailscale_admin_console_event, + tailscale_alert_context, +) + + +def rule(event): + if not filter_include_event(event): + return False + action = deep_get(event, "event", "action", default="") + target_property = deep_get( + event, "event", "target", "property", default="" + ) + return all( + [ + action == "DISABLE", + target_property == "MAGIC_DNS", + is_tailscale_admin_console_event(event), + ] + ) + + +def title(event): + user = deep_get(event, "event", "actor", "loginName", default="") + target_id = deep_get(event, "event", "target", "id", default="") + return ( + f"Tailscale user [{user}] disabled Magic DNS for " + f"[{target_id}] in your organization’s tenant." + ) + + +def alert_context(event): + return tailscale_alert_context(event) diff --git a/rules/tailscale_rules/tailscale_magicdns_disabled.yml b/rules/tailscale_rules/tailscale_magicdns_disabled.yml new file mode 100644 index 000000000..513da6419 --- /dev/null +++ b/rules/tailscale_rules/tailscale_magicdns_disabled.yml @@ -0,0 +1,99 @@ +AnalysisType: rule +Description: A Tailscale User disabled magic dns settings in your organization's tenant. +DisplayName: "Tailscale Magic DNS Disabled" +Enabled: true +Filename: tailscale_magicdns_disabled.py +Runbook: Assess if this was done by the user for a valid business reason. Be vigilant to re-enable this setting as it's in the best security interest for your organization's security posture. +Severity: High +Tests: + - ExpectedResult: true + Log: + { + "event": { + "action": "DISABLE", + "actor": { + "displayName": "Homer Simpson", + "id": "uodc9f3CNTRL", + "loginName": "homer.simpson@yourcompany.io", + "type": "USER" + }, + "eventGroupID": "017676eb3de31cd31c0be96b965c2970", + "origin": "ADMIN_CONSOLE", + "target": { + "id": "yoururl.com", + "name": "yoururl.com", + "property": "MAGIC_DNS", + "type": "TAILNET" + }, + }, + "fields": { + "recorded": "2023-07-19 16:10:38.825360311" + }, + "p_any_actor_ids": [ + "uodc9f3CNTRL" + ], + "p_any_emails": [ + "homer.simpson@yourcompany.io" + ], + "p_any_usernames": [ + "homer.simpson" + ], + "p_event_time": "2023-07-19 16:10:38.365000", + "p_log_type": "Tailscale.Audit", + "p_parse_time": "2023-07-19 16:13:56.849016", + "p_row_id": "5e197fb53834e39eeab7feb9198904", + "p_schema_version": 0, + "p_source_id": "5d65e24a-7ebb-403b-803c-51396e03d201", + "p_source_label": "Tailscale Audit and Network Logs", + "p_udm": {}, + "time": "2023-07-19 16:10:38.365000000" + } + Name: Magic DNS Disabled + - ExpectedResult: false + Log: + { + "event": { + "action": "CREATE", + "actor": { + "displayName": "Homer Simpson", + "id": "uodc9f3CNTRL", + "loginName": "homer.simpson@yourcompany.io", + "type": "USER" + }, + "eventGroupID": "9f880e02981e341447958344b7b4071f", + "new": {}, + "origin": "ADMIN_CONSOLE", + "target": { + "id": "k6r3fm3CNTRL", + "name": "API key", + "type": "API_KEY" + }, + }, + "fields": { + "recorded": "2023-07-19 16:11:41.778839718" + }, + "p_any_actor_ids": [ + "uodc9f3CNTRL" + ], + "p_any_emails": [ + "homer.simpson@yourcompany.io" + ], + "p_any_usernames": [ + "homersimpson" + ], + "p_event_time": "2023-07-19 16:11:41.601000", + "p_log_type": "Tailscale.Audit", + "p_parse_time": "2023-07-19 16:14:56.865276", + "p_row_id": "02eaf97ec9caaaabff8882ba19ad1d", + "p_schema_version": 0, + "p_source_id": "5d65e24a-7ebb-403b-803c-51396e03d201", + "p_source_label": "Tailscale Audit and Network Logs", + "p_udm": {}, + "time": "2023-07-19 16:11:41.601000000" + } + Name: Other Event +DedupPeriodMinutes: 60 +LogTypes: + - Tailscale.Audit +RuleID: "Tailscale.Magic.DNS.Disabled" +Threshold: 1