Direct Interactive Kubernetes API Request Detected via Defend for Containers
This rule detects the execution of direct interactive Kubernetes API requests inside a container. An adversary may need to execute direct interactive Kubernetes API requests to gain access to the Kubernetes API server or other resources within the cluster. These requests are often used to enumerate the Kubernetes API server or other resources within the cluster, and may indicate an attempt to move laterally within the cluster. Note that this rule may not trigger if the token is expanded within the process argument list, as the length of the "process.args" field may lead to the field being ignored.
Elastic rule (View on GitHub)
1[metadata]
2creation_date = "2026/01/21"
3integration = ["cloud_defend"]
4maturity = "production"
5min_stack_comments = "Defend for Containers integration was re-introduced in 9.3.0"
6min_stack_version = "9.3.0"
7updated_date = "2026/01/27"
8
9[rule]
10author = ["Elastic"]
11description = """
12This rule detects the execution of direct interactive Kubernetes API requests inside a container. An adversary may
13need to execute direct interactive Kubernetes API requests to gain access to the Kubernetes API server or other resources
14within the cluster. These requests are often used to enumerate the Kubernetes API server or other resources within the
15cluster, and may indicate an attempt to move laterally within the cluster. Note that this rule may not trigger if the
16token is expanded within the process argument list, as the length of the "process.args" field may lead to the field being
17ignored.
18"""
19false_positives = [
20 """
21 There is a potential for false positives if the direct interactive Kubernetes API requests are used for legitimate purposes,
22 such as debugging or troubleshooting. It is important to investigate any alerts generated by this rule to determine
23 if they are indicative of malicious activity or part of legitimate container activity.
24 """,
25]
26from = "now-6m"
27index = ["logs-cloud_defend.process*"]
28interval = "5m"
29language = "eql"
30license = "Elastic License v2"
31name = "Direct Interactive Kubernetes API Request Detected via Defend for Containers"
32note = """ ## Triage and analysis
33
34> **Disclaimer**:
35> This investigation guide was created using generative AI technology and has been reviewed to improve its accuracy and relevance. While every effort has been made to ensure its quality, we recommend validating the content and adapting it to suit your specific environment and operational needs.
36
37### Investigating Direct Interactive Kubernetes API Request Detected via Defend for Containers
38
39The rule flags interactive use of curl, wget, openssl, busybox ssl_client, socat/ncat, or kubectl from inside a container to call the Kubernetes API with a bearer token, often with custom CA or insecure TLS options. An operator enumerates cluster resources and tests access with in-pod credentials, enabling lateral movement or privilege escalation; after landing in a pod, they read the service account token and query the API to list namespaces, pods, or secrets, or issue kubectl get/patch to probe or modify workloads.
40
41### Possible investigation steps
42
43- Map the container ID to its pod, namespace, node, image, and owning controller, and confirm whether this workload is expected to make direct Kubernetes API calls or allow interactive access.
44- Determine how the interactive session was initiated and by whom by correlating with Kubernetes events and audit logs for exec/attach/ephemeral-container activity and runtime logs for TTY sessions, including the initiating principal and source IP.
45- Correlate with API server audit logs to retrieve the exact requests (verbs, resources, namespaces), the authenticated subject (service account or user), and response codes to identify any successful access to sensitive resources like Secrets or workload-modifying actions.
46- Inspect the pod for credential use and operator traces by checking recent process activity, shell history, environment variables, and access to service account token or kubeconfig files at expected mount paths.
47- Assess scope and potential persistence by listing recent cluster objects created or modified by the same identity across namespaces (Pods, CronJobs, RoleBindings, Secrets) within the timeframe around the alert.
48
49### False positive analysis
50
51- An administrator used kubectl interactively within a maintenance container to run get/list/patch commands during routine operations such as inspecting pods or updating labels, which matches expected administrative behavior.
52- A developer ran openssl s_client, socat with SSL, or ncat --ssl interactively from within the container to troubleshoot TLS connectivity to a service endpoint, not the Kubernetes API server, causing the rule to fire despite benign intent.
53
54### Response and remediation
55
56- Immediately delete the affected pod to terminate interactive access, and apply a temporary NetworkPolicy in its namespace that blocks egress to the default/kubernetes service (API server) while you patch its ServiceAccount to set automountServiceAccountToken: false.
57- Use API server audit logs and kubectl to enumerate actions taken by the pod’s ServiceAccount and revert any unauthorized objects it created or modified (Pods, CronJobs, RoleBindings, Secrets), and remove any attached ephemeral containers across the namespace.
58- Rotate credentials and restore workloads by deleting any legacy ServiceAccount token Secret, restarting pods to issue new bound tokens, rebuilding the image from a trusted base, and redeploying with read-only rootfs and minimal RBAC verified via kubectl auth can-i.
59- Escalate to incident response if audit logs show Secrets access or create/patch/update on workloads, if the ServiceAccount holds cluster-admin, or if the observed commands used curl -k/--insecure, wget --no-check-certificate, or openssl/socat/ncat with SSL to the API server.
60- Harden the cluster by enforcing admission controls that deny kubectl exec/attach for non-admins, requiring automountServiceAccountToken: false by default and short-lived bound tokens where needed, restricting NetworkPolicies so only designated controllers can reach the API server, and adopting distroless images that omit curl/wget/openssl/ncat.
61"""
62risk_score = 21
63rule_id = "26a989d2-010e-4dae-b46b-689d03cc22b3"
64severity = "low"
65tags = [
66 "Data Source: Elastic Defend for Containers",
67 "Domain: Container",
68 "OS: Linux",
69 "Use Case: Threat Detection",
70 "Tactic: Execution",
71 "Tactic: Discovery",
72 "Resources: Investigation Guide",
73]
74timestamp_override = "event.ingested"
75type = "eql"
76query = '''
77process where host.os.type == "linux" and event.type == "start" and event.action == "exec" and (
78 (
79 process.name == "curl" and
80 process.args in ("-H", "--header") and
81 process.args like "*Authorization: Bearer *" and
82 (
83 /* CA-specified */
84 process.args in ("--cacert", "--capath") or
85 /* insecure */
86 process.args in ("-k", "--insecure")
87 )
88 ) or
89 (
90 process.name == "wget" and
91 process.args like "--header*" and
92 process.args like "*Authorization: Bearer *" and
93 (
94 /* CA-specified */
95 process.args == "--ca-certificate" or
96 /* insecure */
97 process.args == "--no-check-certificate"
98 )
99 ) or
100 (
101 /* Account for tools that execute utilities as a subprocess, in this case the target utility name will appear as a process arg */
102 process.name in ("bash", "dash", "sh", "tcsh", "csh", "zsh", "ksh", "fish", "busybox") and
103 process.args in ("wget", "/bin/wget", "/usr/bin/wget", "/usr/local/bin/wget") and
104 process.args like "--header*" and
105 process.args like "*Authorization: Bearer*" and
106 process.args == "--no-check-certificate"
107 ) or
108 (
109 /* ssl_client is busybox-specific, so we need to handle it separately */
110 process.name == "busybox" and
111 process.args == "ssl_client" and
112 process.args like "*Authorization: Bearer*"
113 ) or
114 (process.name == "openssl" and process.args == "s_client" and process.args == "-connect") or
115 (process.name == "socat" and process.args like~ "*ssl*") or
116 (process.name == "ncat" and process.args like "--ssl*") or
117 (process.name == "kubectl" and process.args in ("get", "list", "watch", "create", "patch", "update"))
118) and
119process.interactive == true and container.id like "*"
120'''
121
122[[rule.threat]]
123framework = "MITRE ATT&CK"
124
125[[rule.threat.technique]]
126id = "T1059"
127name = "Command and Scripting Interpreter"
128reference = "https://attack.mitre.org/techniques/T1059/"
129
130[[rule.threat.technique.subtechnique]]
131id = "T1059.004"
132name = "Unix Shell"
133reference = "https://attack.mitre.org/techniques/T1059/004/"
134
135[rule.threat.tactic]
136id = "TA0002"
137name = "Execution"
138reference = "https://attack.mitre.org/tactics/TA0002/"
139
140[[rule.threat]]
141framework = "MITRE ATT&CK"
142
143[[rule.threat.technique]]
144id = "T1613"
145name = "Container and Resource Discovery"
146reference = "https://attack.mitre.org/techniques/T1613/"
147
148[rule.threat.tactic]
149id = "TA0007"
150name = "Discovery"
151reference = "https://attack.mitre.org/tactics/TA0007/"
Triage and analysis
Disclaimer: This investigation guide was created using generative AI technology and has been reviewed to improve its accuracy and relevance. While every effort has been made to ensure its quality, we recommend validating the content and adapting it to suit your specific environment and operational needs.
Investigating Direct Interactive Kubernetes API Request Detected via Defend for Containers
The rule flags interactive use of curl, wget, openssl, busybox ssl_client, socat/ncat, or kubectl from inside a container to call the Kubernetes API with a bearer token, often with custom CA or insecure TLS options. An operator enumerates cluster resources and tests access with in-pod credentials, enabling lateral movement or privilege escalation; after landing in a pod, they read the service account token and query the API to list namespaces, pods, or secrets, or issue kubectl get/patch to probe or modify workloads.
Possible investigation steps
- Map the container ID to its pod, namespace, node, image, and owning controller, and confirm whether this workload is expected to make direct Kubernetes API calls or allow interactive access.
- Determine how the interactive session was initiated and by whom by correlating with Kubernetes events and audit logs for exec/attach/ephemeral-container activity and runtime logs for TTY sessions, including the initiating principal and source IP.
- Correlate with API server audit logs to retrieve the exact requests (verbs, resources, namespaces), the authenticated subject (service account or user), and response codes to identify any successful access to sensitive resources like Secrets or workload-modifying actions.
- Inspect the pod for credential use and operator traces by checking recent process activity, shell history, environment variables, and access to service account token or kubeconfig files at expected mount paths.
- Assess scope and potential persistence by listing recent cluster objects created or modified by the same identity across namespaces (Pods, CronJobs, RoleBindings, Secrets) within the timeframe around the alert.
False positive analysis
- An administrator used kubectl interactively within a maintenance container to run get/list/patch commands during routine operations such as inspecting pods or updating labels, which matches expected administrative behavior.
- A developer ran openssl s_client, socat with SSL, or ncat --ssl interactively from within the container to troubleshoot TLS connectivity to a service endpoint, not the Kubernetes API server, causing the rule to fire despite benign intent.
Response and remediation
- Immediately delete the affected pod to terminate interactive access, and apply a temporary NetworkPolicy in its namespace that blocks egress to the default/kubernetes service (API server) while you patch its ServiceAccount to set automountServiceAccountToken: false.
- Use API server audit logs and kubectl to enumerate actions taken by the pod’s ServiceAccount and revert any unauthorized objects it created or modified (Pods, CronJobs, RoleBindings, Secrets), and remove any attached ephemeral containers across the namespace.
- Rotate credentials and restore workloads by deleting any legacy ServiceAccount token Secret, restarting pods to issue new bound tokens, rebuilding the image from a trusted base, and redeploying with read-only rootfs and minimal RBAC verified via kubectl auth can-i.
- Escalate to incident response if audit logs show Secrets access or create/patch/update on workloads, if the ServiceAccount holds cluster-admin, or if the observed commands used curl -k/--insecure, wget --no-check-certificate, or openssl/socat/ncat with SSL to the API server.
- Harden the cluster by enforcing admission controls that deny kubectl exec/attach for non-admins, requiring automountServiceAccountToken: false by default and short-lived bound tokens where needed, restricting NetworkPolicies so only designated controllers can reach the API server, and adopting distroless images that omit curl/wget/openssl/ncat.
Related rules
- Direct Interactive Kubernetes API Request by Common Utilities
- Direct Interactive Kubernetes API Request by Unusual Utilities
- Forbidden Direct Interactive Kubernetes API Request
- Service Account Token or Certificate Access Followed by Kubernetes API Request
- DNS Enumeration Detected via Defend for Containers