Detection rules › Elastic
Kubernetes Pod Exec Sensitive File or Credential Path Access
Detects Kubernetes pod exec sessions whose decoded command line references high-value host or in-cluster paths and material types: mounted service account or platform tokens, kubelet and control-plane configuration areas, host identity stores, root dot-directories for cloud and kubeconfig material, common private-key and keystore extensions, process environment dumps, and configuration filenames suggestive of embedded secrets. The intent is to catch interactive or scripted access that often precedes lateral movement, privilege escalation, or credential theft from the node or workload boundary. A narrow exclusion ignores benign reads of resolv.conf. The query also labels an access_type bucket to speed triage without altering the detection predicates you validated.
MITRE ATT&CK coverage
| Tactic | Techniques |
|---|---|
| Execution | T1609 Container Administration Command |
| Credential Access | T1552.001 Unsecured Credentials: Credentials In Files, T1552.007 Unsecured Credentials: Container API |
Event coverage
| Provider | Event | Title |
|---|---|---|
| Kubernetes-pods | any-pods | any verb on pods (synthetic aggregation) |
Rules detecting the same action
Other rules on this platform that filter on the same API call or operation.
Rule body elastic
[metadata]
creation_date = "2026/04/23"
integration = ["kubernetes"]
maturity = "production"
updated_date = "2026/04/23"
[rule]
author = ["Elastic"]
description = """
Detects Kubernetes pod exec sessions whose decoded command line references high-value host or in-cluster paths and
material types: mounted service account or platform tokens, kubelet and control-plane configuration areas, host
identity stores, root dot-directories for cloud and kubeconfig material, common private-key and keystore extensions,
process environment dumps, and configuration filenames suggestive of embedded secrets. The intent is to catch
interactive or scripted access that often precedes lateral movement, privilege escalation, or credential theft from
the node or workload boundary. A narrow exclusion ignores benign reads of resolv.conf. The query also labels an
access_type bucket to speed triage without altering the detection predicates you validated.
"""
from = "now-6m"
interval = "5m"
language = "esql"
license = "Elastic License v2"
name = "Kubernetes Pod Exec Sensitive File or Credential Path Access"
note = """## Triage and analysis
### Investigating Kubernetes Pod Exec Sensitive File or Credential Path Access
This alert ties Kubernetes audit exec events to reconstructed command text that matches sensitive path and filename
patterns. Use the Esql.access_type field to prioritize: IRSA token paths, default Kubernetes service account tokens,
other mounted secrets, certificates and keystores, Kubernetes static config, kubelet state, host passwd or shadow,
user home credential stores, and proc environ scraping.
### Possible investigation steps
- Identify the Kubernetes user, groups, impersonation, source IP, and user agent for the exec caller.
- Map objectRef namespace, pod, and container to an owning team, image digest, and change history.
- Compare Esql.executed_command against known runbooks; capture follow-on audit activity such as additional execs,
secret reads at the API layer, or RBAC changes.
- If host-level paths appear, determine whether the workload runs privileged, with hostPath mounts, or on nodes where
break-glass access is expected.
### False positive analysis
- Diagnostic images and vendor agents sometimes cat resolv.conf or kubeconfig-like paths; the rule excludes resolv.conf
but other matches may still be legitimate—baseline stable automation identities.
- Training containers that deliberately demonstrate passwd reads can trigger; scope exceptions to those images and
namespaces.
### Response and remediation
- If malicious, end the exec session, isolate the pod or node, rotate any credentials that could have been read,
review and tighten pods exec RBAC and admission controls, and inspect for persistence added after the session.
"""
references = [
"https://attack.mitre.org/techniques/T1552/001/",
"https://attack.mitre.org/techniques/T1552/007/",
]
risk_score = 73
rule_id = "b2c3d4e5-f6a7-4890-b1c2-d3e4f5a60789"
severity = "high"
tags = [
"Data Source: Kubernetes",
"Domain: Kubernetes",
"Use Case: Threat Detection",
"Tactic: Credential Access",
"Tactic: Execution",
"Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "esql"
query = '''
from logs-kubernetes.audit_logs-* metadata _id, _index, _version
| WHERE kubernetes.audit.objectRef.subresource == "exec"
AND kubernetes.audit.requestURI LIKE "*command=*"
| EVAL decoded_uri = URL_DECODE(kubernetes.audit.requestURI)
| GROK decoded_uri "%{DATA}/exec\\?%{DATA:raw_commands}&(?:container|stdin|stdout|stderr)=%{GREEDYDATA}"
| EVAL command = REPLACE(raw_commands, "command=", "")
| EVAL command = REPLACE(command, "&", " ")
| EVAL Esql.executed_command = REPLACE(command, "\\+", " ")
| WHERE Esql.executed_command IS NOT NULL
AND Esql.executed_command RLIKE """.*(/var/run/secrets/|/etc/kubernetes/|/var/lib/kubelet/|/etc/shadow|/etc/passwd|/etc/sudoers|(/root|/home/[^/]+)/\.(ssh|aws|azure|kube|config/gcloud)|\.p12|\.pem|\.key|\.jks|\.keystore|/etc/.*\.conf.*(password|secret|key|token|credential)|/proc/.*/environ).*"""
AND NOT Esql.executed_command RLIKE """.*/etc/resolv\.conf.*"""
| EVAL Esql.access_type = CASE(
Esql.executed_command RLIKE """.*/var/run/secrets/eks\.amazonaws\.com.*""", "AWS_IRSA_TOKEN",
Esql.executed_command RLIKE """.*/var/run/secrets/azure/tokens/.*""", "AZURE_WORKLOAD_IDENTITY_TOKEN",
Esql.executed_command RLIKE """.*/var/run/secrets/tokens/gcp-ksa/.*""", "GCP_WORKLOAD_IDENTITY_TOKEN",
Esql.executed_command RLIKE """.*/var/run/secrets/kubernetes\.io/serviceaccount/token.*""", "K8S_SA_TOKEN",
Esql.executed_command RLIKE """.*/var/run/secrets/.*""", "MOUNTED_SECRET",
Esql.executed_command RLIKE """.*\.(p12|pem|key|jks|keystore).*""", "CERTIFICATE_OR_KEY",
Esql.executed_command RLIKE """.*/etc/kubernetes/.*""", "K8S_CONFIG",
Esql.executed_command RLIKE """.*/var/lib/kubelet/.*""", "KUBELET_CONFIG",
Esql.executed_command RLIKE """.*/etc/shadow.*""", "HOST_CREDENTIALS",
Esql.executed_command RLIKE """.*/etc/passwd.*""", "USER_ENUMERATION",
Esql.executed_command RLIKE """.*/etc/sudoers.*""", "SUDOERS_ACCESS",
Esql.executed_command RLIKE """.*(/root|/home)/\.(ssh|aws|azure|kube|config/gcloud).*""", "USER_CREDENTIALS",
Esql.executed_command RLIKE """.*/proc/.*/environ.*""", "PROCESS_ENV_SECRETS",
Esql.executed_command RLIKE """.*/etc/.*\.conf.*(password|secret|key|token|credential).*""", "EMBEDDED_CONFIG_SECRET",
"OTHER_SENSITIVE"
)
| KEEP *
'''
[[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/"
Stages and Predicates
Stage 1: from
from logs-kubernetes.audit_logs-* metadata _id, _index, _version
Stage 2: where
| WHERE kubernetes.audit.objectRef.subresource == "exec"
AND kubernetes.audit.requestURI LIKE "*command=*"
Stage 3: eval
| EVAL decoded_uri = URL_DECODE(kubernetes.audit.requestURI)
Stage 4: grok
| GROK decoded_uri "%{DATA}/exec\\?%{DATA:raw_commands}&(?:container|stdin|stdout|stderr)=%{GREEDYDATA}"
Stage 5: eval
| EVAL command = REPLACE(raw_commands, "command=", "")
Stage 6: eval
| EVAL command = REPLACE(command, "&", " ")
Stage 7: eval
| EVAL Esql.executed_command = REPLACE(command, "\\+", " ")
Stage 8: where
| WHERE Esql.executed_command IS NOT NULL
AND Esql.executed_command RLIKE """.*(/var/run/secrets/|/etc/kubernetes/|/var/lib/kubelet/|/etc/shadow|/etc/passwd|/etc/sudoers|(/root|/home/[^/]+)/\.(ssh|aws|azure|kube|config/gcloud)|\.p12|\.pem|\.key|\.jks|\.keystore|/etc/.*\.conf.*(password|secret|key|token|credential)|/proc/.*/environ).*"""
AND NOT Esql.executed_command RLIKE """.*/etc/resolv\.conf.*"""
Stage 9: eval
| EVAL Esql.access_type = CASE(
Esql.executed_command RLIKE """.*/var/run/secrets/eks\.amazonaws\.com.*""", "AWS_IRSA_TOKEN",
Esql.executed_command RLIKE """.*/var/run/secrets/azure/tokens/.*""", "AZURE_WORKLOAD_IDENTITY_TOKEN",
Esql.executed_command RLIKE """.*/var/run/secrets/tokens/gcp-ksa/.*""", "GCP_WORKLOAD_IDENTITY_TOKEN",
Esql.executed_command RLIKE """.*/var/run/secrets/kubernetes\.io/serviceaccount/token.*""", "K8S_SA_TOKEN",
Esql.executed_command RLIKE """.*/var/run/secrets/.*""", "MOUNTED_SECRET",
Esql.executed_command RLIKE """.*\.(p12|pem|key|jks|keystore).*""", "CERTIFICATE_OR_KEY",
Esql.executed_command RLIKE """.*/etc/kubernetes/.*""", "K8S_CONFIG",
Esql.executed_command RLIKE """.*/var/lib/kubelet/.*""", "KUBELET_CONFIG",
Esql.executed_command RLIKE """.*/etc/shadow.*""", "HOST_CREDENTIALS",
Esql.executed_command RLIKE """.*/etc/passwd.*""", "USER_ENUMERATION",
Esql.executed_command RLIKE """.*/etc/sudoers.*""", "SUDOERS_ACCESS",
Esql.executed_command RLIKE """.*(/root|/home)/\.(ssh|aws|azure|kube|config/gcloud).*""", "USER_CREDENTIALS",
Esql.executed_command RLIKE """.*/proc/.*/environ.*""", "PROCESS_ENV_SECRETS",
Esql.executed_command RLIKE """.*/etc/.*\.conf.*(password|secret|key|token|credential).*""", "EMBEDDED_CONFIG_SECRET",
"OTHER_SENSITIVE"
)
Esql.access_type =Esql.executed_command RLIKE """.*/var/run/secrets/eks\.amazonaws\.com.*""""AWS_IRSA_TOKEN"Esql.executed_command RLIKE """.*/var/run/secrets/azure/tokens/.*""""AZURE_WORKLOAD_IDENTITY_TOKEN"Esql.executed_command RLIKE """.*/var/run/secrets/tokens/gcp-ksa/.*""""GCP_WORKLOAD_IDENTITY_TOKEN"Esql.executed_command RLIKE """.*/var/run/secrets/kubernetes\.io/serviceaccount/token.*""""K8S_SA_TOKEN"Esql.executed_command RLIKE """.*/var/run/secrets/.*""""MOUNTED_SECRET"Esql.executed_command RLIKE """.*\.(p12|pem|key|jks|keystore).*""""CERTIFICATE_OR_KEY"Esql.executed_command RLIKE """.*/etc/kubernetes/.*""""K8S_CONFIG"Esql.executed_command RLIKE """.*/var/lib/kubelet/.*""""KUBELET_CONFIG"Esql.executed_command RLIKE """.*/etc/shadow.*""""HOST_CREDENTIALS"Esql.executed_command RLIKE """.*/etc/passwd.*""""USER_ENUMERATION"Esql.executed_command RLIKE """.*/etc/sudoers.*""""SUDOERS_ACCESS"Esql.executed_command RLIKE """.*(/root|/home)/\.(ssh|aws|azure|kube|config/gcloud).*""""USER_CREDENTIALS"Esql.executed_command RLIKE """.*/proc/.*/environ.*""""PROCESS_ENV_SECRETS"Esql.executed_command RLIKE """.*/etc/.*\.conf.*(password|secret|key|token|credential).*""""EMBEDDED_CONFIG_SECRET""OTHER_SENSITIVE"Stage 10: keep
| KEEP *
Exclusions
Top-level NOT(...) conjuncts: predicates this rule actively suppresses.
| Field | Kind | Excluded values |
|---|---|---|
Esql.executed_command | regex_match | .*/etc/resolv.conf.* |
Indicators
Each row is a field, operator, and value that the rule matches. The corpus column counts how many other rules in the catalog look for the same combination: high numbers point to widely-used, community-vetted indicators. Blank or 1 shows that the indicator is specific to this rule.
| Field | Kind | Values |
|---|---|---|
Esql.executed_command | is_not_null | |
Esql.executed_command | regex_match |
|
kubernetes.audit.objectRef.subresource | eq |
|
kubernetes.audit.requestURI | wildcard |
|
Output fields
Fields the rule emits when it matches. Chronicle authors list these in the outcome block; they appear on the detection and $risk_score drives alerting. Sentinel / Defender XDR rules build them up through project / summarize / extend stages. Sentinel maps these into alert fields via entityMappings and customDetails; Defender XDR custom detections surface them as alert fields directly.
| Field | Source |
|---|---|
* | KEEP * |