Kubernetes Pod Exec Cloud Instance Metadata Access

Detects Kubernetes pod exec sessions whose decoded command line references cloud instance metadata endpoints or equivalent hostnames and paths. Workloads that reach the link-local metadata IP, AWS IMDS paths, GCP computeMetadata, Azure IMDS token routes, or encoded variants are often attempting to harvest role credentials, tokens, or instance attributes from the underlying node or hypervisor boundary. That behavior is high risk in multi-tenant and regulated environments because it can expose short-lived cloud credentials to code running inside a container. The rule classifies a coarse cloud target label and whether the string looks like credential retrieval versus lighter reconnaissance.

Elastic rule (View on GitHub)

  1[metadata]
  2creation_date = "2026/04/23"
  3integration = ["kubernetes"]
  4maturity = "production"
  5min_stack_comments = "URL_DECODE was added to ES|QL in 9.2.0 and is not available on 8.19; 9.3.0 is the lowest supported 9.x release."
  6min_stack_version = "9.3.0"
  7updated_date = "2026/09/22"
  8
  9[rule]
 10author = ["Elastic"]
 11description = """
 12Detects Kubernetes pod exec sessions whose decoded command line references cloud instance metadata endpoints or
 13equivalent hostnames and paths. Workloads that reach the link-local metadata IP, AWS IMDS paths, GCP computeMetadata,
 14Azure IMDS token routes, or encoded variants are often attempting to harvest role credentials, tokens, or instance
 15attributes from the underlying node or hypervisor boundary. That behavior is high risk in multi-tenant and regulated
 16environments because it can expose short-lived cloud credentials to code running inside a container. The rule
 17classifies a coarse cloud target label and whether the string looks like credential retrieval versus lighter
 18reconnaissance.
 19"""
 20from = "now-6m"
 21interval = "5m"
 22language = "esql"
 23license = "Elastic License v2"
 24name = "Kubernetes Pod Exec Cloud Instance Metadata Access"
 25note = """## Triage and analysis
 26
 27### Investigating Kubernetes Pod Exec Cloud Instance Metadata Access
 28
 29This alert fires when an audited exec requestURI, after URL decoding and command reconstruction, matches patterns
 30associated with instance metadata services across AWS, GCP, and Azure. Use it to catch interactive or scripted access
 31from inside a pod to metadata surfaces that should usually be blocked by network policy or not needed by application
 32code.
 33
 34### Possible investigation steps
 35
 36- Confirm the Kubernetes identity that performed exec: user name, groups, impersonation, source IP, and user agent.
 37- Map the pod and namespace to a workload owner, image digest, and entrypoint; determine whether the container should
 38  ever call metadata endpoints.
 39- Inspect Esql.cloud_target and Esql.is_credential_theft in the alert document and expand the timeline for the same
 40  identity for secret reads, IAM changes, or data egress.
 41- Correlate with cloud audit logs on the node identity or instance profile for STS or token issuance around the event
 42  time.
 43
 44### False positive analysis
 45
 46- Break-glass debugging from platform engineers may include curl to 169.254.169.254; validate change tickets and
 47  bastion use.
 48- Misconfigured agents or bootstrap scripts in bespoke images can touch metadata during startup; baseline approved
 49  images and tune exclusions narrowly.
 50
 51### Response and remediation
 52
 53- If unauthorized, terminate the session, isolate the workload, revoke or rotate instance and workload credentials that
 54  could have been read, and tighten RBAC on pods exec plus network policies that deny link-local metadata from pods.
 55"""
 56references = [
 57    "https://attack.mitre.org/techniques/T1552/005/",
 58    "https://hardenedsecurity.io/blog/aws-imds-vulnerabilities-and-mitigations/",
 59]
 60risk_score = 73
 61rule_id = "a8e7d6c5-b4a3-2918-0f9e-8d7c6b5a4032"
 62severity = "high"
 63tags = [
 64    "Data Source: Kubernetes",
 65    "Data Source: Kubernetes API Server Audit Logs",
 66    "Domain: Kubernetes",
 67    "Platform: Kubernetes",
 68    "Domain: Cloud",
 69    "Use Case: Threat Detection",
 70    "Tactic: Credential Access",
 71    "Tactic: Execution",
 72    "Resources: Investigation Guide",
 73    "Noise: Unknown",
 74    "Performance: Normal",
 75    "Profile: Recommended",
 76    "Threat: IMDS Credential Theft",
 77    "Rule Type: ES|QL",
 78    "Domain: Containers",
 79]
 80timestamp_override = "event.ingested"
 81type = "esql"
 82query = '''
 83FROM logs-kubernetes.audit_logs-* metadata _id, _index, _version
 84| WHERE kubernetes.audit.objectRef.subresource == "exec"
 85  AND kubernetes.audit.requestURI LIKE "*command=*"
 86| EVAL Esql.decoded_uri = URL_DECODE(kubernetes.audit.requestURI)
 87| GROK Esql.decoded_uri "%{DATA}/exec\\?%{DATA:raw_commands}&(?:container|stdin|stdout|stderr)=%{GREEDYDATA}"
 88| EVAL command = REPLACE(raw_commands, "command=", "")
 89| EVAL command = REPLACE(command, "&", " ")
 90| EVAL Esql.executed_command = REPLACE(command, "\\+", " ")
 91| WHERE Esql.executed_command IS NOT NULL 
 92  AND Esql.executed_command RLIKE """.*(169\.254\.169\.254|2852039166|0xa9fea9fe|/latest/api/token|/latest/meta-data|/latest/user-data|/latest/dynamic/instance-identity|computeMetadata/v1|metadata\.google\.internal|metadata/identity/oauth2/token|metadata/instance).*"""
 93| EVAL Esql.cloud_target = CASE(
 94    Esql.executed_command RLIKE """.*(169\.254\.169\.254|2852039166|0xa9fea9fe|/latest/meta-data|/latest/api/token|/latest/user-data|/latest/dynamic).*""", "AWS_IMDS",
 95    Esql.executed_command RLIKE """.*(computeMetadata/v1|metadata\.google\.internal).*""", "GCP_METADATA",
 96    Esql.executed_command RLIKE """.*metadata/identity/oauth2/token.*""", "AZURE_IMDS",
 97    "UNKNOWN"
 98  )
 99| EVAL Esql.is_credential_theft = CASE(
100    Esql.executed_command RLIKE """.*(security-credentials|/api/token|oauth2/token|service-accounts/.*/token).*""", "yes",
101    "recon"
102  )
103| KEEP Esql.*, user.name, user_agent.original, event.*, source.ip, kubernetes.audit.*, _id, _version, _index, data_stream.namespace
104'''
105
106[[rule.threat]]
107framework = "MITRE ATT&CK"
108
109[[rule.threat.technique]]
110id = "T1552"
111name = "Unsecured Credentials"
112reference = "https://attack.mitre.org/techniques/T1552/"
113
114[[rule.threat.technique.subtechnique]]
115id = "T1552.005"
116name = "Cloud Instance Metadata API"
117reference = "https://attack.mitre.org/techniques/T1552/005/"
118
119[rule.threat.tactic]
120id = "TA0006"
121name = "Credential Access"
122reference = "https://attack.mitre.org/tactics/TA0006/"
123
124[[rule.threat]]
125framework = "MITRE ATT&CK"
126
127[[rule.threat.technique]]
128id = "T1609"
129name = "Container Administration Command"
130reference = "https://attack.mitre.org/techniques/T1609/"
131
132[rule.threat.tactic]
133id = "TA0002"
134name = "Execution"
135reference = "https://attack.mitre.org/tactics/TA0002/"

Triage and analysis

Investigating Kubernetes Pod Exec Cloud Instance Metadata Access

This alert fires when an audited exec requestURI, after URL decoding and command reconstruction, matches patterns associated with instance metadata services across AWS, GCP, and Azure. Use it to catch interactive or scripted access from inside a pod to metadata surfaces that should usually be blocked by network policy or not needed by application code.

Possible investigation steps

  • Confirm the Kubernetes identity that performed exec: user name, groups, impersonation, source IP, and user agent.
  • Map the pod and namespace to a workload owner, image digest, and entrypoint; determine whether the container should ever call metadata endpoints.
  • Inspect Esql.cloud_target and Esql.is_credential_theft in the alert document and expand the timeline for the same identity for secret reads, IAM changes, or data egress.
  • Correlate with cloud audit logs on the node identity or instance profile for STS or token issuance around the event time.

False positive analysis

  • Break-glass debugging from platform engineers may include curl to 169.254.169.254; validate change tickets and bastion use.
  • Misconfigured agents or bootstrap scripts in bespoke images can touch metadata during startup; baseline approved images and tune exclusions narrowly.

Response and remediation

  • If unauthorized, terminate the session, isolate the workload, revoke or rotate instance and workload credentials that could have been read, and tighten RBAC on pods exec plus network policies that deny link-local metadata from pods.

References

Related rules

to-top