From 60aaeb76b9bf59b13531f30ab916d0a8dee77b8c Mon Sep 17 00:00:00 2001 From: Evan Gibler Date: Tue, 13 Feb 2024 11:50:03 -0600 Subject: [PATCH 01/11] updated broken link (#78) (#1103) Co-authored-by: Ariel Ropek <79653153+arielkr256@users.noreply.github.com> --- rules/gcp_audit_rules/gcp_gcs_public.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rules/gcp_audit_rules/gcp_gcs_public.py b/rules/gcp_audit_rules/gcp_gcs_public.py index 02dabe399..28743607d 100644 --- a/rules/gcp_audit_rules/gcp_gcs_public.py +++ b/rules/gcp_audit_rules/gcp_gcs_public.py @@ -12,7 +12,7 @@ def rule(event): if not service_data: return False - # Reference: bit.ly/2WsJdZS + # Reference: https://cloud.google.com/iam/docs/policies binding_deltas = deep_get(service_data, "policyDelta", "bindingDeltas") if not binding_deltas: return False From 9b31818d4ae097fa7c9093a8bd985c002bef7449 Mon Sep 17 00:00:00 2001 From: Evan Gibler Date: Tue, 13 Feb 2024 11:55:25 -0600 Subject: [PATCH 02/11] [sync] GCP compute.instances.create Privilege Escalation - rule (#63) (#1100) * GCP compute.instances.create Privilege Escalation - rule * GCP compute.instances.create Privilege Escalation - check KeyPath existence * GCP compute.instances.create Privilege Escalation - python rule * GCP compute.instances.create Privilege Escalation - linter fix Co-authored-by: akozlovets098 <95437895+akozlovets098@users.noreply.github.com> --- ...teinstances_create_privilege_escalation.py | 62 ++++ ...einstances_create_privilege_escalation.yml | 346 ++++++++++++++++++ 2 files changed, 408 insertions(+) create mode 100644 rules/gcp_audit_rules/gcp_computeinstances_create_privilege_escalation.py create mode 100644 rules/gcp_audit_rules/gcp_computeinstances_create_privilege_escalation.yml diff --git a/rules/gcp_audit_rules/gcp_computeinstances_create_privilege_escalation.py b/rules/gcp_audit_rules/gcp_computeinstances_create_privilege_escalation.py new file mode 100644 index 000000000..beb37b249 --- /dev/null +++ b/rules/gcp_audit_rules/gcp_computeinstances_create_privilege_escalation.py @@ -0,0 +1,62 @@ +from gcp_base_helpers import gcp_alert_context +from panther_base_helpers import deep_get + +REQUIRED_PERMISSIONS = [ + "compute.disks.create", + "compute.instances.create", + "compute.instances.setMetadata", + "compute.instances.setServiceAccount", + "compute.subnetworks.use", + "compute.subnetworks.useExternalIp", +] + + +def rule(event): + if deep_get(event, "protoPayload", "response", "error"): + return False + + method = deep_get(event, "protoPayload", "methodName") + if not method.endswith("compute.instances.insert"): + return False + + authorization_info = deep_get(event, "protoPayload", "authorizationInfo") + if not authorization_info: + return False + + granted_permissions = {} + for auth in authorization_info: + granted_permissions[auth["permission"]] = auth["granted"] + for permission in REQUIRED_PERMISSIONS: + if not granted_permissions.get(permission): + return False + + return True + + +def title(event): + actor = deep_get( + event, "protoPayload", "authenticationInfo", "principalEmail", default="" + ) + + service_accounts = deep_get(event, "protoPayload", "request", "serviceAccounts") + if not service_accounts: + service_account_emails = "" + else: + service_account_emails = [service_acc["email"] for service_acc in service_accounts] + + project = deep_get(event, "resource", "labels", "project_id", default="") + return ( + f"[GCP]: [{actor}] created a new Compute Engine instance with [{service_account_emails}] " + f"Service Account on project [{project}]" + ) + + +def alert_context(event): + context = gcp_alert_context(event) + service_accounts = deep_get(event, "protoPayload", "request", "serviceAccounts") + if not service_accounts: + service_account_emails = "" + else: + service_account_emails = [service_acc["email"] for service_acc in service_accounts] + context["serviceAccount"] = service_account_emails + return context diff --git a/rules/gcp_audit_rules/gcp_computeinstances_create_privilege_escalation.yml b/rules/gcp_audit_rules/gcp_computeinstances_create_privilege_escalation.yml new file mode 100644 index 000000000..a0b4cd0e0 --- /dev/null +++ b/rules/gcp_audit_rules/gcp_computeinstances_create_privilege_escalation.yml @@ -0,0 +1,346 @@ +AnalysisType: rule +LogTypes: + - GCP.AuditLog +Description: Detects compute.instances.create method for privilege escalation in GCP. +DisplayName: "GCP compute.instances.create Privilege Escalation" +RuleID: "GCP.compute.instances.create.Privilege.Escalation" +Enabled: true +Reference: https://rhinosecuritylabs.com/gcp/privilege-escalation-google-cloud-platform-part-1/ +Runbook: Confirm this was authorized and necessary behavior. +Reports: + MITRE ATT&CK: + - TA0004:T1548 # Abuse Elevation Control Mechanism +Severity: High +Filename: gcp_computeinstances_create_privilege_escalation.py +DedupPeriodMinutes: 60 +Threshold: 1 +Tests: + - + Name: GCP compute.instances - Potential Privilege Escalation + ExpectedResult: true + Log: + { + "protoPayload": { + "at_sign_type": "type.googleapis.com/google.cloud.audit.AuditLog", + "authenticationInfo": { + "principalEmail": "some.user@company.com", + "principalSubject": "user:some.user@company.com" + }, + "authorizationInfo": [ + { + "granted": true, + "permission": "compute.instances.create", + "resource": "projects/some-project/zones/us-central1-f/instances/abc", + "resourceAttributes": { + "name": "projects/some-project/zones/us-central1-f/instances/abc", + "service": "compute", + "type": "compute.instances" + } + }, + { + "granted": true, + "permission": "compute.disks.create", + "resource": "projects/some-project/zones/us-central1-f/disks/abc", + "resourceAttributes": { + "name": "projects/some-project/zones/us-central1-f/disks/abc", + "service": "compute", + "type": "compute.disks" + } + }, + { + "granted": true, + "permission": "compute.subnetworks.use", + "resource": "projects/some-project/regions/us-central1/subnetworks/default", + "resourceAttributes": { + "name": "projects/some-project/regions/us-central1/subnetworks/default", + "service": "compute", + "type": "compute.subnetworks" + } + }, + { + "granted": true, + "permission": "compute.subnetworks.useExternalIp", + "resource": "projects/some-project/regions/us-central1/subnetworks/default", + "resourceAttributes": { + "name": "projects/some-project/regions/us-central1/subnetworks/default", + "service": "compute", + "type": "compute.subnetworks" + } + }, + { + "granted": true, + "permission": "compute.instances.setMetadata", + "resource": "projects/some-project/zones/us-central1-f/instances/abc", + "resourceAttributes": { + "name": "projects/some-project/zones/us-central1-f/instances/abc", + "service": "compute", + "type": "compute.instances" + } + }, + { + "granted": true, + "permission": "compute.instances.setServiceAccount", + "resource": "projects/some-project/zones/us-central1-f/instances/abc", + "resourceAttributes": { + "name": "projects/some-project/zones/us-central1-f/instances/abc", + "service": "compute", + "type": "compute.instances" + } + } + ], + "methodName": "v1.compute.instances.insert", + "request": { + "@type": "type.googleapis.com/compute.instances.insert", + "disks": ..., + "machineType": ..., + "name": ..., + "networkInterfaces": ..., + "serviceAccounts": [ + { + "email": "abcmail@some-project.iam.gserviceaccount.com", + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/iam" + ] + } + ] + }, + "requestMetadata": { + "callerIP": "1.2.3.4", + "callerSuppliedUserAgent": "(gzip),gzip(gfe)", + "destinationAttributes": { }, + "requestAttributes": { + "auth": { }, + "time": "2024-01-30T12:52:36.003867Z" + } + }, + "resourceLocation": ..., + "resourceName": "projects/some-project/zones/us-central1-f/instances/abc", + "response": { + "@type": "type.googleapis.com/operation", + "id": "8758546889396539388", + "insertTime": "2024-01-30T04:52:35.886-08:00", + "name": "operation-1706619154623-610293c7a6a25-934f1c35-1efebb12", + "operationType": "insert", + "progress": "0", + "selfLink": "https://www.googleapis.com/compute/v1/projects/some-project/zones/us-central1-f/operations/operation-1706619154623-610293c7a6a25-934f1c35-1efebb12", + "selfLinkWithId": "https://www.googleapis.com/compute/v1/projects/some-project/zones/us-central1-f/operations/8758546889396539388", + "startTime": "2024-01-30T04:52:35.887-08:00", + "status": "RUNNING", + "targetId": "1454427709413609468", + "targetLink": "https://www.googleapis.com/compute/v1/projects/some-project/zones/us-central1-f/instances/abc", + "user": "some.user@company.com", + "zone": "https://www.googleapis.com/compute/v1/projects/some-project/zones/us-central1-f" + }, + "serviceName": "compute.googleapis.com" + }, + "receiveTimestamp": "2024-01-30 12:52:36.642422049", + "resource": { + "labels": { + "instance_id": "1454427709413609468", + "project_id": "some-project", + "zone": "us-central1-f" + }, + "type": "gce_instance" + }, + "severity": "NOTICE", + "timestamp": "2024-01-30 12:52:34.676384000" + } + - + Name: GCP compute.instances - Error + ExpectedResult: false + Log: + { + "protoPayload": { + "at_sign_type": "type.googleapis.com/google.cloud.audit.AuditLog", + "authenticationInfo": { + "principalEmail": "some.user@company.com", + "principalSubject": "user:some.user@company.com" + }, + "authorizationInfo": [ + { + "granted": true, + "permission": "compute.instances.create", + "resource": "projects/some-project/zones/us-central1-f/instances/abc", + "resourceAttributes": { + "name": "projects/some-project/zones/us-central1-f/instances/abc", + "service": "compute", + "type": "compute.instances" + } + }, + { + "granted": true, + "permission": "compute.disks.create", + "resource": "projects/some-project/zones/us-central1-f/disks/abc", + "resourceAttributes": { + "name": "projects/some-project/zones/us-central1-f/disks/abc", + "service": "compute", + "type": "compute.disks" + } + }, + { + "granted": true, + "permission": "compute.subnetworks.use", + "resource": "projects/some-project/regions/us-central1/subnetworks/default", + "resourceAttributes": { + "name": "projects/some-project/regions/us-central1/subnetworks/default", + "service": "compute", + "type": "compute.subnetworks" + } + }, + { + "granted": true, + "permission": "compute.subnetworks.useExternalIp", + "resource": "projects/some-project/regions/us-central1/subnetworks/default", + "resourceAttributes": { + "name": "projects/some-project/regions/us-central1/subnetworks/default", + "service": "compute", + "type": "compute.subnetworks" + } + }, + { + "granted": true, + "permission": "compute.instances.setMetadata", + "resource": "projects/some-project/zones/us-central1-f/instances/abc", + "resourceAttributes": { + "name": "projects/some-project/zones/us-central1-f/instances/abc", + "service": "compute", + "type": "compute.instances" + } + }, + { + "granted": true, + "permission": "compute.instances.setServiceAccount", + "resource": "projects/some-project/zones/us-central1-f/instances/abc", + "resourceAttributes": { + "name": "projects/some-project/zones/us-central1-f/instances/abc", + "service": "compute", + "type": "compute.instances" + } + } + ], + "methodName": "v1.compute.instances.insert", + "request": { + "@type": ..., + "disks": ..., + "machineType": ..., + "name": ..., + "networkInterfaces": ..., + "serviceAccounts": [ + { + "email": "abcmail@some-project.iam.gserviceaccount.com", + "scopes": [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/iam" + ] + } + ] + }, + "requestMetadata": ..., + "resourceLocation": ..., + "resourceName": "projects/some-project/zones/us-central1-f/instances/abc", + "response": { + "@type": "type.googleapis.com/error", + "error": { + "code": 404, + "errors": [ + { + "domain": "global", + "message": "The resource 'abc' was not found", + "reason": "notFound" + } + ], + "message": "The resource 'abc' was not found" + } + }, + "serviceName": "compute.googleapis.com", + "status": { + "code": 5, + "message": "The resource 'abc' was not found" + } + }, + "receiveTimestamp": "2024-01-30 11:03:56.719662927", + "resource": { + "labels": { + "instance_id": "", + "project_id": "some-project", + "zone": "us-central1-f" + }, + "type": "gce_instance" + }, + "severity": "ERROR", + "timestamp": "2024-01-30 11:03:55.700872000" + } + - Name: GCP compute.instances - Not All Permissions + ExpectedResult: false + Log: + { + "protoPayload": { + "at_sign_type": "type.googleapis.com/google.cloud.audit.AuditLog", + "authenticationInfo": { + "principalEmail": "some.user@company.com", + "principalSubject": "user:some.user@company.com" + }, + "authorizationInfo": [ + { + "granted": true, + "permission": "compute.instances.create", + "resource": "projects/some-project/zones/us-central1-f/instances/abc", + "resourceAttributes": { + "name": "projects/some-project/zones/us-central1-f/instances/abc", + "service": "compute", + "type": "compute.instances" + } + }, + { + "granted": true, + "permission": "compute.disks.create", + "resource": "projects/some-project/zones/us-central1-f/disks/abc", + "resourceAttributes": { + "name": "projects/some-project/zones/us-central1-f/disks/abc", + "service": "compute", + "type": "compute.disks" + } + }, + { + "granted": true, + "permission": "compute.subnetworks.use", + "resource": "projects/some-project/regions/us-central1/subnetworks/default", + "resourceAttributes": { + "name": "projects/some-project/regions/us-central1/subnetworks/default", + "service": "compute", + "type": "compute.subnetworks" + } + }, + { + "granted": true, + "permission": "compute.subnetworks.useExternalIp", + "resource": "projects/some-project/regions/us-central1/subnetworks/default", + "resourceAttributes": { + "name": "projects/some-project/regions/us-central1/subnetworks/default", + "service": "compute", + "type": "compute.subnetworks" + } + }, + { + "granted": true, + "permission": "compute.instances.setMetadata", + "resource": "projects/some-project/zones/us-central1-f/instances/abc", + "resourceAttributes": { + "name": "projects/some-project/zones/us-central1-f/instances/abc", + "service": "compute", + "type": "compute.instances" + } + }, + ], + "methodName": "v1.compute.instances.insert", + "request": ..., + "requestMetadata": ..., + "resourceLocation": ..., + "resourceName": ..., + "response": ..., + "serviceName": ... + }, + "receiveTimestamp": ..., + "resource": ... + } From 5b622ef1e0461577ef405cecd11a4948f36e5340 Mon Sep 17 00:00:00 2001 From: Evan Gibler Date: Tue, 13 Feb 2024 11:59:01 -0600 Subject: [PATCH 03/11] [sync] Add GCP.Storage.Hmac.Keys.Create detection rule (#64) (#1101) Co-authored-by: Oleh Melenevskyi <767472+melenevskyi@users.noreply.github.com> --- packs/gcp_audit.yml | 1 + .../gcp_storage_hmac_keys_create.yml | 57 +++++++++++++++++++ 2 files changed, 58 insertions(+) create mode 100644 rules/gcp_audit_rules/gcp_storage_hmac_keys_create.yml diff --git a/packs/gcp_audit.yml b/packs/gcp_audit.yml index bbd68c422..9d67600e7 100644 --- a/packs/gcp_audit.yml +++ b/packs/gcp_audit.yml @@ -36,6 +36,7 @@ PackDefinition: - GCP.VPC.Flow.Logs.Disabled - GCP.Workforce.Pool.Created.or.Updated - GCP.Workload.Identity.Pool.Created.or.Updated + - GCP.Storage.Hmac.Keys.Create # Data model - Standard.GCP.AuditLog # Globals used in these rules/policies diff --git a/rules/gcp_audit_rules/gcp_storage_hmac_keys_create.yml b/rules/gcp_audit_rules/gcp_storage_hmac_keys_create.yml new file mode 100644 index 000000000..e2da538a9 --- /dev/null +++ b/rules/gcp_audit_rules/gcp_storage_hmac_keys_create.yml @@ -0,0 +1,57 @@ +AnalysisType: rule +RuleID: "GCP.Storage.Hmac.Keys.Create" +DisplayName: "GCP storage hmac keys create" +Description: "There is a feature of Cloud Storage, “interoperability”, that provides a way for Cloud Storage to interact with storage offerings from other cloud providers, like AWS S3. As part of that, there are HMAC keys that can be created for both Service Accounts and regular users. We can escalate Cloud Storage permissions by creating an HMAC key for a higher-privileged Service Account." +Enabled: true +LogTypes: + - GCP.AuditLog +Severity: High +DedupPeriodMinutes: 60 +Threshold: 1 +Reference: https://rhinosecuritylabs.com/cloud-security/privilege-escalation-google-cloud-platform-part-2/ +Reports: + MITRE ATT&CK: + - TA0004:T1548 +Detection: + - All: + - KeyPath: protoPayload.authorizationInfo[*].granted + Condition: Contains + Value: true + - KeyPath: protoPayload.authorizationInfo[*].permission + Condition: Contains + Value: storage.hmacKeys.create +Tests: + - Name: privilege-escalation + ExpectedResult: true + Log: + protoPayload: + authorizationInfo: + - granted: true + permission: storage.hmacKeys.create + methodName: v2.deploymentmanager.deployments.insert + serviceName: deploymentmanager.googleapis.com + receiveTimestamp: "2024-01-19 13:47:19.465856238" + resource: + labels: + name: test-vm-deployment + project_id: panther-threat-research + type: deployment + severity: NOTICE + timestamp: "2024-01-19 13:47:18.279921000" + - Name: fail + ExpectedResult: false + Log: + protoPayload: + authorizationInfo: + - granted: false + permission: storage.hmacKeys.create + methodName: v2.deploymentmanager.deployments.insert + serviceName: deploymentmanager.googleapis.com + receiveTimestamp: "2024-01-19 13:47:19.465856238" + resource: + labels: + name: test-vm-deployment + project_id: panther-threat-research + type: deployment + severity: NOTICE + timestamp: "2024-01-19 13:47:18.279921000" From 56df42bca61b0ad92fab936297d8bf3cc98f17d7 Mon Sep 17 00:00:00 2001 From: Evan Gibler Date: Tue, 13 Feb 2024 12:27:00 -0600 Subject: [PATCH 04/11] [sync] Add GCP.Kubernetes.New.Daemonset.Deployed rule (#76) (#1102) Co-authored-by: Oleh Melenevskyi <767472+melenevskyi@users.noreply.github.com> --- packs/gcp_audit.yml | 1 + .../gcp_kubernetes_new_daemonset_deployed.yml | 54 +++++++++++++++++++ 2 files changed, 55 insertions(+) create mode 100644 rules/gcp_k8s_rules/gcp_kubernetes_new_daemonset_deployed.yml diff --git a/packs/gcp_audit.yml b/packs/gcp_audit.yml index 9d67600e7..0a689a423 100644 --- a/packs/gcp_audit.yml +++ b/packs/gcp_audit.yml @@ -37,6 +37,7 @@ PackDefinition: - GCP.Workforce.Pool.Created.or.Updated - GCP.Workload.Identity.Pool.Created.or.Updated - GCP.Storage.Hmac.Keys.Create + - GCP.K8s.New.Daemonset.Deployed # Data model - Standard.GCP.AuditLog # Globals used in these rules/policies diff --git a/rules/gcp_k8s_rules/gcp_kubernetes_new_daemonset_deployed.yml b/rules/gcp_k8s_rules/gcp_kubernetes_new_daemonset_deployed.yml new file mode 100644 index 000000000..96155e9a6 --- /dev/null +++ b/rules/gcp_k8s_rules/gcp_kubernetes_new_daemonset_deployed.yml @@ -0,0 +1,54 @@ +AnalysisType: rule +RuleID: "GCP.K8s.New.Daemonset.Deployed" +DisplayName: "GCP K8s New Daemonset Deployed" +Description: "Detects Daemonset creation in GCP Kubernetes clusters." +Enabled: true +LogTypes: + - GCP.AuditLog +Severity: Medium +DedupPeriodMinutes: 60 +Threshold: 1 +Reference: https://medium.com/snowflake/from-logs-to-detection-using-snowflake-and-panther-to-detect-k8s-threats-d72f70a504d7 +Detection: + - All: + - KeyPath: protoPayload.authorizationInfo[*].granted + Condition: Contains + Value: true + - KeyPath: protoPayload.authorizationInfo[*].permission + Condition: Contains + Value: io.k8s.apps.v1.daemonsets.create +Tests: + - Name: privilege-escalation + ExpectedResult: true + Log: + protoPayload: + authorizationInfo: + - granted: true + permission: io.k8s.apps.v1.daemonsets.create + methodName: v2.deploymentmanager.deployments.insert + serviceName: deploymentmanager.googleapis.com + receiveTimestamp: "2024-01-19 13:47:19.465856238" + resource: + labels: + name: test-vm-deployment + project_id: panther-threat-research + type: deployment + severity: NOTICE + timestamp: "2024-01-19 13:47:18.279921000" + - Name: fail + ExpectedResult: false + Log: + protoPayload: + authorizationInfo: + - granted: false + permission: io.k8s.apps.v1.daemonsets.create + methodName: v2.deploymentmanager.deployments.insert + serviceName: deploymentmanager.googleapis.com + receiveTimestamp: "2024-01-19 13:47:19.465856238" + resource: + labels: + name: test-vm-deployment + project_id: panther-threat-research + type: deployment + severity: NOTICE + timestamp: "2024-01-19 13:47:18.279921000" From e60b7c75bc6864a879f27a9686c776be62a02ef1 Mon Sep 17 00:00:00 2001 From: Evan Gibler Date: Tue, 13 Feb 2024 12:30:36 -0600 Subject: [PATCH 05/11] [sync] GitHub Data Model Admin Actions update (#79) (#1104) * action = 'team.add_repository' and perm = 'admin' * fmt --------- Co-authored-by: Ariel Ropek <79653153+arielkr256@users.noreply.github.com> --- data_models/github_data_model.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/data_models/github_data_model.py b/data_models/github_data_model.py index b6f337089..5ab24efb8 100644 --- a/data_models/github_data_model.py +++ b/data_models/github_data_model.py @@ -6,14 +6,25 @@ "team.promote_maintainer", } +CONDITIONAL_ADMIN_EVENTS = { + "team.add_repository", +} + def get_admin_role(event): action = event.get("action", "") + permission = event.get("permission", "") + if action in CONDITIONAL_ADMIN_EVENTS and permission == "admin": + return action return action if action in ADMIN_EVENTS else "" def get_event_type(event): - if event.get("action", "") in ADMIN_EVENTS: + action = event.get("action", "") + permission = event.get("permission", "") + if action in ADMIN_EVENTS: + return event_type.ADMIN_ROLE_ASSIGNED + if action in CONDITIONAL_ADMIN_EVENTS and permission == "admin": return event_type.ADMIN_ROLE_ASSIGNED if event.get("action", "") == "org.disable_two_factor_requirement": return event_type.MFA_DISABLED From c28793bba742b8e5e37e5bb44d9892c598bf3707 Mon Sep 17 00:00:00 2001 From: Evan Gibler Date: Tue, 13 Feb 2024 12:33:40 -0600 Subject: [PATCH 06/11] [sync] Add GCP.K8s.IOC.Activity rule (#80) (#1105) * Add GCP.K8s.IOC.Activity rule * Update rules/gcp_k8s_rules/gcp_k8s_ioc_activity.yml --------- Co-authored-by: Oleh Melenevskyi <767472+melenevskyi@users.noreply.github.com> --- lookup_tables/tor/tor_exit_nodes.yml | 1 + rules/gcp_k8s_rules/gcp_k8s_ioc_activity.yml | 44 ++++++++++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 rules/gcp_k8s_rules/gcp_k8s_ioc_activity.yml diff --git a/lookup_tables/tor/tor_exit_nodes.yml b/lookup_tables/tor/tor_exit_nodes.yml index 672fd65f3..705b7f5e2 100644 --- a/lookup_tables/tor/tor_exit_nodes.yml +++ b/lookup_tables/tor/tor_exit_nodes.yml @@ -211,6 +211,7 @@ LogTypeMap: - "$.protoPayload.requestMetadata.callerIP" - "$.httpRequest.remoteIP" - "$.httpRequest.serverIP" + - "$.requestMetadata.callerIP" - LogType: GCP.HTTPLoadBalancer Selectors: - "$.jsonPayload.removeIp" diff --git a/rules/gcp_k8s_rules/gcp_k8s_ioc_activity.yml b/rules/gcp_k8s_rules/gcp_k8s_ioc_activity.yml new file mode 100644 index 000000000..e89cccfed --- /dev/null +++ b/rules/gcp_k8s_rules/gcp_k8s_ioc_activity.yml @@ -0,0 +1,44 @@ +AnalysisType: rule +RuleID: "GCP.K8s.IOC.Activity" +DisplayName: "GCP K8s IOCActivity" +Enabled: true +LogTypes: + - GCP.AuditLog +Tags: + - GCP + - Optional +Severity: Medium +Description: This detection monitors for any kuberentes API Request originating from an Indicator of Compromise. +Detection: + - All: + - KeyPath: operation.producer + Condition: Equals + Value: k8s.io + - KeyPath: p_enrichment.tor_exit_nodes + Condition: IsNotNullOrEmpty +Reference: https://medium.com/snowflake/from-logs-to-detection-using-snowflake-and-panther-to-detect-k8s-threats-d72f70a504d7 +Tests: + - + Name: triggers + ExpectedResult: true + Log: + { + "operation": {"producer":"k8s.io"}, + "p_enrichment": { + "tor_exit_nodes": [ + "1.1.1.1" + ] + } + } + - + Name: ignore + ExpectedResult: false + Log: + { + "operation": {"producer":"chrome"}, + "p_enrichment": { + "tor_exit_nodes": [ + "1.1.1.1" + ] + } + } From 3f5e90df4327cbe0eb6a1207cb491fef0319e28f Mon Sep 17 00:00:00 2001 From: Evan Gibler Date: Tue, 13 Feb 2024 12:37:15 -0600 Subject: [PATCH 07/11] [sync] GCP K8S Privileged Pod Created - rule (#81) (#1106) Co-authored-by: akozlovets098 <95437895+akozlovets098@users.noreply.github.com> --- .../gcp_k8s_privileged_pod_created.py | 40 ++ .../gcp_k8s_privileged_pod_created.yml | 344 ++++++++++++++++++ 2 files changed, 384 insertions(+) create mode 100644 rules/gcp_k8s_rules/gcp_k8s_privileged_pod_created.py create mode 100644 rules/gcp_k8s_rules/gcp_k8s_privileged_pod_created.yml diff --git a/rules/gcp_k8s_rules/gcp_k8s_privileged_pod_created.py b/rules/gcp_k8s_rules/gcp_k8s_privileged_pod_created.py new file mode 100644 index 000000000..283ca7b42 --- /dev/null +++ b/rules/gcp_k8s_rules/gcp_k8s_privileged_pod_created.py @@ -0,0 +1,40 @@ +from gcp_base_helpers import gcp_alert_context +from panther_base_helpers import deep_get, deep_walk + + +def rule(event): + if deep_get(event, "protoPayload", "response", "status") == "Failure": + return False + + if deep_get(event, "protoPayload", "methodName") != "io.k8s.core.v1.pods.create": + return False + + authorization_info = deep_walk(event, "protoPayload", "authorizationInfo") + containers_info = deep_walk(event, "protoPayload", "response", "spec", "containers") + for auth in authorization_info: + if auth.get("permission") == "io.k8s.core.v1.pods.create" and auth.get("granted") is True: + for security_context in containers_info: + if ( + deep_get(security_context, "securityContext", "privileged") is True + or deep_get(security_context, "securityContext", "runAsNonRoot") is False + ): + return True + + return False + + +def title(event): + actor = deep_get( + event, "protoPayload", "authenticationInfo", "principalEmail", default="" + ) + pod_name = deep_get(event, "protoPayload", "resourceName", default="") + project_id = deep_get(event, "resource", "labels", "project_id", default="") + + return f"[GCP]: [{actor}] created a privileged pod [{pod_name}] in project [{project_id}]" + + +def alert_context(event): + context = gcp_alert_context(event) + containers_info = deep_walk(event, "protoPayload", "response", "spec", "containers") + context["pod_security_context"] = [i.get("securityContext") for i in containers_info] + return context diff --git a/rules/gcp_k8s_rules/gcp_k8s_privileged_pod_created.yml b/rules/gcp_k8s_rules/gcp_k8s_privileged_pod_created.yml new file mode 100644 index 000000000..9d85349a6 --- /dev/null +++ b/rules/gcp_k8s_rules/gcp_k8s_privileged_pod_created.yml @@ -0,0 +1,344 @@ +AnalysisType: rule +RuleID: "GCP.K8S.Privileged.Pod.Created" +DisplayName: "GCP K8S Privileged Pod Created" +Enabled: true +LogTypes: + - GCP.AuditLog +Severity: High +Filename: gcp_k8s_privileged_pod_created.py +Description: > + Alerts when a user creates privileged pod. These particular pods have full access to the host’s namespace and + devices, have the ability to exploit the kernel, have dangerous linux capabilities, and can be a powerful launching + point for further attacks. In the event of a successful container escape where a user is operating with root + privileges, the attacker retains this role on the node. +Runbook: > + Investigate the reason of creating privileged pod. Advise that it is discouraged practice. + Create ticket if appropriate. +Reference: https://www.golinuxcloud.com/kubernetes-privileged-pod-examples/ +Reports: + MITRE ATT&CK: + - TA0004:T1548 # Abuse Elevation Control Mechanism +Tests: + - + Name: Privileged Pod Created + ExpectedResult: true + Log: + { + "logName": "projects/some-project/logs/cloudaudit.googleapis.com%2Factivity", + "operation": {}, + "protoPayload": { + "at_sign_type": "type.googleapis.com/google.cloud.audit.AuditLog", + "authenticationInfo": { + "principalEmail": "john.doe@company.com" + }, + "authorizationInfo": [ + { + "granted": true, + "permission": "io.k8s.core.v1.pods.create", + "resource": "core/v1/namespaces/default/pods/test-privileged-pod" + } + ], + "methodName": "io.k8s.core.v1.pods.create", + "request": { + "@type": "core.k8s.io/v1.Pod", + "apiVersion": "v1", + "kind": "Pod", + "metadata": { + "name": "test-privileged-pod", + "namespace": "default" + }, + "spec": { + "containers": [ + { + "image": "nginx", + "imagePullPolicy": "Always", + "name": "nginx", + "resources": { }, + "securityContext": { + "privileged": true + }, + } + ], + "securityContext": { }, + }, + "status": { } + }, + "requestMetadata": { + "callerIP": "1.2.3.4", + }, + "resourceName": "core/v1/namespaces/default/pods/test-privileged-pod", + "response": { + "@type": "core.k8s.io/v1.Pod", + "apiVersion": "v1", + "kind": "Pod", + "metadata": {}, + "spec": { + "containers": [ + { + "image": "nginx", + "imagePullPolicy": "Always", + "name": "nginx", + "resources": { }, + "securityContext": { + "privileged": true + }, + } + ], + "securityContext": { }, + "serviceAccount": "default", + "serviceAccountName": "default", + "terminationGracePeriodSeconds": 30, + }, + "status": {} + }, + "serviceName": "k8s.io", + "status": {} + }, + "receiveTimestamp": "2024-02-13 12:45:20.058795785", + "resource": { + "labels": { + "cluster_name": "some-project-cluster", + "location": "us-west1", + "project_id": "some-project" + }, + "type": "k8s_cluster" + }, + "timestamp": "2024-02-13 12:45:06.073905000" + } + - + Name: Run-As-Root Pod Created + ExpectedResult: true + Log: + { + "logName": "projects/some-project/logs/cloudaudit.googleapis.com%2Factivity", + "operation": {}, + "protoPayload": { + "at_sign_type": "type.googleapis.com/google.cloud.audit.AuditLog", + "authenticationInfo": { + "principalEmail": "john.doe@company.com" + }, + "authorizationInfo": [ + { + "granted": true, + "permission": "io.k8s.core.v1.pods.create", + "resource": "core/v1/namespaces/default/pods/test-runasroot-pod" + } + ], + "methodName": "io.k8s.core.v1.pods.create", + "request": { + "@type": "core.k8s.io/v1.Pod", + "apiVersion": "v1", + "kind": "Pod", + "metadata": {}, + "spec": { + "containers": [ + { + "image": "nginx", + "imagePullPolicy": "Always", + "name": "nginx", + "resources": { }, + "securityContext": { + "runAsNonRoot": false + }, + } + ], + }, + "status": { } + }, + "requestMetadata": { + "callerIP": "1.2.3.4", + }, + "resourceName": "core/v1/namespaces/default/pods/test-runasroot-pod", + "response": { + "@type": "core.k8s.io/v1.Pod", + "apiVersion": "v1", + "kind": "Pod", + "metadata": {}, + "spec": { + "containers": [ + { + "image": "nginx", + "imagePullPolicy": "Always", + "name": "nginx", + "resources": { }, + "securityContext": { + "runAsNonRoot": false + }, + } + ], + }, + "status": { + "phase": "Pending", + "qosClass": "BestEffort" + } + }, + "serviceName": "k8s.io", + "status": { } + }, + "receiveTimestamp": "2024-02-13 13:13:53.113465457", + "resource": { + "labels": { + "cluster_name": "some-project-cluster", + "location": "us-west1", + "project_id": "some-project" + }, + "type": "k8s_cluster" + }, + "timestamp": "2024-02-13 13:13:45.363388000" + } + - + Name: Non-Privileged Pod Created + ExpectedResult: false + Log: + { + "logName": "projects/some-project/logs/cloudaudit.googleapis.com%2Factivity", + "operation": { + "first": true, + "id": "7f8c5bec-01ff-4079-97e3-065ac34e10e8", + "last": true, + "producer": "k8s.io" + }, + "protoPayload": { + "at_sign_type": "type.googleapis.com/google.cloud.audit.AuditLog", + "authenticationInfo": { + "principalEmail": "john.doe@company.com" + }, + "authorizationInfo": [ + { + "granted": true, + "permission": "io.k8s.core.v1.pods.create", + "resource": "core/v1/namespaces/default/pods/test-non-privileged-pod" + } + ], + "methodName": "io.k8s.core.v1.pods.create", + "request": { + "@type": "core.k8s.io/v1.Pod", + "apiVersion": "v1", + "kind": "Pod", + "metadata": { + "name": "test-non-privileged-pod", + "namespace": "default" + }, + "spec": { + "containers": [ + { + "image": "nginx", + "imagePullPolicy": "Always", + "name": "nginx", + "resources": { }, + } + ], + }, + "status": { } + }, + "requestMetadata": { + "callerIP": "1.2.3.4", + }, + "resourceName": "core/v1/namespaces/default/pods/test-non-privileged-pod", + "response": { + "@type": "core.k8s.io/v1.Pod", + "apiVersion": "v1", + "kind": "Pod", + "metadata": {}, + "spec": { + "containers": [ + { + "image": "nginx", + "imagePullPolicy": "Always", + "name": "nginx", + "resources": { }, + } + ], + }, + "status": {} + }, + "serviceName": "k8s.io", + "status": { } + }, + "receiveTimestamp": "2024-02-13 13:07:54.642331675", + "resource": { + "labels": { + "cluster_name": "some-project-cluster", + "location": "us-west1", + "project_id": "some-project" + }, + "type": "k8s_cluster" + }, + "timestamp": "2024-02-13 13:07:29.505948000" + } + - Name: Error Creating Pod + ExpectedResult: false + Log: + { + "logName": "projects/some-project/logs/cloudaudit.googleapis.com%2Factivity", + "protoPayload": { + "at_sign_type": "type.googleapis.com/google.cloud.audit.AuditLog", + "authenticationInfo": { + "principalEmail": "john.doe@company.com" + }, + "authorizationInfo": [ + { + "granted": true, + "permission": "io.k8s.core.v1.pods.create", + "resource": "core/v1/namespaces/default/pods/test-privileged-pod" + } + ], + "methodName": "io.k8s.core.v1.pods.create", + "request": { + "@type": "core.k8s.io/v1.Pod", + "apiVersion": "v1", + "kind": "Pod", + "metadata": { + "name": "test-privileged-pod", + "namespace": "default" + }, + "spec": { + "containers": [ + { + "image": "nginx", + "imagePullPolicy": "Always", + "name": "nginx", + "resources": { }, + "securityContext": { + "runAsNonRoot": false + }, + } + ], + }, + "status": { } + }, + "requestMetadata": { + "callerIP": "1.2.3.4", + }, + "resourceName": "core/v1/namespaces/default/pods/test-privileged-pod", + "response": { + "@type": "core.k8s.io/v1.Status", + "apiVersion": "v1", + "code": 409, + "details": { + "kind": "pods", + "name": "test-privileged-pod" + }, + "kind": "Status", + "message": "pods \"test-privileged-pod\" already exists", + "metadata": { }, + "reason": "AlreadyExists", + "status": "Failure" + }, + "serviceName": "k8s.io", + "status": { + "code": 10, + "message": "pods \"test-privileged-pod\" already exists" + } + }, + "receiveTimestamp": "2024-02-13 13:13:33.486605432", + "resource": { + "labels": { + "cluster_name": "some-project-cluster", + "location": "us-west1", + "project_id": "some-project" + }, + "type": "k8s_cluster" + }, + "timestamp": "2024-02-13 13:13:24.079140000" + } From 38b47076a1364cf608c53e222b81a90684e01b7c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 13 Feb 2024 18:40:45 +0000 Subject: [PATCH 08/11] build(deps): bump aws-actions/configure-aws-credentials from 4.0.1 to 4.0.2 (#1099) Bumps [aws-actions/configure-aws-credentials](https://github.com/aws-actions/configure-aws-credentials) from 4.0.1 to 4.0.2. - [Release notes](https://github.com/aws-actions/configure-aws-credentials/releases) - [Changelog](https://github.com/aws-actions/configure-aws-credentials/blob/main/CHANGELOG.md) - [Commits](https://github.com/aws-actions/configure-aws-credentials/compare/010d0da01d0b5a38af31e9c3470dbfdabdecca3a...e3dd6a429d7300a6a4c196c26e071d42e0343502) --- updated-dependencies: - dependency-name: aws-actions/configure-aws-credentials dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Evan Gibler --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 2078e8513..1a7f8ddf9 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -17,7 +17,7 @@ jobs: fetch-depth: 0 token: ${{ env.GITHUB_TOKEN }} - name: Configure AWS credentials - uses: aws-actions/configure-aws-credentials@010d0da01d0b5a38af31e9c3470dbfdabdecca3a # v4.0.1 + uses: aws-actions/configure-aws-credentials@e3dd6a429d7300a6a4c196c26e071d42e0343502 # v4.0.2 with: role-to-assume: ${{ secrets.AWS_ROLE }} aws-region: ${{ secrets.AWS_REGION }} From bdc9e8681779b52b21a97bcdf1980bbe1de2106f Mon Sep 17 00:00:00 2001 From: Sam Kottler Date: Tue, 13 Feb 2024 13:53:25 -0500 Subject: [PATCH 09/11] standard_rules/impossible_travel_login: set IS_PRIVATE_RELAY to true only when private relay is in use (#1098) Co-authored-by: Evan Gibler --- rules/standard_rules/impossible_travel_login.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rules/standard_rules/impossible_travel_login.py b/rules/standard_rules/impossible_travel_login.py index 9d718c741..8e4db4450 100644 --- a/rules/standard_rules/impossible_travel_login.py +++ b/rules/standard_rules/impossible_travel_login.py @@ -72,7 +72,7 @@ def rule(event): IS_PRIVATE_RELAY = all( [ deep_get(ipinfo_privacy, "relay", default=False), - deep_get(ipinfo_privacy, "service", default="") != "", + deep_get(ipinfo_privacy, "service", default="") == "Apple Private Relay", ] ) # We've found that some places, like WeWork locations, From ae19c5074f6df39baea1ca7fe59183474a321569 Mon Sep 17 00:00:00 2001 From: Evan Gibler Date: Tue, 13 Feb 2024 13:21:33 -0600 Subject: [PATCH 10/11] [sync] added config tags and enabled rules w/o config (#75) (#1107) Co-authored-by: Ariel Ropek <79653153+arielkr256@users.noreply.github.com> --- packs/auth0.yml | 1 + packs/aws.yml | 2 ++ packs/carbonblack.yml | 1 + packs/cloudflare.yml | 2 ++ .../aws_cloudtrail_unsuccessful_mfa_attempt.yml | 2 ++ rules/aws_cloudtrail_rules/aws_console_root_login.yml | 2 +- rules/aws_cloudtrail_rules/aws_lambda_crud.yml | 1 + rules/aws_cloudtrail_rules/aws_rds_manual_snapshot_created.yml | 2 +- rules/aws_cloudtrail_rules/aws_software_discovery.yml | 2 ++ rules/aws_cloudtrail_rules/aws_unused_region.yml | 1 + rules/carbonblack_rules/cb_passthrough.yml | 2 +- rules/gcp_audit_rules/gcp_iam_admin_role_assigned.yml | 2 ++ .../gsuite_activityevent_rules/gsuite_permissions_delegated.yml | 2 ++ rules/netskope_rules/netskope_many_deletes.yml | 2 +- rules/netskope_rules/netskope_unauthorized_api_calls.yml | 2 +- rules/notion_rules/notion_login_from_blocked_ip.yml | 1 + rules/okta_rules/okta_idp_signin.yaml | 2 ++ 17 files changed, 24 insertions(+), 5 deletions(-) diff --git a/packs/auth0.yml b/packs/auth0.yml index 820572892..5ffb82d9d 100644 --- a/packs/auth0.yml +++ b/packs/auth0.yml @@ -5,6 +5,7 @@ PackDefinition: IDs: - Auth0.Custom.Role.Created - Auth0.Integration.Installed + - Auth0.MFA.Factor.Setting.Enabled - Auth0.MFA.Policy.Disabled - Auth0.MFA.Policy.Enabled - Auth0.MFA.Risk.Assessment.Disabled diff --git a/packs/aws.yml b/packs/aws.yml index 4731a9f09..240f46368 100644 --- a/packs/aws.yml +++ b/packs/aws.yml @@ -49,6 +49,7 @@ PackDefinition: # Root Activity - AWS.CloudTrail.RootAccessKeyCreated - AWS.CloudTrail.RootPasswordChanged + - AWS.Console.RootLogin - AWS.Console.RootLoginFailed - AWS.EC2.Instance.DetailedMonitoring - AWS.Root.Activity @@ -110,6 +111,7 @@ PackDefinition: - AWS.GuardDuty.MediumSeverityFinding - AWS.IAM.Policy.AdministrativePrivileges - AWS.RDS.InstanceHighAvailability + - AWS.RDS.ManualSnapshotCreated - AWS.RDS.MasterPasswordUpdated - AWS.RDS.PublicRestore - AWS.RDS.SnapshotShared diff --git a/packs/carbonblack.yml b/packs/carbonblack.yml index dbdba1d36..7a815c6ad 100644 --- a/packs/carbonblack.yml +++ b/packs/carbonblack.yml @@ -3,6 +3,7 @@ PackID: PantherManaged.CarbonBlack Description: Group of all Carbon Black detections PackDefinition: IDs: + - CarbonBlack.AlertV2.Passthrough - CarbonBlack.Audit.Admin.Grant - CarbonBlack.Audit.API.Key.Created.Retrieved - CarbonBlack.Audit.Data.Forwarder.Stopped diff --git a/packs/cloudflare.yml b/packs/cloudflare.yml index 003d30f21..332d00808 100644 --- a/packs/cloudflare.yml +++ b/packs/cloudflare.yml @@ -6,6 +6,8 @@ PackDefinition: IDs: - Cloudflare.Firewall.L7DDoS - Cloudflare.Firewall.SuspiciousEventGreyNoise + - Cloudflare.HttpRequest.BotHighVolume + - Cloudflare.HttpRequest.BotHighVolumeGreyNoise # Globals used in these rules/policies - panther_base_helpers - panther_cloudflare_helpers diff --git a/rules/aws_cloudtrail_rules/aws_cloudtrail_unsuccessful_mfa_attempt.yml b/rules/aws_cloudtrail_rules/aws_cloudtrail_unsuccessful_mfa_attempt.yml index 138703915..a7f7004e1 100644 --- a/rules/aws_cloudtrail_rules/aws_cloudtrail_unsuccessful_mfa_attempt.yml +++ b/rules/aws_cloudtrail_rules/aws_cloudtrail_unsuccessful_mfa_attempt.yml @@ -4,6 +4,8 @@ DisplayName: "AWS Unsuccessful MFA attempt" Enabled: false Filename: aws_cloudtrail_unsuccessful_mfa_attempt.py Reference: https://attack.mitre.org/techniques/T1621/ +Tags: + - Configuration Required # configure threshold for multiple MFA failures Reports: MITRE ATT&CK: - TA0006:T1621 diff --git a/rules/aws_cloudtrail_rules/aws_console_root_login.yml b/rules/aws_cloudtrail_rules/aws_console_root_login.yml index e5096871f..1fef21db3 100644 --- a/rules/aws_cloudtrail_rules/aws_console_root_login.yml +++ b/rules/aws_cloudtrail_rules/aws_console_root_login.yml @@ -2,7 +2,7 @@ AnalysisType: rule Filename: aws_console_root_login.py RuleID: "AWS.Console.RootLogin" DisplayName: "Root Console Login" -Enabled: false +Enabled: true DedupPeriodMinutes: 15 LogTypes: - AWS.CloudTrail diff --git a/rules/aws_cloudtrail_rules/aws_lambda_crud.yml b/rules/aws_cloudtrail_rules/aws_lambda_crud.yml index 8ca1cb70c..879053ce1 100644 --- a/rules/aws_cloudtrail_rules/aws_lambda_crud.yml +++ b/rules/aws_cloudtrail_rules/aws_lambda_crud.yml @@ -8,6 +8,7 @@ LogTypes: Tags: - AWS - Security Control + - Configuration Required Reports: CIS: - 3.12 diff --git a/rules/aws_cloudtrail_rules/aws_rds_manual_snapshot_created.yml b/rules/aws_cloudtrail_rules/aws_rds_manual_snapshot_created.yml index 54fb358aa..8fc26baff 100644 --- a/rules/aws_cloudtrail_rules/aws_rds_manual_snapshot_created.yml +++ b/rules/aws_cloudtrail_rules/aws_rds_manual_snapshot_created.yml @@ -2,7 +2,7 @@ AnalysisType: rule Filename: aws_rds_manual_snapshot_created.py RuleID: "AWS.RDS.ManualSnapshotCreated" DisplayName: "AWS RDS Manual/Public Snapshot Created" -Enabled: false +Enabled: true LogTypes: - AWS.CloudTrail Tags: diff --git a/rules/aws_cloudtrail_rules/aws_software_discovery.yml b/rules/aws_cloudtrail_rules/aws_software_discovery.yml index a2493852f..199471ef4 100644 --- a/rules/aws_cloudtrail_rules/aws_software_discovery.yml +++ b/rules/aws_cloudtrail_rules/aws_software_discovery.yml @@ -4,6 +4,8 @@ DisplayName: "AWS Software Discovery" Enabled: false Filename: aws_software_discovery.py Reference: https://attack.mitre.org/techniques/T1518/001/ +Tags: + - Configuration Required Reports: MITRE ATT&CK: - TA0007:T1518 diff --git a/rules/aws_cloudtrail_rules/aws_unused_region.yml b/rules/aws_cloudtrail_rules/aws_unused_region.yml index e3b0d873f..a38b3b996 100644 --- a/rules/aws_cloudtrail_rules/aws_unused_region.yml +++ b/rules/aws_cloudtrail_rules/aws_unused_region.yml @@ -8,6 +8,7 @@ LogTypes: Tags: - AWS - Defense Evasion:Unused/Unsupported Cloud Regions + - Configuration Required Reports: MITRE ATT&CK: - TA0005:T1535 diff --git a/rules/carbonblack_rules/cb_passthrough.yml b/rules/carbonblack_rules/cb_passthrough.yml index ec1a28024..67e239668 100644 --- a/rules/carbonblack_rules/cb_passthrough.yml +++ b/rules/carbonblack_rules/cb_passthrough.yml @@ -4,7 +4,7 @@ Description: This rule enriches and contextualizes security alerts generated by DisplayName: Carbon Black Passthrough Rule Runbook: Review the Carbon Black alert details to determine what malicious behavior was detected, and whether or not it was blocked. Use the Reference link to view the alert in the Carbon Black console and take remediating actions if necessary. Reference: https://docs.vmware.com/en/VMware-Carbon-Black-Cloud/services/carbon-black-cloud-user-guide/GUID-0B68199D-6411-45D1-AE0D-2AB9B7A28513.html -Enabled: false +Enabled: true Filename: cb_passthrough.py LogTypes: - CarbonBlack.AlertV2 diff --git a/rules/gcp_audit_rules/gcp_iam_admin_role_assigned.yml b/rules/gcp_audit_rules/gcp_iam_admin_role_assigned.yml index 7cfcb7e17..84c0020fa 100644 --- a/rules/gcp_audit_rules/gcp_iam_admin_role_assigned.yml +++ b/rules/gcp_audit_rules/gcp_iam_admin_role_assigned.yml @@ -9,6 +9,8 @@ Tags: - GCP - Identity & Access Management - Privilege Escalation:Valid Accounts + - Configuration Required + - Deprecated Reports: MITRE ATT&CK: - TA0004:T1078 diff --git a/rules/gsuite_activityevent_rules/gsuite_permissions_delegated.yml b/rules/gsuite_activityevent_rules/gsuite_permissions_delegated.yml index 22337695e..3738d16da 100644 --- a/rules/gsuite_activityevent_rules/gsuite_permissions_delegated.yml +++ b/rules/gsuite_activityevent_rules/gsuite_permissions_delegated.yml @@ -7,6 +7,8 @@ LogTypes: - GSuite.ActivityEvent Tags: - GSuite + - Configuration Required + - Deprecated Severity: Low Description: > A GSuite user was granted new administrator privileges. diff --git a/rules/netskope_rules/netskope_many_deletes.yml b/rules/netskope_rules/netskope_many_deletes.yml index c89c54fe6..93dc7abdf 100644 --- a/rules/netskope_rules/netskope_many_deletes.yml +++ b/rules/netskope_rules/netskope_many_deletes.yml @@ -12,7 +12,7 @@ LogTypes: - Netskope.Audit Tags: - Netskope - - Configuration Required + - Configuration Required # configure threshold for your environment - Data Destruction Reports: MITRE ATT&CK: diff --git a/rules/netskope_rules/netskope_unauthorized_api_calls.yml b/rules/netskope_rules/netskope_unauthorized_api_calls.yml index 74758ed4f..1a1896f6b 100644 --- a/rules/netskope_rules/netskope_unauthorized_api_calls.yml +++ b/rules/netskope_rules/netskope_unauthorized_api_calls.yml @@ -12,7 +12,7 @@ LogTypes: - Netskope.Audit Tags: - Netskope - - Configuration Required + - Configuration Required # configure threshold for your environment - Brute Force Reports: MITRE ATT&CK: diff --git a/rules/notion_rules/notion_login_from_blocked_ip.yml b/rules/notion_rules/notion_login_from_blocked_ip.yml index af4e2134b..c47541ce1 100644 --- a/rules/notion_rules/notion_login_from_blocked_ip.yml +++ b/rules/notion_rules/notion_login_from_blocked_ip.yml @@ -9,6 +9,7 @@ Tags: - Notion - Network Security Monitoring - Malicious Connections + - Configuration Required Severity: Medium Description: "A user attempted to access Notion from a blocked IP address. Note: before deployinh, make sure to add Rule Filters checking if event.ip_address is in a certain CIDR range(s)." DedupPeriodMinutes: 60 diff --git a/rules/okta_rules/okta_idp_signin.yaml b/rules/okta_rules/okta_idp_signin.yaml index feade31b6..6409a618b 100644 --- a/rules/okta_rules/okta_idp_signin.yaml +++ b/rules/okta_rules/okta_idp_signin.yaml @@ -5,6 +5,8 @@ DisplayName: "Okta Identity Provider Sign-in" Enabled: false LogTypes: - Okta.SystemLog +Tags: + - Configuration Required Reports: MITRE ATT&CK: - TA0001:T1199 # Trusted Relationship From 50fd32bba4b8da9dea069816746b0a6a5010d723 Mon Sep 17 00:00:00 2001 From: nskobov <93276498+nskobov@users.noreply.github.com> Date: Tue, 13 Feb 2024 15:51:56 -0600 Subject: [PATCH 11/11] Update panther_analysis_tool version (#1108) * Update panther_analysis_tool version * make deps-update --- Pipfile | 2 +- Pipfile.lock | 65 +++++++++++++++++++++++++++++++--------------------- 2 files changed, 40 insertions(+), 27 deletions(-) diff --git a/Pipfile b/Pipfile index 7fc86308c..95e4f9a9f 100644 --- a/Pipfile +++ b/Pipfile @@ -19,7 +19,7 @@ wrapt = "~=1.15" [packages] policyuniverse = "==1.5.1.20230817" requests = "==2.31.0" -panther-analysis-tool = "~=0.39" +panther-analysis-tool = "~=0.40" panther-detection-helpers = "==0.2.0" [requires] diff --git a/Pipfile.lock b/Pipfile.lock index f22df0f43..4204c9c87 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "d2d43cb0e38e6667b7f9fc5f22dc91cfe095a2e0c7825c2e9105a18dbfeae942" + "sha256": "ef3121c751224143c7f27939ddd036b7a8b5a454d45de632892d1a4369805548" }, "pipfile-spec": 6, "requires": { @@ -147,19 +147,19 @@ }, "boto3": { "hashes": [ - "sha256:7c70c6ceb2706c7fad6466a5de174fe6d0d6f5f8f1e052bfaad9cbe4e53b64cd", - "sha256:e74fbad79bc921a74a9a276ef9f38e1e31153f76690fe9bc5ec790007de36572" + "sha256:9fd66f22a4cdd63165a7a19186fff9b6e3d742e83498ea3f3231bab6ae4bf0f3", + "sha256:ae1a974c728c076a49392a695102124f650f45361c654bb7c0bef1bb644c52d5" ], "markers": "python_version >= '3.8'", - "version": "==1.34.38" + "version": "==1.34.41" }, "botocore": { "hashes": [ - "sha256:773e49f5bf596191e796b2a15096ff381e61778cbe7c982b381bb9f6bfe5fef3", - "sha256:da9754a8e1798706427ede9c9c0a55263bd8e57f217c021807b2946eb4a0c2d8" + "sha256:3a6943c75a0d292ab6e008bce58ee6503776969479f991f5ad03a5d877af29ae", + "sha256:9b5827332da766da487e5a5b14b36e02528be9f2e899f909577afb7001eb441d" ], "markers": "python_version >= '3.8'", - "version": "==1.34.38" + "version": "==1.34.41" }, "certifi": { "hashes": [ @@ -668,10 +668,10 @@ }, "panther-analysis-tool": { "hashes": [ - "sha256:70bea9cbadd820ae2e77361e966320e058d5d16ebbc8d730298b0606844e934c" + "sha256:54534d08ef27e35186a7e5cfbc2eb7970132d615367372906d2065e030164718" ], "index": "pypi", - "version": "==0.39.0" + "version": "==0.40.0" }, "panther-core": { "hashes": [ @@ -715,6 +715,7 @@ "sha256:7920896195af163230635f1a5cee0958f56003ef8c421f805ec81f134f80a57c" ], "index": "pypi", + "markers": "python_version >= '3.7'", "version": "==1.5.1.20230817" }, "pygments": { @@ -738,7 +739,7 @@ "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86", "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'", + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==2.8.2" }, "pyyaml": { @@ -911,6 +912,7 @@ "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1" ], "index": "pypi", + "markers": "python_version >= '3.7'", "version": "==2.31.0" }, "rpds-py": { @@ -1079,7 +1081,7 @@ "sha256:f481f16baec5290e45aebdc2a5168ebc6d35189ae6fea7a58787613a25f6e875", "sha256:fff3573c2db359f091e1589c3d7c5fc2f86f5bdb6f24252c2d8e539d4e45f412" ], - "markers": "platform_python_implementation == 'CPython' and python_version < '3.13'", + "markers": "python_version < '3.13' and platform_python_implementation == 'CPython'", "version": "==0.2.8" }, "s3transfer": { @@ -1110,7 +1112,7 @@ "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'", + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==1.16.0" }, "sniffio": { @@ -1155,11 +1157,11 @@ }, "tqdm": { "hashes": [ - "sha256:d302b3c5b53d47bce91fea46679d9c3c6508cf6332229aa1e7d8653723793386", - "sha256:d88e651f9db8d8551a62556d3cff9e3034274ca5d66e93197cf2490e2dcb69c7" + "sha256:1ee4f8a893eb9bef51c6e35730cebf234d5d0b6bd112b0271e10ed7c24a02bd9", + "sha256:6cd52cdf0fef0e0f543299cfc96fec90d7b8a7e88745f411ec33eb44d5ed3531" ], "markers": "python_version >= '3.7'", - "version": "==4.66.1" + "version": "==4.66.2" }, "typing-extensions": { "hashes": [ @@ -1289,6 +1291,7 @@ "sha256:527906bec6088cb499aae31bc962864b4e77569e9d529ee51df3a93b4b8ab28a" ], "index": "pypi", + "markers": "python_version >= '3.8'", "version": "==1.7.7" }, "black": { @@ -1307,23 +1310,24 @@ "sha256:d30b212bffeb1e252b31dd269dfae69dd17e06d92b87ad26e23890f3efea366f" ], "index": "pypi", + "markers": "python_version >= '3.7'", "version": "==22.12.0" }, "boto3": { "hashes": [ - "sha256:7c70c6ceb2706c7fad6466a5de174fe6d0d6f5f8f1e052bfaad9cbe4e53b64cd", - "sha256:e74fbad79bc921a74a9a276ef9f38e1e31153f76690fe9bc5ec790007de36572" + "sha256:9fd66f22a4cdd63165a7a19186fff9b6e3d742e83498ea3f3231bab6ae4bf0f3", + "sha256:ae1a974c728c076a49392a695102124f650f45361c654bb7c0bef1bb644c52d5" ], "markers": "python_version >= '3.8'", - "version": "==1.34.38" + "version": "==1.34.41" }, "botocore": { "hashes": [ - "sha256:773e49f5bf596191e796b2a15096ff381e61778cbe7c982b381bb9f6bfe5fef3", - "sha256:da9754a8e1798706427ede9c9c0a55263bd8e57f217c021807b2946eb4a0c2d8" + "sha256:3a6943c75a0d292ab6e008bce58ee6503776969479f991f5ad03a5d877af29ae", + "sha256:9b5827332da766da487e5a5b14b36e02528be9f2e899f909577afb7001eb441d" ], "markers": "python_version >= '3.8'", - "version": "==1.34.38" + "version": "==1.34.41" }, "certifi": { "hashes": [ @@ -1539,6 +1543,7 @@ "sha256:b8c3f85900b9dc423225913c5aace94729fe1fa9763b38939a95226f02d37186" ], "index": "pypi", + "markers": "python_version >= '3.5'", "version": "==5.1.1" }, "dill": { @@ -1547,6 +1552,7 @@ "sha256:c36ca9ffb54365bdd2f8eb3eff7d2a21237f8452b57ace88b1ac615b7e815bd7" ], "index": "pypi", + "markers": "python_version >= '3.8'", "version": "==0.3.8" }, "idna": { @@ -1563,6 +1569,7 @@ "sha256:8ca5e72a8d85860d5a3fa69b8745237f2939afe12dbf656afbcb47fe72d947a6" ], "index": "pypi", + "markers": "python_full_version >= '3.8.0'", "version": "==5.13.2" }, "jinja2": { @@ -1720,6 +1727,7 @@ "sha256:94e3b07a403cc8078ffee94bf404ef677112d036a57ddb5e0f19c5fcf48987f5" ], "index": "pypi", + "markers": "python_version >= '3.8'", "version": "==5.0.1" }, "mypy": { @@ -1753,6 +1761,7 @@ "sha256:f5ac9a4eeb1ec0f1ccdc6f326bcdb464de5f80eb07fb38b5ddd7b0de6bc61e55" ], "index": "pypi", + "markers": "python_version >= '3.8'", "version": "==1.8.0" }, "mypy-extensions": { @@ -1808,6 +1817,7 @@ "sha256:f4fcac7ae74cfe36bc8451e931d8438e4a476c20314b1101c458ad0f05191fad" ], "index": "pypi", + "markers": "python_full_version >= '3.7.2'", "version": "==2.17.7" }, "pylint-print": { @@ -1816,6 +1826,7 @@ "sha256:a2b2599e7887b93e551db2624c523c1e6e9e58c3be8416cd98d41e4427e2669b" ], "index": "pypi", + "markers": "python_version >= '3.6'", "version": "==1.0.1" }, "python-dateutil": { @@ -1823,7 +1834,7 @@ "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86", "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'", + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==2.8.2" }, "pyyaml": { @@ -1889,15 +1900,16 @@ "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1" ], "index": "pypi", + "markers": "python_version >= '3.7'", "version": "==2.31.0" }, "responses": { "hashes": [ - "sha256:a2b43f4c08bfb9c9bd242568328c65a34b318741d3fab884ac843c5ceeb543f9", - "sha256:b127c6ca3f8df0eb9cc82fd93109a3007a86acb24871834c47b77765152ecf8c" + "sha256:01ae6a02b4f34e39bffceb0fc6786b67a25eae919c6368d05eabc8d9576c2a66", + "sha256:2f0b9c2b6437db4b528619a77e5d565e4ec2a9532162ac1a131a83529db7be1a" ], "markers": "python_version >= '3.8'", - "version": "==0.24.1" + "version": "==0.25.0" }, "rich": { "hashes": [ @@ -1920,7 +1932,7 @@ "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254" ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'", + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==1.16.0" }, "stevedore": { @@ -2045,6 +2057,7 @@ "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4" ], "index": "pypi", + "markers": "python_version >= '3.6'", "version": "==1.16.0" }, "xmltodict": {