From 60aaeb76b9bf59b13531f30ab916d0a8dee77b8c Mon Sep 17 00:00:00 2001 From: Evan Gibler Date: Tue, 13 Feb 2024 11:50:03 -0600 Subject: [PATCH 01/14] 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/14] [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/14] [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/14] [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/14] [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/14] [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/14] [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/14] 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/14] 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/14] [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/14] 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": { From 49db59c467537bf363eff355c176470436e6b537 Mon Sep 17 00:00:00 2001 From: Evan Gibler Date: Tue, 20 Feb 2024 17:09:29 -0600 Subject: [PATCH 12/14] Add SDYAML directories for Rules (#1110) * Add SDYAML directories for Rules * Make simple_rules a top-level directory --- .../gcp_cloudbuild_potential_privilege_escalation.yml | 3 +-- .../gcp_audit_rules/gcp_cloudfunctions_functions_create.yml | 0 .../gcp_audit_rules/gcp_cloudfunctions_functions_update.yml | 0 .../gcp_iam_roles_update_prielege_escalation.yml | 0 .../gcp_audit_rules/gcp_iam_service_account_key_create.yml | 0 .../gcp_privilege_escalation_by_deployments_create.yml | 0 .../gcp_serviceusage_apikeys_create_privilege_escalation.yml | 5 ++--- .../gcp_k8s_rules/gcp_k8s_ioc_activity.yml | 0 .../gcp_k8s_rules/gcp_kubernetes_new_daemonset_deployed.yml | 0 .../netskope_rules/netskope_admin_logged_out.yml | 0 .../netskope_rules/netskope_admin_user_change.yml | 0 .../netskope_rules/netskope_many_deletes.yml | 0 .../netskope_rules/netskope_personnel_action.yml | 0 .../netskope_rules/netskope_unauthorized_api_calls.yml | 0 14 files changed, 3 insertions(+), 5 deletions(-) rename {rules => simple_rules}/gcp_audit_rules/gcp_cloudbuild_potential_privilege_escalation.yml (98%) rename {rules => simple_rules}/gcp_audit_rules/gcp_cloudfunctions_functions_create.yml (100%) rename {rules => simple_rules}/gcp_audit_rules/gcp_cloudfunctions_functions_update.yml (100%) rename {rules => simple_rules}/gcp_audit_rules/gcp_iam_roles_update_prielege_escalation.yml (100%) rename {rules => simple_rules}/gcp_audit_rules/gcp_iam_service_account_key_create.yml (100%) rename {rules => simple_rules}/gcp_audit_rules/gcp_privilege_escalation_by_deployments_create.yml (100%) rename {rules => simple_rules}/gcp_audit_rules/gcp_serviceusage_apikeys_create_privilege_escalation.yml (99%) rename {rules => simple_rules}/gcp_k8s_rules/gcp_k8s_ioc_activity.yml (100%) rename {rules => simple_rules}/gcp_k8s_rules/gcp_kubernetes_new_daemonset_deployed.yml (100%) rename {rules => simple_rules}/netskope_rules/netskope_admin_logged_out.yml (100%) rename {rules => simple_rules}/netskope_rules/netskope_admin_user_change.yml (100%) rename {rules => simple_rules}/netskope_rules/netskope_many_deletes.yml (100%) rename {rules => simple_rules}/netskope_rules/netskope_personnel_action.yml (100%) rename {rules => simple_rules}/netskope_rules/netskope_unauthorized_api_calls.yml (100%) diff --git a/rules/gcp_audit_rules/gcp_cloudbuild_potential_privilege_escalation.yml b/simple_rules/gcp_audit_rules/gcp_cloudbuild_potential_privilege_escalation.yml similarity index 98% rename from rules/gcp_audit_rules/gcp_cloudbuild_potential_privilege_escalation.yml rename to simple_rules/gcp_audit_rules/gcp_cloudbuild_potential_privilege_escalation.yml index f7436ebf6..f12994f79 100644 --- a/rules/gcp_audit_rules/gcp_cloudbuild_potential_privilege_escalation.yml +++ b/simple_rules/gcp_audit_rules/gcp_cloudbuild_potential_privilege_escalation.yml @@ -29,8 +29,7 @@ Detection: - KeyPath: protoPayload.methodName Condition: EndsWith Value: CloudBuild.CreateBuild -AlertTitle: "[GCP]: [{protoPayload.authenticationInfo.principalEmail}] performed [{protoPayload.methodName}] on -project [{resource.labels.project_id}]" +AlertTitle: "[GCP]: [{protoPayload.authenticationInfo.principalEmail}] performed [{protoPayload.methodName}] on project [{resource.labels.project_id}]" AlertContext: - KeyName: project KeyValue: diff --git a/rules/gcp_audit_rules/gcp_cloudfunctions_functions_create.yml b/simple_rules/gcp_audit_rules/gcp_cloudfunctions_functions_create.yml similarity index 100% rename from rules/gcp_audit_rules/gcp_cloudfunctions_functions_create.yml rename to simple_rules/gcp_audit_rules/gcp_cloudfunctions_functions_create.yml diff --git a/rules/gcp_audit_rules/gcp_cloudfunctions_functions_update.yml b/simple_rules/gcp_audit_rules/gcp_cloudfunctions_functions_update.yml similarity index 100% rename from rules/gcp_audit_rules/gcp_cloudfunctions_functions_update.yml rename to simple_rules/gcp_audit_rules/gcp_cloudfunctions_functions_update.yml diff --git a/rules/gcp_audit_rules/gcp_iam_roles_update_prielege_escalation.yml b/simple_rules/gcp_audit_rules/gcp_iam_roles_update_prielege_escalation.yml similarity index 100% rename from rules/gcp_audit_rules/gcp_iam_roles_update_prielege_escalation.yml rename to simple_rules/gcp_audit_rules/gcp_iam_roles_update_prielege_escalation.yml diff --git a/rules/gcp_audit_rules/gcp_iam_service_account_key_create.yml b/simple_rules/gcp_audit_rules/gcp_iam_service_account_key_create.yml similarity index 100% rename from rules/gcp_audit_rules/gcp_iam_service_account_key_create.yml rename to simple_rules/gcp_audit_rules/gcp_iam_service_account_key_create.yml diff --git a/rules/gcp_audit_rules/gcp_privilege_escalation_by_deployments_create.yml b/simple_rules/gcp_audit_rules/gcp_privilege_escalation_by_deployments_create.yml similarity index 100% rename from rules/gcp_audit_rules/gcp_privilege_escalation_by_deployments_create.yml rename to simple_rules/gcp_audit_rules/gcp_privilege_escalation_by_deployments_create.yml diff --git a/rules/gcp_audit_rules/gcp_serviceusage_apikeys_create_privilege_escalation.yml b/simple_rules/gcp_audit_rules/gcp_serviceusage_apikeys_create_privilege_escalation.yml similarity index 99% rename from rules/gcp_audit_rules/gcp_serviceusage_apikeys_create_privilege_escalation.yml rename to simple_rules/gcp_audit_rules/gcp_serviceusage_apikeys_create_privilege_escalation.yml index 5ffdff704..ff752560a 100644 --- a/rules/gcp_audit_rules/gcp_serviceusage_apikeys_create_privilege_escalation.yml +++ b/simple_rules/gcp_audit_rules/gcp_serviceusage_apikeys_create_privilege_escalation.yml @@ -27,8 +27,7 @@ Detection: - KeyPath: protoPayload.methodName Condition: EndsWith Value: ApiKeys.CreateKey -AlertTitle: "[GCP]: [{protoPayload.authenticationInfo.principalEmail}] created new API Key in -project [{resource.labels.project_id}]" +AlertTitle: "[GCP]: [{protoPayload.authenticationInfo.principalEmail}] created new API Key in project [{resource.labels.project_id}]" AlertContext: - KeyName: project KeyValue: @@ -214,4 +213,4 @@ Tests: "resource": { }, "severity": "NOTICE", "timestamp": "2024-01-25 13:28:18.961519813" - } \ No newline at end of file + } diff --git a/rules/gcp_k8s_rules/gcp_k8s_ioc_activity.yml b/simple_rules/gcp_k8s_rules/gcp_k8s_ioc_activity.yml similarity index 100% rename from rules/gcp_k8s_rules/gcp_k8s_ioc_activity.yml rename to simple_rules/gcp_k8s_rules/gcp_k8s_ioc_activity.yml diff --git a/rules/gcp_k8s_rules/gcp_kubernetes_new_daemonset_deployed.yml b/simple_rules/gcp_k8s_rules/gcp_kubernetes_new_daemonset_deployed.yml similarity index 100% rename from rules/gcp_k8s_rules/gcp_kubernetes_new_daemonset_deployed.yml rename to simple_rules/gcp_k8s_rules/gcp_kubernetes_new_daemonset_deployed.yml diff --git a/rules/netskope_rules/netskope_admin_logged_out.yml b/simple_rules/netskope_rules/netskope_admin_logged_out.yml similarity index 100% rename from rules/netskope_rules/netskope_admin_logged_out.yml rename to simple_rules/netskope_rules/netskope_admin_logged_out.yml diff --git a/rules/netskope_rules/netskope_admin_user_change.yml b/simple_rules/netskope_rules/netskope_admin_user_change.yml similarity index 100% rename from rules/netskope_rules/netskope_admin_user_change.yml rename to simple_rules/netskope_rules/netskope_admin_user_change.yml diff --git a/rules/netskope_rules/netskope_many_deletes.yml b/simple_rules/netskope_rules/netskope_many_deletes.yml similarity index 100% rename from rules/netskope_rules/netskope_many_deletes.yml rename to simple_rules/netskope_rules/netskope_many_deletes.yml diff --git a/rules/netskope_rules/netskope_personnel_action.yml b/simple_rules/netskope_rules/netskope_personnel_action.yml similarity index 100% rename from rules/netskope_rules/netskope_personnel_action.yml rename to simple_rules/netskope_rules/netskope_personnel_action.yml diff --git a/rules/netskope_rules/netskope_unauthorized_api_calls.yml b/simple_rules/netskope_rules/netskope_unauthorized_api_calls.yml similarity index 100% rename from rules/netskope_rules/netskope_unauthorized_api_calls.yml rename to simple_rules/netskope_rules/netskope_unauthorized_api_calls.yml From 0ea1223dac223726e864ffee84d9a8d8f1894c3d Mon Sep 17 00:00:00 2001 From: Evan Gibler Date: Tue, 20 Feb 2024 17:31:18 -0600 Subject: [PATCH 13/14] Add _simple suffix to SDYAML Rules (#1111) --- ...l => gcp_cloudbuild_potential_privilege_escalation_simple.yml} | 0 ..._create.yml => gcp_cloudfunctions_functions_create_simple.yml} | 0 ..._update.yml => gcp_cloudfunctions_functions_update_simple.yml} | 0 ...n.yml => gcp_iam_roles_update_privilege_escalation_simple.yml} | 0 ...y_create.yml => gcp_iam_service_account_key_create_simple.yml} | 0 ... => gcp_privilege_escalation_by_deployments_create_simple.yml} | 0 ...p_serviceusage_apikeys_create_privilege_escalation_simple.yml} | 0 .../{gcp_k8s_ioc_activity.yml => gcp_k8s_ioc_activity_simple.yml} | 0 ...loyed.yml => gcp_kubernetes_new_daemonset_deployed_simple.yml} | 0 ..._admin_logged_out.yml => netskope_admin_logged_out_simple.yml} | 0 ...dmin_user_change.yml => netskope_admin_user_change_simple.yml} | 0 ...netskope_many_deletes.yml => netskope_many_deletes_simple.yml} | 0 ..._personnel_action.yml => netskope_personnel_action_simple.yml} | 0 ...d_api_calls.yml => netskope_unauthorized_api_calls_simple.yml} | 0 14 files changed, 0 insertions(+), 0 deletions(-) rename simple_rules/gcp_audit_rules/{gcp_cloudbuild_potential_privilege_escalation.yml => gcp_cloudbuild_potential_privilege_escalation_simple.yml} (100%) rename simple_rules/gcp_audit_rules/{gcp_cloudfunctions_functions_create.yml => gcp_cloudfunctions_functions_create_simple.yml} (100%) rename simple_rules/gcp_audit_rules/{gcp_cloudfunctions_functions_update.yml => gcp_cloudfunctions_functions_update_simple.yml} (100%) rename simple_rules/gcp_audit_rules/{gcp_iam_roles_update_prielege_escalation.yml => gcp_iam_roles_update_privilege_escalation_simple.yml} (100%) rename simple_rules/gcp_audit_rules/{gcp_iam_service_account_key_create.yml => gcp_iam_service_account_key_create_simple.yml} (100%) rename simple_rules/gcp_audit_rules/{gcp_privilege_escalation_by_deployments_create.yml => gcp_privilege_escalation_by_deployments_create_simple.yml} (100%) rename simple_rules/gcp_audit_rules/{gcp_serviceusage_apikeys_create_privilege_escalation.yml => gcp_serviceusage_apikeys_create_privilege_escalation_simple.yml} (100%) rename simple_rules/gcp_k8s_rules/{gcp_k8s_ioc_activity.yml => gcp_k8s_ioc_activity_simple.yml} (100%) rename simple_rules/gcp_k8s_rules/{gcp_kubernetes_new_daemonset_deployed.yml => gcp_kubernetes_new_daemonset_deployed_simple.yml} (100%) rename simple_rules/netskope_rules/{netskope_admin_logged_out.yml => netskope_admin_logged_out_simple.yml} (100%) rename simple_rules/netskope_rules/{netskope_admin_user_change.yml => netskope_admin_user_change_simple.yml} (100%) rename simple_rules/netskope_rules/{netskope_many_deletes.yml => netskope_many_deletes_simple.yml} (100%) rename simple_rules/netskope_rules/{netskope_personnel_action.yml => netskope_personnel_action_simple.yml} (100%) rename simple_rules/netskope_rules/{netskope_unauthorized_api_calls.yml => netskope_unauthorized_api_calls_simple.yml} (100%) diff --git a/simple_rules/gcp_audit_rules/gcp_cloudbuild_potential_privilege_escalation.yml b/simple_rules/gcp_audit_rules/gcp_cloudbuild_potential_privilege_escalation_simple.yml similarity index 100% rename from simple_rules/gcp_audit_rules/gcp_cloudbuild_potential_privilege_escalation.yml rename to simple_rules/gcp_audit_rules/gcp_cloudbuild_potential_privilege_escalation_simple.yml diff --git a/simple_rules/gcp_audit_rules/gcp_cloudfunctions_functions_create.yml b/simple_rules/gcp_audit_rules/gcp_cloudfunctions_functions_create_simple.yml similarity index 100% rename from simple_rules/gcp_audit_rules/gcp_cloudfunctions_functions_create.yml rename to simple_rules/gcp_audit_rules/gcp_cloudfunctions_functions_create_simple.yml diff --git a/simple_rules/gcp_audit_rules/gcp_cloudfunctions_functions_update.yml b/simple_rules/gcp_audit_rules/gcp_cloudfunctions_functions_update_simple.yml similarity index 100% rename from simple_rules/gcp_audit_rules/gcp_cloudfunctions_functions_update.yml rename to simple_rules/gcp_audit_rules/gcp_cloudfunctions_functions_update_simple.yml diff --git a/simple_rules/gcp_audit_rules/gcp_iam_roles_update_prielege_escalation.yml b/simple_rules/gcp_audit_rules/gcp_iam_roles_update_privilege_escalation_simple.yml similarity index 100% rename from simple_rules/gcp_audit_rules/gcp_iam_roles_update_prielege_escalation.yml rename to simple_rules/gcp_audit_rules/gcp_iam_roles_update_privilege_escalation_simple.yml diff --git a/simple_rules/gcp_audit_rules/gcp_iam_service_account_key_create.yml b/simple_rules/gcp_audit_rules/gcp_iam_service_account_key_create_simple.yml similarity index 100% rename from simple_rules/gcp_audit_rules/gcp_iam_service_account_key_create.yml rename to simple_rules/gcp_audit_rules/gcp_iam_service_account_key_create_simple.yml diff --git a/simple_rules/gcp_audit_rules/gcp_privilege_escalation_by_deployments_create.yml b/simple_rules/gcp_audit_rules/gcp_privilege_escalation_by_deployments_create_simple.yml similarity index 100% rename from simple_rules/gcp_audit_rules/gcp_privilege_escalation_by_deployments_create.yml rename to simple_rules/gcp_audit_rules/gcp_privilege_escalation_by_deployments_create_simple.yml diff --git a/simple_rules/gcp_audit_rules/gcp_serviceusage_apikeys_create_privilege_escalation.yml b/simple_rules/gcp_audit_rules/gcp_serviceusage_apikeys_create_privilege_escalation_simple.yml similarity index 100% rename from simple_rules/gcp_audit_rules/gcp_serviceusage_apikeys_create_privilege_escalation.yml rename to simple_rules/gcp_audit_rules/gcp_serviceusage_apikeys_create_privilege_escalation_simple.yml diff --git a/simple_rules/gcp_k8s_rules/gcp_k8s_ioc_activity.yml b/simple_rules/gcp_k8s_rules/gcp_k8s_ioc_activity_simple.yml similarity index 100% rename from simple_rules/gcp_k8s_rules/gcp_k8s_ioc_activity.yml rename to simple_rules/gcp_k8s_rules/gcp_k8s_ioc_activity_simple.yml diff --git a/simple_rules/gcp_k8s_rules/gcp_kubernetes_new_daemonset_deployed.yml b/simple_rules/gcp_k8s_rules/gcp_kubernetes_new_daemonset_deployed_simple.yml similarity index 100% rename from simple_rules/gcp_k8s_rules/gcp_kubernetes_new_daemonset_deployed.yml rename to simple_rules/gcp_k8s_rules/gcp_kubernetes_new_daemonset_deployed_simple.yml diff --git a/simple_rules/netskope_rules/netskope_admin_logged_out.yml b/simple_rules/netskope_rules/netskope_admin_logged_out_simple.yml similarity index 100% rename from simple_rules/netskope_rules/netskope_admin_logged_out.yml rename to simple_rules/netskope_rules/netskope_admin_logged_out_simple.yml diff --git a/simple_rules/netskope_rules/netskope_admin_user_change.yml b/simple_rules/netskope_rules/netskope_admin_user_change_simple.yml similarity index 100% rename from simple_rules/netskope_rules/netskope_admin_user_change.yml rename to simple_rules/netskope_rules/netskope_admin_user_change_simple.yml diff --git a/simple_rules/netskope_rules/netskope_many_deletes.yml b/simple_rules/netskope_rules/netskope_many_deletes_simple.yml similarity index 100% rename from simple_rules/netskope_rules/netskope_many_deletes.yml rename to simple_rules/netskope_rules/netskope_many_deletes_simple.yml diff --git a/simple_rules/netskope_rules/netskope_personnel_action.yml b/simple_rules/netskope_rules/netskope_personnel_action_simple.yml similarity index 100% rename from simple_rules/netskope_rules/netskope_personnel_action.yml rename to simple_rules/netskope_rules/netskope_personnel_action_simple.yml diff --git a/simple_rules/netskope_rules/netskope_unauthorized_api_calls.yml b/simple_rules/netskope_rules/netskope_unauthorized_api_calls_simple.yml similarity index 100% rename from simple_rules/netskope_rules/netskope_unauthorized_api_calls.yml rename to simple_rules/netskope_rules/netskope_unauthorized_api_calls_simple.yml From f03e9757c189ab25505fc13cbaf35710106dff14 Mon Sep 17 00:00:00 2001 From: Evan Gibler Date: Wed, 21 Feb 2024 12:29:54 -0600 Subject: [PATCH 14/14] Prepare for `3.42.0` (#1117) * Add .Simple suffix to Simple Rule IDs (#1112) * Add .Simple suffix to Simple Rule IDs * Update Rule IDs in Packs * [sync] Add GCP GKE Kubernetes Cron Job Created Or Modified rule (#68) (#1113) * Add GCP GKE Kubernetes Cron Job Created Or Modified rule (#68) Co-authored-by: Evan Gibler * Move to simple_rules --------- Co-authored-by: Oleh Melenevskyi <767472+melenevskyi@users.noreply.github.com> * [sync] Add GCP.K8s.Pod.Using.Host.PID.Namespace rule (#84) (#1114) * Add GCP.K8s.Pod.Using.Host.PID.Namespace rule * Update filename * Add .Simple suffix to Rule ID --------- Co-authored-by: Oleh Melenevskyi <767472+melenevskyi@users.noreply.github.com> Co-authored-by: akozlovets098 <95437895+akozlovets098@users.noreply.github.com> * [sync] GCP K8S Pod Create Or Modify Host Path Volume Mount - rule (#85) (#1115) Co-authored-by: akozlovets098 <95437895+akozlovets098@users.noreply.github.com> * [sync] GCP K8S Service Type NodePort Deployed - rule (#86) (#1116) * GCP K8S Service Type NodePort Deployed - rule * GCP K8S Service Type NodePort Deployed - moved to simple rules folder * Update filename * Add .Simple suffix to Rule ID --------- Co-authored-by: akozlovets098 <95437895+akozlovets098@users.noreply.github.com> --------- Co-authored-by: Oleh Melenevskyi <767472+melenevskyi@users.noreply.github.com> Co-authored-by: akozlovets098 <95437895+akozlovets098@users.noreply.github.com> --- packs/gcp_audit.yml | 23 +- packs/netskope.yml | 6 +- ...od_create_or_modify_host_path_vol_mount.py | 71 +++++ ...d_create_or_modify_host_path_vol_mount.yml | 287 +++++++++++++++++ ..._potential_privilege_escalation_simple.yml | 2 +- ...cloudfunctions_functions_create_simple.yml | 4 +- ...cloudfunctions_functions_update_simple.yml | 4 +- ...es_cron_job_created_or_modified_simple.yml | 71 +++++ ...les_update_privilege_escalation_simple.yml | 2 +- ..._iam_service_account_key_create_simple.yml | 2 +- ...scalation_by_deployments_create_simple.yml | 2 +- ...eys_create_privilege_escalation_simple.yml | 2 +- .../gcp_k8s_ioc_activity_simple.yml | 2 +- ...8s_pod_using_host_pid_namespace_simple.yml | 70 +++++ ...service_type_node_port_deployed_simple.yml | 290 ++++++++++++++++++ ...bernetes_new_daemonset_deployed_simple.yml | 2 +- .../netskope_admin_logged_out_simple.yml | 2 +- .../netskope_admin_user_change_simple.yml | 4 +- .../netskope_many_deletes_simple.yml | 2 +- .../netskope_personnel_action_simple.yml | 2 +- ...netskope_unauthorized_api_calls_simple.yml | 2 +- 21 files changed, 821 insertions(+), 31 deletions(-) create mode 100644 rules/gcp_k8s_rules/gcp_k8s_pod_create_or_modify_host_path_vol_mount.py create mode 100644 rules/gcp_k8s_rules/gcp_k8s_pod_create_or_modify_host_path_vol_mount.yml create mode 100644 simple_rules/gcp_audit_rules/gcp_gke_kubernetes_cron_job_created_or_modified_simple.yml create mode 100644 simple_rules/gcp_k8s_rules/gcp_k8s_pod_using_host_pid_namespace_simple.yml create mode 100644 simple_rules/gcp_k8s_rules/gcp_k8s_service_type_node_port_deployed_simple.yml diff --git a/packs/gcp_audit.yml b/packs/gcp_audit.yml index 0a689a423..f06f7b71f 100644 --- a/packs/gcp_audit.yml +++ b/packs/gcp_audit.yml @@ -7,9 +7,9 @@ PackDefinition: - GCP.Access.Attempts.Violating.VPC.Service.Controls - GCP.BigQuery.Large.Scan - GCP.Cloud.Storage.Buckets.Modified.Or.Deleted - - GCP.CloudBuild.Potential.Privilege.Escalation - - GCP.Cloudfunctions.Functions.Create - - GCP.Cloudfunctions.Functions.Update + - GCP.CloudBuild.Potential.Privilege.Escalation.Simple + - GCP.Cloudfunctions.Functions.Create.Simple + - GCP.Cloudfunctions.Functions.Update.Simple - GCP.Destructive.Queries - GCP.DNS.Zone.Modified.or.Deleted - GCP.Firewall.Rule.Created @@ -17,35 +17,36 @@ PackDefinition: - GCP.Firewall.Rule.Modified - GCP.GCS.IAMChanges - GCP.GCS.Public + - GCP.GKE.Kubernetes.Cron.Job.Created.Or.Modified.Simple - GCP.IAM.CorporateEmail - GCP.IAM.CustomRoleChanges - GCP.IAM.OrgFolderIAMChanges - - GCP.iam.roles.update.Privilege.Escalation - - GCP.iam.serviceAccountKeys.create + - GCP.iam.roles.update.Privilege.Escalation.Simple + - GCP.iam.serviceAccountKeys.create.Simple - GCP.Inbound.SSO.Profile.Created + - GCP.K8s.New.Daemonset.Deployed.Simple - GCP.Log.Bucket.Or.Sink.Deleted - GCP.Logging.Settings.Modified - GCP.Logging.Sink.Modified - GCP.Permissions.Granted.to.Create.or.Manage.Service.Account.Key - - GCP.Privilege.Escalation.By.Deployments.Create + - GCP.Privilege.Escalation.By.Deployments.Create.Simple - GCP.Service.Account.Access.Denied - GCP.Service.Account.or.Keys.Created - - GCP.serviceusage.apiKeys.create.Privilege.Escalation + - GCP.serviceusage.apiKeys.create.Privilege.Escalation.Simple - GCP.SQL.ConfigChanges + - GCP.Storage.Hmac.Keys.Create - GCP.User.Added.to.IAP.Protected.Service - GCP.VPC.Flow.Logs.Disabled - 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 - - panther_base_helpers - - panther_event_type_helpers - gcp_base_helpers - gcp_environment + - panther_base_helpers - panther_config - panther_config_defaults - panther_config_overrides + - panther_event_type_helpers DisplayName: "Panther GCP Audit Pack" diff --git a/packs/netskope.yml b/packs/netskope.yml index bb4754f02..e2454b057 100644 --- a/packs/netskope.yml +++ b/packs/netskope.yml @@ -3,7 +3,7 @@ PackID: PantherManaged.Netskope Description: Group of all Netskope detections PackDefinition: IDs: - - Netskope.AdminLoggedOutLoginFailures - - Netskope.AdminUserChange - - Netskope.NetskopePersonnelActivity + - Netskope.AdminLoggedOutLoginFailures.Simple + - Netskope.AdminUserChange.Simple + - Netskope.NetskopePersonnelActivity.Simple DisplayName: "Panther Netskope Pack" diff --git a/rules/gcp_k8s_rules/gcp_k8s_pod_create_or_modify_host_path_vol_mount.py b/rules/gcp_k8s_rules/gcp_k8s_pod_create_or_modify_host_path_vol_mount.py new file mode 100644 index 000000000..e64e8ef7a --- /dev/null +++ b/rules/gcp_k8s_rules/gcp_k8s_pod_create_or_modify_host_path_vol_mount.py @@ -0,0 +1,71 @@ +from gcp_base_helpers import gcp_alert_context +from panther_base_helpers import deep_get, deep_walk + + +SUSPICIOUS_PATHS = [ + "/var/run/docker.sock", + "/var/run/crio/crio.sock", + "/var/lib/kubelet", + "/var/lib/kubelet/pki", + "/var/lib/docker/overlay2", + "/etc/kubernetes", + "/etc/kubernetes/manifests", + "/etc/kubernetes/pki", + "/home/admin", +] + + +def rule(event): + if deep_get(event, "protoPayload", "response", "status") == "Failure": + return False + + if deep_get(event, "protoPayload", "methodName") not in ( + "io.k8s.core.v1.pods.create", + "io.k8s.core.v1.pods.update", + "io.k8s.core.v1.pods.patch", + ): + return False + + volume_mount_path = deep_walk( + event, "protoPayload", "request", "spec", "volumes", "hostPath", "path" + ) + if volume_mount_path not in SUSPICIOUS_PATHS and not any( + path in SUSPICIOUS_PATHS for path in volume_mount_path + ): + return False + + authorization_info = deep_walk(event, "protoPayload", "authorizationInfo") + for auth in authorization_info: + if ( + auth.get("permission") + in ( + "io.k8s.core.v1.pods.create", + "io.k8s.core.v1.pods.update", + "io.k8s.core.v1.pods.patch", + ) + and auth.get("granted") is True + ): + 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 k8s pod [{pod_name}] with a hostPath volume mount " + f"in project [{project_id}]" + ) + + +def alert_context(event): + context = gcp_alert_context(event) + volume_mount_path = deep_walk( + event, "protoPayload", "request", "spec", "volumes", "hostPath", "path" + ) + context["volume_mount_path"] = volume_mount_path + return context diff --git a/rules/gcp_k8s_rules/gcp_k8s_pod_create_or_modify_host_path_vol_mount.yml b/rules/gcp_k8s_rules/gcp_k8s_pod_create_or_modify_host_path_vol_mount.yml new file mode 100644 index 000000000..b59e46a7d --- /dev/null +++ b/rules/gcp_k8s_rules/gcp_k8s_pod_create_or_modify_host_path_vol_mount.yml @@ -0,0 +1,287 @@ +AnalysisType: rule +RuleID: "GCP.K8S.Pot.Create.Or.Modify.Host.Path.Volume.Mount" +DisplayName: "GCP K8S Pot Create Or Modify Host Path Volume Mount" +Enabled: true +LogTypes: + - GCP.AuditLog +Severity: High +Description: > + This detection monitors for pod creation with a hostPath volume mount. The attachment to a node's volume can allow + for privilege escalation through underlying vulnerabilities or it can open up possibilities for data exfiltration + or unauthorized file access. It is very rare to see this being a pod requirement. +Runbook: > + Investigate the reason of adding hostPath volume mount. Advise that it is discouraged practice. + Create ticket if appropriate. +Reference: https://linuxhint.com/kubernetes-hostpath-volumes/ +Reports: + MITRE ATT&CK: + - TA0001 # Initial Access + - TA0002 # Execution +Filename: gcp_k8s_pod_create_or_modify_host_path_vol_mount.py +Tests: + - + Name: Pod With Suspicious Volume Mount Created + ExpectedResult: true + Log: + { + "logName": "projects/some-project/logs/cloudaudit.googleapis.com%2Factivity", + "protoPayload": { + "at_sign_type": "type.googleapis.com/google.cloud.audit.AuditLog", + "authenticationInfo": { + "principalEmail": "some.user@company.com" + }, + "authorizationInfo": [ + { + "granted": true, + "permission": "io.k8s.core.v1.pods.create", + "resource": "core/v1/namespaces/default/pods/test" + } + ], + "methodName": "io.k8s.core.v1.pods.create", + "request": { + "@type": "core.k8s.io/v1.Pod", + "apiVersion": "v1", + "kind": "Pod", + "metadata": { + "name": "test", + "namespace": "default" + }, + "spec": { + "containers": [ + { + "image": "nginx", + "imagePullPolicy": "Always", + "name": "test", + "volumeMounts": [ + { + "mountPath": "/test", + "name": "test-volume" + } + ] + } + ], + "volumes": [ + { + "hostPath": { + "path": "/var/lib/kubelet", + "type": "DirectoryOrCreate" + }, + "name": "test-volume" + } + ] + }, + }, + "requestMetadata": { + "callerIP": "1.2.3.4", + "callerSuppliedUserAgent": "kubectl/v1.28.2 (darwin/amd64) kubernetes/89a4ea3" + }, + "resourceName": "core/v1/namespaces/default/pods/test", + "response": { + "spec": { + "containers": [ + { + "image": "nginx", + "imagePullPolicy": "Always", + "name": "test", + "volumeMounts": [ + { + "mountPath": "/test", + "name": "test-volume" + }, + ] + } + ], + "volumes": [ + { + "hostPath": { + "path": "/var/lib/kubelet", + "type": "DirectoryOrCreate" + }, + "name": "test-volume" + }, + ] + }, + "status": { + "phase": "Pending", + "qosClass": "BestEffort" + } + }, + }, + "receiveTimestamp": "2024-02-16 11:48:43.531373988", + "resource": { + "labels": { + "cluster_name": "some-project-cluster", + "location": "us-west1", + "project_id": "some-project" + }, + "type": "k8s_cluster" + }, + "timestamp": "2024-02-16 11:48:22.742154000" + } + - Name: Pod With Non-Suspicious Volume Mount Created + 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": "some.user@company.com" + }, + "authorizationInfo": [ + { + "granted": true, + "permission": "io.k8s.core.v1.pods.create", + "resource": "core/v1/namespaces/default/pods/test" + } + ], + "methodName": "io.k8s.core.v1.pods.create", + "request": { + "@type": "core.k8s.io/v1.Pod", + "apiVersion": "v1", + "kind": "Pod", + "metadata": { + "name": "test", + "namespace": "default" + }, + "spec": { + "containers": [ + { + "image": "nginx", + "imagePullPolicy": "Always", + "name": "test", + "volumeMounts": [ + { + "mountPath": "/test", + "name": "test-volume" + } + ] + } + ], + "volumes": [ + { + "hostPath": { + "path": "/data", + "type": "DirectoryOrCreate" + }, + "name": "test-volume" + } + ] + }, + }, + "requestMetadata": { + "callerIP": "1.2.3.4", + "callerSuppliedUserAgent": "kubectl/v1.28.2 (darwin/amd64) kubernetes/89a4ea3" + }, + "resourceName": "core/v1/namespaces/default/pods/test", + "response": { + "spec": { + "containers": [ + { + "image": "nginx", + "imagePullPolicy": "Always", + "name": "test", + "volumeMounts": [ + { + "mountPath": "/test", + "name": "test-volume" + }, + ] + } + ], + "volumes": [ + { + "hostPath": { + "path": "/data", + "type": "DirectoryOrCreate" + }, + "name": "test-volume" + }, + ] + }, + "status": { + "phase": "Pending", + "qosClass": "BestEffort" + } + }, + }, + "receiveTimestamp": "2024-02-16 11:48:43.531373988", + "resource": { + "labels": { + "cluster_name": "some-project-cluster", + "location": "us-west1", + "project_id": "some-project" + }, + "type": "k8s_cluster" + }, + "timestamp": "2024-02-16 11:48:22.742154000" + } + - + Name: Pod Not Created + 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": "some.user@company.com" + }, + "authorizationInfo": [ + { + "granted": true, + "permission": "io.k8s.core.v1.pods.create", + "resource": "core/v1/namespaces/default/pods/test" + } + ], + "methodName": "io.k8s.core.v1.pods.create", + "request": { + "@type": "core.k8s.io/v1.Pod", + "apiVersion": "v1", + "kind": "Pod", + "metadata": { + "name": "test", + "namespace": "default" + }, + "spec": { + "containers": [ + { + "image": "nginx", + "imagePullPolicy": "Always", + "name": "test", + "volumeMounts": [ + { + "mountPath": "/test", + "name": "test-volume" + } + ] + } + ], + "volumes": [ + { + "hostPath": { + "path": "/var/lib/kubelet", + "type": "DirectoryOrCreate" + }, + "name": "test-volume" + } + ] + }, + "status": { } + }, + "resourceName": "core/v1/namespaces/default/pods/test", + "response": { + "status": "Failure" + }, + }, + "receiveTimestamp": "2024-02-16 12:55:17.003485190", + "resource": { + "labels": { + "cluster_name": "some-project-cluster", + "location": "us-west1", + "project_id": "some-project" + }, + "type": "k8s_cluster" + }, + "timestamp": "2024-02-16 12:55:00.510160000" + } diff --git a/simple_rules/gcp_audit_rules/gcp_cloudbuild_potential_privilege_escalation_simple.yml b/simple_rules/gcp_audit_rules/gcp_cloudbuild_potential_privilege_escalation_simple.yml index f12994f79..21313403f 100644 --- a/simple_rules/gcp_audit_rules/gcp_cloudbuild_potential_privilege_escalation_simple.yml +++ b/simple_rules/gcp_audit_rules/gcp_cloudbuild_potential_privilege_escalation_simple.yml @@ -5,7 +5,7 @@ Description: Detects privilege escalation attacks designed to gain access to the A user with permissions to start a new build with Cloud Build can gain access to the Cloud Build Service Account and abuse it for more access to the environment. DisplayName: "GCP CloudBuild Potential Privilege Escalation" -RuleID: "GCP.CloudBuild.Potential.Privilege.Escalation" +RuleID: "GCP.CloudBuild.Potential.Privilege.Escalation.Simple" Enabled: true Reference: https://rhinosecuritylabs.com/gcp/iam-privilege-escalation-gcp-cloudbuild/ Runbook: Confirm this was authorized and necessary behavior. To defend against this privilege escalation attack, diff --git a/simple_rules/gcp_audit_rules/gcp_cloudfunctions_functions_create_simple.yml b/simple_rules/gcp_audit_rules/gcp_cloudfunctions_functions_create_simple.yml index e4f438f5c..44412d504 100644 --- a/simple_rules/gcp_audit_rules/gcp_cloudfunctions_functions_create_simple.yml +++ b/simple_rules/gcp_audit_rules/gcp_cloudfunctions_functions_create_simple.yml @@ -1,5 +1,5 @@ AnalysisType: rule -RuleID: "GCP.Cloudfunctions.Functions.Create" +RuleID: "GCP.Cloudfunctions.Functions.Create.Simple" DisplayName: "GCP cloudfunctions functions create" Description: "The Identity and Access Management (IAM) service manages authorization and authentication for a GCP environment. This means that there are very likely multiple privilege escalation methods that use the IAM service and/or its permissions." Enabled: true @@ -54,4 +54,4 @@ Tests: project_id: panther-threat-research type: deployment severity: NOTICE - timestamp: "2024-01-19 13:47:18.279921000" \ No newline at end of file + timestamp: "2024-01-19 13:47:18.279921000" diff --git a/simple_rules/gcp_audit_rules/gcp_cloudfunctions_functions_update_simple.yml b/simple_rules/gcp_audit_rules/gcp_cloudfunctions_functions_update_simple.yml index 1a83fe396..8b951cd09 100644 --- a/simple_rules/gcp_audit_rules/gcp_cloudfunctions_functions_update_simple.yml +++ b/simple_rules/gcp_audit_rules/gcp_cloudfunctions_functions_update_simple.yml @@ -1,5 +1,5 @@ AnalysisType: rule -RuleID: "GCP.Cloudfunctions.Functions.Update" +RuleID: "GCP.Cloudfunctions.Functions.Update.Simple" DisplayName: "GCP cloudfunctions functions update" Description: "The Identity and Access Management (IAM) service manages authorization and authentication for a GCP environment. This means that there are very likely multiple privilege escalation methods that use the IAM service and/or its permissions." Enabled: true @@ -54,4 +54,4 @@ Tests: project_id: panther-threat-research type: deployment severity: NOTICE - timestamp: "2024-01-19 13:47:18.279921000" \ No newline at end of file + timestamp: "2024-01-19 13:47:18.279921000" diff --git a/simple_rules/gcp_audit_rules/gcp_gke_kubernetes_cron_job_created_or_modified_simple.yml b/simple_rules/gcp_audit_rules/gcp_gke_kubernetes_cron_job_created_or_modified_simple.yml new file mode 100644 index 000000000..1311279c3 --- /dev/null +++ b/simple_rules/gcp_audit_rules/gcp_gke_kubernetes_cron_job_created_or_modified_simple.yml @@ -0,0 +1,71 @@ +AnalysisType: rule +RuleID: "GCP.GKE.Kubernetes.Cron.Job.Created.Or.Modified.Simple" +DisplayName: "GCP GKE Kubernetes Cron Job Created Or Modified" +Description: "This detection monitor for any modifications or creations of a cron job in GKE. Attackers may create or modify an existing scheduled job in order to achieve cluster persistence." +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: + - Any: + - KeyPath: protoPayload.authorizationInfo[*].permission + Condition: Contains + Value: io.k8s.batch.v1.cronjobs.create + - KeyPath: protoPayload.authorizationInfo[*].permission + Condition: Contains + Value: io.k8s.batch.v1.cronjobs.update +Tests: + - Name: create + ExpectedResult: true + Log: + protoPayload: + authorizationInfo: + - granted: true + permission: io.k8s.batch.v1.cronjobs.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: update + ExpectedResult: true + Log: + protoPayload: + authorizationInfo: + - granted: true + permission: io.k8s.batch.v1.cronjobs.update + 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: cloudfunctions.functions.upsert + 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" diff --git a/simple_rules/gcp_audit_rules/gcp_iam_roles_update_privilege_escalation_simple.yml b/simple_rules/gcp_audit_rules/gcp_iam_roles_update_privilege_escalation_simple.yml index 026a803d8..27c389a25 100644 --- a/simple_rules/gcp_audit_rules/gcp_iam_roles_update_privilege_escalation_simple.yml +++ b/simple_rules/gcp_audit_rules/gcp_iam_roles_update_privilege_escalation_simple.yml @@ -1,5 +1,5 @@ AnalysisType: rule -RuleID: "GCP.iam.roles.update.Privilege.Escalation" +RuleID: "GCP.iam.roles.update.Privilege.Escalation.Simple" DisplayName: "GCP iam.roles.update Privilege Escalation" Description: "If your user is assigned a custom IAM role, then iam.roles.update will allow you to update the “includedPermissons” on that role. Because it is assigned to you, you will gain the additional privileges, which could be anything you desire." Enabled: true diff --git a/simple_rules/gcp_audit_rules/gcp_iam_service_account_key_create_simple.yml b/simple_rules/gcp_audit_rules/gcp_iam_service_account_key_create_simple.yml index f82fdca8b..5a1dd1599 100644 --- a/simple_rules/gcp_audit_rules/gcp_iam_service_account_key_create_simple.yml +++ b/simple_rules/gcp_audit_rules/gcp_iam_service_account_key_create_simple.yml @@ -1,5 +1,5 @@ AnalysisType: rule -RuleID: "GCP.iam.serviceAccountKeys.create" +RuleID: "GCP.iam.serviceAccountKeys.create.Simple" DisplayName: "GCP.Iam.ServiceAccountKeys.Create" Description: "If your user is assigned a custom IAM role, then iam.roles.update will allow you to update the “includedPermissons” on that role. Because it is assigned to you, you will gain the additional privileges, which could be anything you desire." Enabled: true diff --git a/simple_rules/gcp_audit_rules/gcp_privilege_escalation_by_deployments_create_simple.yml b/simple_rules/gcp_audit_rules/gcp_privilege_escalation_by_deployments_create_simple.yml index 9e0c36159..1daa546c0 100644 --- a/simple_rules/gcp_audit_rules/gcp_privilege_escalation_by_deployments_create_simple.yml +++ b/simple_rules/gcp_audit_rules/gcp_privilege_escalation_by_deployments_create_simple.yml @@ -1,5 +1,5 @@ AnalysisType: rule -RuleID: "GCP.Privilege.Escalation.By.Deployments.Create" +RuleID: "GCP.Privilege.Escalation.By.Deployments.Create.Simple" DisplayName: "GCP.Privilege.Escalation.By.Deployments.Create" Description: "Detects privilege escalation in GCP by taking over the deploymentsmanager.deployments.create permission" Enabled: true diff --git a/simple_rules/gcp_audit_rules/gcp_serviceusage_apikeys_create_privilege_escalation_simple.yml b/simple_rules/gcp_audit_rules/gcp_serviceusage_apikeys_create_privilege_escalation_simple.yml index ff752560a..b64970c64 100644 --- a/simple_rules/gcp_audit_rules/gcp_serviceusage_apikeys_create_privilege_escalation_simple.yml +++ b/simple_rules/gcp_audit_rules/gcp_serviceusage_apikeys_create_privilege_escalation_simple.yml @@ -5,7 +5,7 @@ Description: Detects serviceusage.apiKeys.create method for privilege escalation created with no restrictions, which means they have access to the entire GCP project they were created in. We can capitalize on that fact by creating a new API key that may have more privileges than our own user. DisplayName: "GCP serviceusage.apiKeys.create Privilege Escalation" -RuleID: "GCP.serviceusage.apiKeys.create.Privilege.Escalation" +RuleID: "GCP.serviceusage.apiKeys.create.Privilege.Escalation.Simple" Enabled: true Reference: https://rhinosecuritylabs.com/cloud-security/privilege-escalation-google-cloud-platform-part-2/ Runbook: Confirm this was authorized and necessary behavior. This is not a vulnerability in GCP, it is a vulnerability diff --git a/simple_rules/gcp_k8s_rules/gcp_k8s_ioc_activity_simple.yml b/simple_rules/gcp_k8s_rules/gcp_k8s_ioc_activity_simple.yml index e89cccfed..564ff1d3a 100644 --- a/simple_rules/gcp_k8s_rules/gcp_k8s_ioc_activity_simple.yml +++ b/simple_rules/gcp_k8s_rules/gcp_k8s_ioc_activity_simple.yml @@ -1,5 +1,5 @@ AnalysisType: rule -RuleID: "GCP.K8s.IOC.Activity" +RuleID: "GCP.K8s.IOC.Activity.Simple" DisplayName: "GCP K8s IOCActivity" Enabled: true LogTypes: diff --git a/simple_rules/gcp_k8s_rules/gcp_k8s_pod_using_host_pid_namespace_simple.yml b/simple_rules/gcp_k8s_rules/gcp_k8s_pod_using_host_pid_namespace_simple.yml new file mode 100644 index 000000000..dca8ff9a2 --- /dev/null +++ b/simple_rules/gcp_k8s_rules/gcp_k8s_pod_using_host_pid_namespace_simple.yml @@ -0,0 +1,70 @@ +AnalysisType: rule +RuleID: "GCP.K8s.Pod.Using.Host.PID.Namespace.Simple" +DisplayName: "GCP K8s Pod Using Host PID Namespace" +Enabled: true +LogTypes: + - GCP.AuditLog +Tags: + - GCP + - Optional +Severity: Medium +Description: This detection monitors for any pod creation or modification using the host PID namespace. The Host PID namespace enables a pod and its containers to have direct access and share the same view as of the host’s processes. This can offer a powerful escape hatch to the underlying host. +Detection: + - All: + - KeyPath: protoPayload.methodName + Condition: IsIn + Values: + - io.k8s.core.v1.pods.create + - io.k8s.core.v1.pods.update + - io.k8s.core.v1.pods.patch + - Any: + - KeyPath: protoPayload.request.spec.hostPID + Condition: Equals + Value: true + - KeyPath: protoPayload.response.spec.hostPID + Condition: Equals + Value: true +Reference: https://medium.com/snowflake/from-logs-to-detection-using-snowflake-and-panther-to-detect-k8s-threats-d72f70a504d7 +Tests: + - + Name: triggers + ExpectedResult: true + Log: + { + "authorizationInfo": [ + { + "granted": true, + "permission": "io.k8s.core.v1.pods.create", + "resource": "core/v1/namespaces/default/pods/nginx-test" + } + ], + "protoPayload": { + "methodName": "io.k8s.core.v1.pods.create", + "request": { + "spec": { + "hostPID": true, + } + } + } + } + - + Name: ignore + ExpectedResult: false + Log: + { + "authorizationInfo": [ + { + "granted": true, + "permission": "io.k8s.core.v1.pods.create", + "resource": "core/v1/namespaces/default/pods/nginx-test" + } + ], + "protoPayload": { + "methodName": "io.k8s.core.v1.pods.create", + "request": { + "spec": { + "hostPID": false, + } + } + } + } diff --git a/simple_rules/gcp_k8s_rules/gcp_k8s_service_type_node_port_deployed_simple.yml b/simple_rules/gcp_k8s_rules/gcp_k8s_service_type_node_port_deployed_simple.yml new file mode 100644 index 000000000..0ffce2092 --- /dev/null +++ b/simple_rules/gcp_k8s_rules/gcp_k8s_service_type_node_port_deployed_simple.yml @@ -0,0 +1,290 @@ +AnalysisType: rule +RuleID: "GCP.K8S.Service.Type.NodePort.Deployed.Simple" +DisplayName: "GCP K8S Service Type NodePort Deployed" +Enabled: true +LogTypes: + - GCP.AuditLog +Severity: High +Detection: + - All: + - KeyPath: protoPayload.methodName + Condition: Contains + Value: io.k8s.core.v1.services.create + - KeyPath: protoPayload.authorizationInfo[*].granted + Condition: Contains + Value: true + - KeyPath: protoPayload.authorizationInfo[*].permission + Condition: Contains + Value: io.k8s.core.v1.services.create + - KeyPath: protoPayload.response.status + Condition: DoesNotEqual + Value: Failure + - KeyPath: protoPayload.request.spec.type + Condition: Equals + Value: NodePort +AlertTitle: "[GCP]: [{protoPayload.authenticationInfo.principalEmail}] created NodePort service in +project [{resource.labels.project_id}]" +AlertContext: + - KeyName: project + KeyValue: + KeyPath: resource.labels.project_id + - KeyName: principal + KeyValue: + KeyPath: protoPayload.authenticationInfo.principalEmail + - KeyName: caller_ip + KeyValue: + KeyPath: protoPayload.requestMetadata.callerIP + - KeyName: methodName + KeyValue: + KeyPath: protoPayload.methodName + - KeyName: resourceName + KeyValue: + KeyPath: protoPayload.resourceName + - KeyName: serviceName + KeyValue: + KeyPath: protoPayload.serviceName + - KeyName: request_spec + KeyValue: + KeyPath: protoPayload.request.spec +Description: > + This detection monitors for any kubernetes service deployed with type node port. A Node Port service allows + an attacker to expose a set of pods hosting the service to the internet by opening their port and redirecting + traffic here. This can be used to bypass network controls and intercept traffic, creating a direct line to + the outside network. +Runbook: > + Investigate the reason of creating NodePort service. Advise that it is discouraged practice. + Create ticket if appropriate. +Reference: https://kubernetes.io/docs/tutorials/kubernetes-basics/expose/expose-intro/ +Reports: + MITRE ATT&CK: + - T1190 # Exploit Public-Facing Application +Tests: + - + Name: Service Created + ExpectedResult: true + Log: + { + "logName": "projects/some-project/logs/cloudaudit.googleapis.com%2Factivity", + "protoPayload": { + "at_sign_type": "type.googleapis.com/google.cloud.audit.AuditLog", + "authenticationInfo": { + "principalEmail": "some.user@company.com" + }, + "authorizationInfo": [ + { + "granted": true, + "permission": "io.k8s.core.v1.services.create", + "resource": "core/v1/namespaces/default/services/test-ns" + } + ], + "methodName": "io.k8s.core.v1.services.create", + "request": { + "@type": "core.k8s.io/v1.Service", + "apiVersion": "v1", + "kind": "Service", + "spec": { + "ports": [ + { + "name": "5678-8080", + "port": 5678, + "protocol": "TCP", + "targetPort": 8080 + } + ], + "type": "NodePort" + }, + }, + "requestMetadata": { + "callerIP": "1.2.3.4", + "callerSuppliedUserAgent": "kubectl/v1.28.2 (darwin/amd64) kubernetes/89a4ea3" + }, + "resourceName": "core/v1/namespaces/default/services/test-ns", + "response": { + "@type": "core.k8s.io/v1.Service", + "apiVersion": "v1", + "kind": "Service", + "metadata": { + "creationTimestamp": "2024-02-19T12:02:21Z", + "name": "test-ns", + "namespace": "default", + "resourceVersion": "15036073", + "uid": "28758fe1-534a-4705-bcc2-12eeac6f11a4" + }, + "spec": { + "clusterIP": "2.3.4.5", + "clusterIPs": [ + "2.3.4.5" + ], + "ports": [ + { + "name": "5678-8080", + "nodePort": 32361, + "port": 5678, + "protocol": "TCP", + "targetPort": 8080 + } + ], + "type": "NodePort" + }, + }, + "serviceName": "k8s.io", + "status": { } + }, + "receiveTimestamp": "2024-02-19 12:02:39.542633547", + "resource": { + "labels": { + "cluster_name": "some-project-cluster", + "location": "us-west1", + "project_id": "some-project" + }, + "type": "k8s_cluster" + }, + "timestamp": "2024-02-19 12:02:22.057586000" + } + - + Name: Error Creating Service + 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": "some.user@company.com" + }, + "authorizationInfo": [ + { + "granted": true, + "permission": "io.k8s.core.v1.services.create", + "resource": "core/v1/namespaces/default/services/test-ns" + } + ], + "methodName": "io.k8s.core.v1.services.create", + "request": { + "@type": "core.k8s.io/v1.Service", + "apiVersion": "v1", + "kind": "Service", + "spec": { + "ports": [ + { + "name": "5678-8080", + "port": 5678, + "protocol": "TCP", + "targetPort": 8080 + } + ], + "type": "NodePort" + }, + }, + "requestMetadata": { + "callerIP": "1.2.3.4", + "callerSuppliedUserAgent": "kubectl/v1.28.2 (darwin/amd64) kubernetes/89a4ea3" + }, + "resourceName": "core/v1/namespaces/default/services/test-ns", + "response": { + "@type": "core.k8s.io/v1.Status", + "apiVersion": "v1", + "code": 409, + "details": { + "kind": "services", + "name": "test-ns" + }, + "kind": "Status", + "message": "services \"test-ns\" already exists", + "metadata": { }, + "reason": "AlreadyExists", + "status": "Failure" + }, + "serviceName": "k8s.io", + "status": { + "code": 10, + "message": "services \"test-ns\" already exists" + } + }, + "receiveTimestamp": "2024-02-20 13:47:46.955496128", + "resource": { + "labels": { + "cluster_name": "some-project-cluster", + "location": "us-west1", + "project_id": "some-project" + }, + "type": "k8s_cluster" + }, + "timestamp": "2024-02-20 13:47:43.126037000" + } + - + Name: No Permission Granted + 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": "some.user@company.com" + }, + "authorizationInfo": [ + { + "granted": false, + "permission": "io.k8s.core.v1.services.create", + "resource": "core/v1/namespaces/default/services/test-ns" + } + ], + "methodName": "io.k8s.core.v1.services.create", + "request": { + "@type": "core.k8s.io/v1.Service", + "apiVersion": "v1", + "kind": "Service", + "spec": { + "ports": [ + { + "name": "5678-8080", + "port": 5678, + "protocol": "TCP", + "targetPort": 8080 + } + ], + "type": "NodePort" + }, + }, + "requestMetadata": { + "callerIP": "1.2.3.4", + "callerSuppliedUserAgent": "kubectl/v1.28.2 (darwin/amd64) kubernetes/89a4ea3" + }, + "resourceName": "core/v1/namespaces/default/services/test-ns", + "spec": { + "clusterIP": "2.3.4.5", + "clusterIPs": [ + "2.3.4.5" + ], + "externalTrafficPolicy": "Cluster", + "internalTrafficPolicy": "Cluster", + "ipFamilies": [ + "IPv4" + ], + "ipFamilyPolicy": "SingleStack", + "ports": [ + { + "name": "5678-8080", + "nodePort": 32361, + "port": 5678, + "protocol": "TCP", + "targetPort": 8080 + } + ], + "type": "NodePort" + }, + }, + "serviceName": "k8s.io", + "status": { }, + "receiveTimestamp": "2024-02-19 12:02:39.542633547", + "resource": { + "labels": { + "cluster_name": "some-project-cluster", + "location": "us-west1", + "project_id": "some-project" + }, + "type": "k8s_cluster" + }, + "timestamp": "2024-02-19 12:02:22.057586000" + } diff --git a/simple_rules/gcp_k8s_rules/gcp_kubernetes_new_daemonset_deployed_simple.yml b/simple_rules/gcp_k8s_rules/gcp_kubernetes_new_daemonset_deployed_simple.yml index 96155e9a6..b62f61186 100644 --- a/simple_rules/gcp_k8s_rules/gcp_kubernetes_new_daemonset_deployed_simple.yml +++ b/simple_rules/gcp_k8s_rules/gcp_kubernetes_new_daemonset_deployed_simple.yml @@ -1,5 +1,5 @@ AnalysisType: rule -RuleID: "GCP.K8s.New.Daemonset.Deployed" +RuleID: "GCP.K8s.New.Daemonset.Deployed.Simple" DisplayName: "GCP K8s New Daemonset Deployed" Description: "Detects Daemonset creation in GCP Kubernetes clusters." Enabled: true diff --git a/simple_rules/netskope_rules/netskope_admin_logged_out_simple.yml b/simple_rules/netskope_rules/netskope_admin_logged_out_simple.yml index b0e6cf9c2..2d5ece611 100644 --- a/simple_rules/netskope_rules/netskope_admin_logged_out_simple.yml +++ b/simple_rules/netskope_rules/netskope_admin_logged_out_simple.yml @@ -1,5 +1,5 @@ AnalysisType: rule -RuleID: "Netskope.AdminLoggedOutLoginFailures" +RuleID: "Netskope.AdminLoggedOutLoginFailures.Simple" DisplayName: "Admin logged out because of successive login failures" AlertTitle: "Admin [{user}] was logged out because of successive login failures" Detection: diff --git a/simple_rules/netskope_rules/netskope_admin_user_change_simple.yml b/simple_rules/netskope_rules/netskope_admin_user_change_simple.yml index c04fbad25..65a31ccb5 100644 --- a/simple_rules/netskope_rules/netskope_admin_user_change_simple.yml +++ b/simple_rules/netskope_rules/netskope_admin_user_change_simple.yml @@ -1,5 +1,5 @@ AnalysisType: rule -RuleID: "Netskope.AdminUserChange" +RuleID: "Netskope.AdminUserChange.Simple" DisplayName: "An administrator account was created, deleted, or modified." AlertTitle: "User [{user}] performed [{audit_log_event}]" Detection: @@ -93,4 +93,4 @@ Tests: "type": "admin_audit_logs", "ur_normalized": "service-account", "user": "service-account" - } \ No newline at end of file + } diff --git a/simple_rules/netskope_rules/netskope_many_deletes_simple.yml b/simple_rules/netskope_rules/netskope_many_deletes_simple.yml index 93dc7abdf..50fc7ed53 100644 --- a/simple_rules/netskope_rules/netskope_many_deletes_simple.yml +++ b/simple_rules/netskope_rules/netskope_many_deletes_simple.yml @@ -1,5 +1,5 @@ AnalysisType: rule -RuleID: "Netskope.ManyDeletes" +RuleID: "Netskope.ManyDeletes.Simple" DisplayName: "Netskope Many Objects Deleted" AlertTitle: "[{user}] deleted many objects in a short time" Detection: diff --git a/simple_rules/netskope_rules/netskope_personnel_action_simple.yml b/simple_rules/netskope_rules/netskope_personnel_action_simple.yml index cd3b2f389..c3cc7dda5 100644 --- a/simple_rules/netskope_rules/netskope_personnel_action_simple.yml +++ b/simple_rules/netskope_rules/netskope_personnel_action_simple.yml @@ -1,5 +1,5 @@ AnalysisType: rule -RuleID: "Netskope.NetskopePersonnelActivity" +RuleID: "Netskope.NetskopePersonnelActivity.Simple" DisplayName: "Action Performed by Netskope Personnel" AlertTitle: "Action [{audit_log_event}] performed by Netskope personnel [{user}]" Detection: diff --git a/simple_rules/netskope_rules/netskope_unauthorized_api_calls_simple.yml b/simple_rules/netskope_rules/netskope_unauthorized_api_calls_simple.yml index 1a1896f6b..49667883e 100644 --- a/simple_rules/netskope_rules/netskope_unauthorized_api_calls_simple.yml +++ b/simple_rules/netskope_rules/netskope_unauthorized_api_calls_simple.yml @@ -1,5 +1,5 @@ AnalysisType: rule -RuleID: "Netskope.UnauthorizedAPICalls" +RuleID: "Netskope.UnauthorizedAPICalls.Simple" DisplayName: "Netskope Many Unauthorized API Calls" AlertTitle: "Many unauthorized API calls from user [{user}]" Detection: