Detection rules › Elastic

GKE Pod Exec Sensitive File or Credential Path Access

Status
production
Severity
high
Time window
6m
Author
Elastic
Source
github.com/elastic/detection-rules

Detects successful GKE pod exec sessions where the executed command references high-value host or in-cluster paths: mounted service account or platform tokens, kubelet and control-plane configuration areas, host identity stores, root or home credential directories, common private-key and keystore extensions, process environment dumps, and configuration filenames suggestive of embedded secrets. Attackers with pods/exec often use these one-liners to steal credentials before lateral movement or privilege escalation. A narrow exclusion ignores benign resolv.conf reads. GKE records the command in gcp.audit.labels.command.gke.io/command when an explicit command is passed to exec.

Known false positives

  • Break-glass debugging or vendor diagnostics may cat credential-adjacent paths. Baseline approved operators and automation identities, then expand client.user.email exclusions as needed.

MITRE ATT&CK coverage

Telemetry coverage

Rules detecting the same action

These rules filter on the same operation.

Rule body

[metadata]
creation_date = "2026/07/15"
integration = ["gcp"]
maturity = "production"
updated_date = "2026/07/15"

[rule]
author = ["Elastic"]
description = """
Detects successful GKE pod exec sessions where the executed command references high-value host or in-cluster paths:
mounted service account or platform tokens, kubelet and control-plane configuration areas, host identity stores, root
or home credential directories, common private-key and keystore extensions, process environment dumps, and configuration
filenames suggestive of embedded secrets. Attackers with pods/exec often use these one-liners to steal credentials
before lateral movement or privilege escalation. A narrow exclusion ignores benign resolv.conf reads. GKE records the
command in gcp.audit.labels.command.gke.io/command when an explicit command is passed to exec.
"""
false_positives = [
    """
    Break-glass debugging or vendor diagnostics may cat credential-adjacent paths. Baseline approved operators and
    automation identities, then expand client.user.email exclusions as needed.
    """,
]
from = "now-6m"
index = ["logs-gcp.audit-*"]
language = "kuery"
license = "Elastic License v2"
name = "GKE Pod Exec Sensitive File or Credential Path Access"
note = """## Triage and analysis

### Investigating GKE Pod Exec Sensitive File or Credential Path Access

This alert fires when a successful pods/exec API call includes a command matching sensitive path or filename
patterns. Review `gcp.audit.labels.command.gke.io/command` for the reconstructed command string.

### Possible investigation steps

- Identify the actor (`client.user.email`), source IP, and user agent for the exec caller.
- Map `gcp.audit.resource_name` (namespace/pod) to a workload owner, image, and change history.
- Correlate adjacent activity from the same identity: secret reads, TokenRequest, RBAC writes, or additional execs.
- If host-level paths appear, determine whether the workload is privileged, uses hostPath, or runs on break-glass nodes.

### False positive analysis

- Diagnostic images and vendor agents sometimes read kubeconfig-like or credential paths; baseline stable automation.
- Training containers that deliberately demonstrate passwd reads can trigger; scope exceptions to those namespaces.

### Response and remediation

- If malicious, end the exec session, isolate the pod or node, rotate credentials that could have been read, and
  tighten pods/exec RBAC and admission controls.
"""
setup = "The GCP Fleet integration with GKE audit logs enabled is required to be compatible with this rule."
references = [
    "https://stratus-red-team.cloud/attack-techniques/kubernetes/k8s.credential-access.steal-serviceaccount-token/",
]
risk_score = 73
rule_id = "0fc705f5-544e-4786-8acc-c73cd74e77cf"
severity = "high"
tags = [
    "Domain: Cloud",
    "Domain: Kubernetes",
    "Data Source: GCP",
    "Data Source: GCP Audit Logs",
    "Data Source: Google Cloud Platform",
    "Use Case: Threat Detection",
    "Tactic: Credential Access",
    "Tactic: Execution",
    "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "query"

query = '''
data_stream.dataset:gcp.audit and service.name:"k8s.io" and event.outcome:success and
event.type:start and
event.action:("io.k8s.core.v1.pods.exec.create" or "io.k8s.core.v1.pods.exec.get") and
gcp.audit.labels.command.gke.io/command:(
  (
    *.jks* or *.key* or *.keystore* or *.p12* or *.pem* or
    */etc/kubernetes/* or */etc/passwd* or */etc/shadow* or */etc/sudoers* or
    */home/*/.aws* or */home/*/.azure* or */home/*/.config/gcloud* or */home/*/.kube* or */home/*/.ssh* or
    */proc/*/environ* or
    */root/.aws* or */root/.azure* or */root/.config/gcloud* or */root/.kube* or */root/.ssh* or
    */var/lib/kubelet/* or */var/run/secrets/* or
    */etc/*.conf* and (*credential* or *key* or *password* or *secret* or *token*)
  ) and not */etc/resolv.conf*
)
'''

[[rule.threat]]
framework = "MITRE ATT&CK"

[[rule.threat.technique]]
id = "T1552"
name = "Unsecured Credentials"
reference = "https://attack.mitre.org/techniques/T1552/"

[[rule.threat.technique.subtechnique]]
id = "T1552.001"
name = "Credentials In Files"
reference = "https://attack.mitre.org/techniques/T1552/001/"

[[rule.threat.technique.subtechnique]]
id = "T1552.007"
name = "Container API"
reference = "https://attack.mitre.org/techniques/T1552/007/"

[rule.threat.tactic]
id = "TA0006"
name = "Credential Access"
reference = "https://attack.mitre.org/tactics/TA0006/"

[[rule.threat]]
framework = "MITRE ATT&CK"

[[rule.threat.technique]]
id = "T1609"
name = "Container Administration Command"
reference = "https://attack.mitre.org/techniques/T1609/"

[rule.threat.tactic]
id = "TA0002"
name = "Execution"
reference = "https://attack.mitre.org/tactics/TA0002/"

[rule.investigation_fields]
field_names = [
    "@timestamp",
    "client.user.email",
    "source.ip",
    "user_agent.original",
    "event.action",
    "event.outcome",
    "event.type",
    "gcp.audit.labels.command.gke.io/command",
    "gcp.audit.resource_name",
    "data_stream.namespace",
]

Stages and Predicates

Stage 1: query

data_stream.dataset:gcp.audit and service.name:"k8s.io" and event.outcome:success and
event.type:start and
event.action:("io.k8s.core.v1.pods.exec.create" or "io.k8s.core.v1.pods.exec.get") and
gcp.audit.labels.command.gke.io/command:(
  (
    *.jks* or *.key* or *.keystore* or *.p12* or *.pem* or
    */etc/kubernetesetc/passwd* or */etc/shadow* or */etc/sudoers* or
    */homehomehomehomehome/*/.ssh* or
    */proc/*/environ* or
    */root/.aws* or */root/.azure* or */root/.config/gcloud* or */root/.kube* or */root/.ssh* or
    */var/lib/kubeletvar/run/secrets/* or
    */etc/*.conf* and (*credential* or *key* or *password* or *secret* or *token*)
  ) and not */etc/resolv.conf*
)

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
gcp.audit.labels.command.gke.io/commandmatch/etc/resolv.confexcludes:gcp.audit.labels.command.gke.io/command field:"gcp.audit.labels.command.gke.io/command" value:"/etc/resolv.conf"

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
data_stream.dataseteq
  • gcp.audit
field:"data_stream.dataset" kind:eq value:"gcp.audit"
event.actionin
  • io.k8s.core.v1.pods.exec.create
  • io.k8s.core.v1.pods.exec.get
field:"EventType" kind:in
event.outcomeeq
  • success
field:"event.outcome" kind:eq value:"success"
event.typeeq
  • start
field:"event.type" kind:eq value:"start"
gcp.audit.labels.command.gke.io/commandwildcard
  • *.jks*
  • *.key*
  • *.keystore*
  • *.p12*
  • *.pem*
  • */etc/*.conf*
  • */etc/kubernetes/*
  • */etc/passwd*
  • */etc/shadow*
  • */etc/sudoers*
  • */home/*/.aws*
  • */home/*/.azure*
  • */home/*/.config/gcloud*
  • */home/*/.kube*
  • */home/*/.ssh*
  • */proc/*/environ*
  • */root/.aws*
  • */root/.azure*
  • */root/.config/gcloud*
  • */root/.kube*
  • */root/.ssh*
  • */var/lib/kubelet/*
  • */var/run/secrets/*
  • *credential*
  • *key*
  • *password*
  • *secret*
  • *token*
field:"gcp.audit.labels.command.gke.io/command" kind:wildcard
service.nameeq
  • k8s.io
field:"ServiceName" kind:eq value:"k8s.io"