GCP Snapshot Creation Detection


Description

This rule detects when someone with an unexpected email domain creates a snapshot of a Compute Disk.

Query · python

from panther_gcp_helpers import gcp_alert_context

EXPECTED_DOMAIN = "@your-domain.tld"


def rule(event):
    if event.deep_get("protoPayload", "response", "error"):
        return False

    method = event.deep_get("protoPayload", "methodName", default="METHOD_NOT_FOUND")
    if method != "v1.compute.snapshots.insert":
        return False

    email = event.deep_get("protoPayload", "authenticationInfo", "principalEmail", default="")
    if not email.endswith(EXPECTED_DOMAIN):
        return True

    return False


def title(event):
    actor = event.deep_get(
        "protoPayload", "authenticationInfo", "principalEmail", default="<ACTOR_NOT_FOUND>"
    )
    project = event.deep_get("resource", "labels", "project_id", default="<PROJECT_NOT_FOUND>")
    return f"[GCP]: Unexpected domain [{actor}] created a snapshot on project [{project}]"


def alert_context(event):
    return gcp_alert_context(event)

Analyst notes

Investigate the snapshot creation to ensure it was authorized. Unauthorized snapshot creation can lead to data exfiltration.

Raw source GCP Snapshot Creation Detection · Panther Python
Esc
Published by panther-labs/panther-analysis ↗, licensed under Apache 2.0 ↗. Reproduced here unmodified.
AnalysisType: rule
DedupPeriodMinutes: 60
DisplayName: GCP Snapshot Creation Detection
Enabled: false
Filename: gcp_snapshot_insert.py
RuleID: "GCP.Compute.Snapshot.UnexpectedDomain"
Severity: Medium
LogTypes:
  - GCP.AuditLog
Tags:
  - Configuration Required
Description: >
  This rule detects when someone with an unexpected email domain creates a snapshot of a Compute Disk.
Runbook: >
  Investigate the snapshot creation to ensure it was authorized. Unauthorized snapshot creation can lead to data exfiltration.
Reference: https://cloud.google.com/compute/docs/disks/snapshots
Tests:
  - Name: Snapshot creation by user with unexpected domain
    LogType: GCP.AuditLog
    ExpectedResult: true
    Log:
      {
        "insertId": "1abcd23efg456",
        "logName": "projects/test-project/logs/cloudaudit.googleapis.com%2Factivity",
        "protoPayload": {
          "@type": "type.googleapis.com/google.cloud.audit.AuditLog",
          "authenticationInfo": {
            "principalEmail": "user@unexpected-domain.com"
          },
          "methodName": "v1.compute.snapshots.insert",
          "resourceName": "projects/test-project/global/snapshots/snapshot-1",
          "serviceName": "compute.googleapis.com"
        },
        "resource": {
          "labels": {
            "project_id": "test-project"
          },
          "type": "gce_snapshot"
        },
        "severity": "NOTICE",
        "timestamp": "2023-10-01T12:34:56.789Z"
      }
  - Name: Snapshot creation by user with expected domain
    LogType: GCP.AuditLog
    ExpectedResult: false
    Log:
      {
        "insertId": "2hijk34lmn789",
        "logName": "projects/test-project/logs/cloudaudit.googleapis.com%2Factivity",
        "protoPayload": {
          "@type": "type.googleapis.com/google.cloud.audit.AuditLog",
          "authenticationInfo": {
            "principalEmail": "user@your-domain.tld"
          },
          "methodName": "v1.compute.snapshots.insert",
          "resourceName": "projects/test-project/global/snapshots/snapshot-2",
          "serviceName": "compute.googleapis.com"
        },
        "resource": {
          "labels": {
            "project_id": "test-project"
          },
          "type": "gce_snapshot"
        },
        "severity": "NOTICE",
        "timestamp": "2023-10-01T12:45:56.789Z"
      }

# ------ paired body: gcp_snapshot_insert.py ------

from panther_gcp_helpers import gcp_alert_context

EXPECTED_DOMAIN = "@your-domain.tld"


def rule(event):
    if event.deep_get("protoPayload", "response", "error"):
        return False

    method = event.deep_get("protoPayload", "methodName", default="METHOD_NOT_FOUND")
    if method != "v1.compute.snapshots.insert":
        return False

    email = event.deep_get("protoPayload", "authenticationInfo", "principalEmail", default="")
    if not email.endswith(EXPECTED_DOMAIN):
        return True

    return False


def title(event):
    actor = event.deep_get(
        "protoPayload", "authenticationInfo", "principalEmail", default="<ACTOR_NOT_FOUND>"
    )
    project = event.deep_get("resource", "labels", "project_id", default="<PROJECT_NOT_FOUND>")
    return f"[GCP]: Unexpected domain [{actor}] created a snapshot on project [{project}]"


def alert_context(event):
    return gcp_alert_context(event)

Detection rules belong to the projects that publish them and remain under their own licenses. This site indexes and links to them; it claims no rights in them.