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)