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.

Query · python

from panther_gcp_helpers import gcp_alert_context


def rule(event):
    authorization_info = event.deep_walk("protoPayload", "authorizationInfo")
    if not authorization_info:
        return False
    for auth in authorization_info:
        if (
            auth.get("permission")
            in ["io.k8s.batch.v1.cronjobs.create", "io.k8s.batch.v1.cronjobs.update"]
            and auth.get("granted") is True
        ):
            return True
    return False


def title(event):
    actor = event.deep_get(
        "protoPayload", "authenticationInfo", "principalEmail", default="<ACTOR_NOT_FOUND>"
    )
    operation = event.deep_get("protoPayload", "methodName", default="<OPERATION_NOT_FOUND>")
    project_id = event.deep_get("resource", "labels", "project_id", default="<PROJECT_NOT_FOUND>")

    return f"[GCP]: [{actor}] performed [{operation}] on project [{project_id}]"


def alert_context(event):
    return gcp_alert_context(event)

Analyst notes

Investigate a reason of creating or modifying a cron job in GKE. Create ticket if appropriate.

Raw source GCP GKE Kubernetes Cron Job Created Or Modified · Panther Python
Esc
Published by panther-labs/panther-analysis ↗, licensed under Apache 2.0 ↗. Reproduced here unmodified.
AnalysisType: rule
RuleID: "GCP.GKE.Kubernetes.Cron.Job.Created.Or.Modified"
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
Filename: gcp_k8s_cron_job_created_or_modified.py
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
Runbook: Investigate a reason of creating or modifying a cron job in GKE. Create ticket if appropriate.
Reports:
  MITRE ATT&CK:
    - TA0003:T1053.003 # Scheduled Task/Job: Cron
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"


# ------ paired body: gcp_k8s_cron_job_created_or_modified.py ------

from panther_gcp_helpers import gcp_alert_context


def rule(event):
    authorization_info = event.deep_walk("protoPayload", "authorizationInfo")
    if not authorization_info:
        return False
    for auth in authorization_info:
        if (
            auth.get("permission")
            in ["io.k8s.batch.v1.cronjobs.create", "io.k8s.batch.v1.cronjobs.update"]
            and auth.get("granted") is True
        ):
            return True
    return False


def title(event):
    actor = event.deep_get(
        "protoPayload", "authenticationInfo", "principalEmail", default="<ACTOR_NOT_FOUND>"
    )
    operation = event.deep_get("protoPayload", "methodName", default="<OPERATION_NOT_FOUND>")
    project_id = event.deep_get("resource", "labels", "project_id", default="<PROJECT_NOT_FOUND>")

    return f"[GCP]: [{actor}] performed [{operation}] on project [{project_id}]"


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.