diff --git a/detection_rules/etc/non-ecs-schema.json b/detection_rules/etc/non-ecs-schema.json index ba928fa7e..f47c60c19 100644 --- a/detection_rules/etc/non-ecs-schema.json +++ b/detection_rules/etc/non-ecs-schema.json @@ -114,6 +114,7 @@ "logs-kubernetes.audit_logs-*": { "kubernetes.audit.objectRef.resource": "keyword", "kubernetes.audit.objectRef.subresource": "keyword", + "kubernetes.audit.requestURI": "keyword", "kubernetes.audit.verb": "keyword", "kubernetes.audit.user.username": "keyword", "kubernetes.audit.impersonatedUser.username": "keyword", diff --git a/rules/integrations/kubernetes/privilege_escalation_kubernetes_api_server_proxy_request_to_kubelet.toml b/rules/integrations/kubernetes/privilege_escalation_kubernetes_api_server_proxy_request_to_kubelet.toml new file mode 100644 index 000000000..defb1438e --- /dev/null +++ b/rules/integrations/kubernetes/privilege_escalation_kubernetes_api_server_proxy_request_to_kubelet.toml @@ -0,0 +1,147 @@ +[metadata] +creation_date = "2026/05/05" +integration = ["kubernetes"] +maturity = "production" +updated_date = "2026/05/05" + +[rule] +author = ["Elastic"] +description = """ +Detects non-system identities using the Kubernetes nodes/proxy API to proxy requests through the API server directly +to a node's Kubelet. The nodes/proxy subresource allows any principal with this RBAC permission to reach the Kubelet +API on any worker node without needing direct network access or Kubelet TLS certificates. Through this proxy path, +an attacker can list all pod specifications including environment variable secrets, read Kubelet configuration and +PKI material, retrieve container logs, and access running pod metadata across all workloads on the target node. +Monitoring and health check endpoints such as /metrics, /healthz, and /stats are excluded to reduce noise from legitimate +observability tooling. +""" +false_positives = [ + """ + Legitimate kubelet debugging, node troubleshooting, or security tooling that uses the node proxy outside the + excluded metrics prefix may match. Baseline approved operators and automation identities. + """, +] +from = "now-9m" +index = ["logs-kubernetes.audit_logs-*"] +language = "kuery" +license = "Elastic License v2" +name = "Kubernetes API Server Proxying Request to Kubelet" +note = """## Triage and analysis + +### Investigating Kubernetes API Server Proxying Request to Kubelet + +Review the user.name, source.ip, and user_agent.original fields to determine who initiated the proxy request and from +where. Examine kubernetes.audit.requestURI to identify which Kubelet endpoint was proxied — the path after /proxy/ +maps directly to the Kubelet API path the attacker accessed. + +### Possible investigation steps + +- Check the proxied Kubelet path in requestURI to determine attacker intent: + - /proxy/pods — pod spec enumeration including environment variable secrets + - /proxy/exec or /proxy/run — command execution inside containers on that node + - /proxy/configz — Kubelet configuration and authentication settings + - /proxy/runningpods — active workload enumeration + - /proxy/containerLogs — log harvesting for leaked credentials +- Identify how the principal obtained nodes/proxy permission by reviewing RBAC bindings: + kubectl get clusterrolebindings -o json | jq '.items[] | select(.roleRef.name as $r | + [.subjects[]?.name] | any(. == ""))' +- Check if a ServiceAccount token was created shortly before via the TokenRequest API — this + indicates the attacker minted a token specifically for this access. +- Review whether the same principal accessed multiple nodes via proxy in a short window, which + indicates systematic lateral movement across the cluster. +- Correlate with auditd telemetry on the target node — if /proxy/exec was used, the Kubelet + will have spawned a process (runc init) inside a container that auditd captures. + +### False positive analysis + +- Prometheus, Datadog, and other monitoring agents scrape /metrics and /stats via nodes/proxy. + These endpoints are excluded by default. If additional monitoring paths generate noise, add + them to the requestURI exclusion. +- Cluster administration tools that inspect node health via the proxy API can match. Correlate + with change management windows and verify the source identity. + +### Response and remediation + +- Immediately review the RBAC role granting nodes/proxy permission and determine if the binding + is authorized. Remove unauthorized bindings. +- If /proxy/pods was accessed, assume all environment variable secrets on that node are compromised. + Rotate affected credentials, API keys, and database passwords. +- If /proxy/exec or /proxy/run was accessed, treat the target node as compromised. Isolate the node, + review running containers for unauthorized modifications, and check for persistence mechanisms. +- Audit all ClusterRoles for nodes/proxy permission — this is a powerful privilege that should be + restricted to infrastructure automation only, never granted to application service accounts. +""" +references = [ + "https://kubernetes.io/docs/concepts/cluster-administration/proxies/", + "https://attack.mitre.org/techniques/T1552/007/", +] +risk_score = 47 +rule_id = "332ecb5b-08b6-47e9-885b-3cee1de74bac" +severity = "medium" +tags = [ + "Data Source: Kubernetes", + "Domain: Kubernetes", + "Use Case: Threat Detection", + "Tactic: Privilege Escalation", + "Tactic: Lateral Movement", + "Tactic: Discovery", + "Resources: Investigation Guide", +] +timestamp_override = "event.ingested" +type = "query" +query = ''' +kubernetes.audit.objectRef.subresource:"proxy" and +kubernetes.audit.objectRef.resource:"nodes" and +not kubernetes.audit.requestURI:(*metrics* or *healthz* or *stats/summary*) and +not user.name:( + system\:kube-controller-manager or + system\:kube-scheduler or + system\:serviceaccount\:kube-system\:* or + system\:node\:* or + eks\:* or aksService +) +''' + +[[rule.threat]] +framework = "MITRE ATT&CK" + +[[rule.threat.technique]] +id = "T1611" +name = "Escape to Host" +reference = "https://attack.mitre.org/techniques/T1611/" + +[rule.threat.tactic] +id = "TA0004" +name = "Privilege Escalation" +reference = "https://attack.mitre.org/tactics/TA0004/" + +[[rule.threat]] +framework = "MITRE ATT&CK" + +[[rule.threat.technique]] +id = "T1550" +name = "Use Alternate Authentication Material" +reference = "https://attack.mitre.org/techniques/T1550/" + +[[rule.threat.technique.subtechnique]] +id = "T1550.001" +name = "Application Access Token" +reference = "https://attack.mitre.org/techniques/T1550/001/" + +[rule.threat.tactic] +id = "TA0008" +name = "Lateral Movement" +reference = "https://attack.mitre.org/tactics/TA0008/" + +[[rule.threat]] +framework = "MITRE ATT&CK" + +[[rule.threat.technique]] +id = "T1613" +name = "Container and Resource Discovery" +reference = "https://attack.mitre.org/techniques/T1613/" + +[rule.threat.tactic] +id = "TA0007" +name = "Discovery" +reference = "https://attack.mitre.org/tactics/TA0007/"