The same exec and attach features that let operators debug a running container let an intruder run commands inside it, using the container's credentials and network position. MITRE ATT&CK T1609 Container Administration Command covers adversaries abusing a container administration service, such as the Docker daemon, the Kubernetes API server or the kubelet, to execute commands within a container. In ATT&CK v20 it sits in the Execution tactic (TA0002), applies to the Containers platform and has no sub-techniques. This guide is for detection engineers, Kubernetes platform teams and cloud security owners. It explains the three administration paths at the level of the ATT&CK description, then focuses on audit and runtime detection, the RBAC and kubelet settings that limit exec, the identity angle and response. It contains no attack procedures. For deploying new workloads rather than running commands in existing ones, see the Kubernetes Security Guide and ATT&CK T1610 Deploy Container.
Key takeaways
- Exec is a permission, not a feature toggle. In Kubernetes, running a command in a pod is a
createon thepods/execsubresource, so whoever holds that verb can run code in every pod it covers. - Three doors, three logs. The API server is recorded in the Kubernetes audit log, the Docker daemon in its own events and logs, and direct kubelet calls only on the node unless you collect them.
- The kubelet is the quiet path. A kubelet on port 10250 with anonymous authentication and
AlwaysAllowauthorisation, or an identity withnodes/proxy, can bypass the controls teams put onkubectl exec. - Exec is how credentials leave. A shell in a pod reads its mounted service account token and any cloud keys, which is why exec into
kube-systemis a high-severity signal. - Detection is a correlation. ATT&CK detection strategy DET0065 pairs the administration call (
docker exec,kubectl exec, kubelet API) with unexpected process creation inside the container.
How the attack works
ATT&CK describes three variants. In Docker, an adversary may set an entrypoint at deployment that runs a script, or use docker exec against a running container. In Kubernetes, an adversary with sufficient permissions may gain execution through the API server, through the kubelet, or with kubectl exec. Defenders should treat these as separate control points:
| Administration path | What grants it | Primary record | Main control |
|---|---|---|---|
| Kubernetes API server exec and attach | RBAC create on pods/exec or pods/attach in a namespace or cluster-wide | API server audit log, objectRef.subresource=exec | RBAC, admission policy, audit |
| Kubelet API on the node | Anonymous kubelet access, or RBAC on nodes/proxy, or node credentials | Kubelet logs on the node; API server audit only when proxied through it | --anonymous-auth=false, --authorization-mode=Webhook, network restriction to 10250 |
| Docker daemon exec | Access to the Docker socket or a remote daemon endpoint | Docker daemon events (exec_create, exec_start), host audit of socket access | Local socket only, TLS client authentication, no socket mounts in containers |
| Entrypoint or command at deployment | Permission to create or modify a workload | Audit log create or patch with command and args fields | Admission policy, GitOps-only changes |
| Ephemeral debug containers | RBAC on pods/ephemeralcontainers | Audit log patch on that subresource | Restrict to break-glass roles |
ATT&CK v20 links T1609 to TeamTNT, the Kubernetes tool Peirates and malware including Hildegard, Siloscape, Kinsing, TeamPCP Cloud Stealer and the self-spreading CanisterWorm and Mini Shai-Hulud. The pattern behind most of these is the same: gain any foothold in a cluster, then use administration commands to reach the pods that hold the most useful credentials.
Where it shows up
- Credential harvesting: exec into a pod to read its service account token or mounted secrets, then use them against the API server or the cloud (T1552.007 Container API).
- Exposed management consoles: in the 2018 Tesla incident, a Kubernetes console reachable without a password gave access to a pod that held AWS credentials. See the Tesla Kubernetes cryptojacking analysis.
- Worm propagation: malware that uses cluster permissions to run itself in other pods.
- Insider and contractor misuse: broad developer exec rights in production namespaces, used outside any support ticket.
- Breakout preparation: exec into a privileged or host-mounted pod as a step towards T1611 Escape to Host.
Detection
DET0065 "Detection Strategy for Container Administration Command Abuse" has one analytic, AN0177, built on two log sources: Docker daemon records of docker exec or docker run with an unexpected command or entrypoint, and Kubernetes API server records of kubectl exec or kubelet API calls targeting running pods. It recommends correlating these with unexpected process creation inside the container.
| Signal | Log source | What to look for |
|---|---|---|
| Exec through API server | Kubernetes audit log (enable the audit log type on EKS; collect GKE and AKS equivalents) | verb=create, objectRef.resource=pods, subresource=exec or attach; who (user.username, groups), from where (sourceIPs), with what (userAgent), into which namespace |
| Exec into system pods | Audit log; Amazon GuardDuty | Exec in kube-system or platform namespaces; GuardDuty Execution:Kubernetes/ExecInKubeSystemPod and Execution:Kubernetes/AnomalousBehavior.ExecInPod |
| Kubelet access | Node logs, network flow to 10250, audit of nodes/proxy | Connections to kubelet from anything other than the control plane and monitoring; any nodes/proxy use |
| Anonymous access | Audit log; GuardDuty | system:anonymous requests; Policy:Kubernetes/AnonymousAccessGranted when a binding grants it permissions |
| Docker exec | Docker daemon events, auditd on /var/run/docker.sock | exec_create and exec_start outside approved tooling; processes that open the socket |
| In-container process | eBPF runtime sensor | Interactive shell spawned in a container whose image never runs shells; reads of /var/run/secrets/kubernetes.io/serviceaccount/token |
Rules to build first
- Exec in production by a human identity without a matching change or incident ticket.
- Exec by a non-human identity: a service account, CI identity or cloud role performing
pods/exec. Automation rarely needs it. - Exec into
kube-system, ingress controllers, CNI and logging agents, or any privileged pod. - Shell followed by token read and API call from the same pod within minutes.
- New RoleBinding granting
pods/execornodes/proxy, especially when followed by exec from the same identity. - Kubelet port reached from a pod network or the internet.
Expect noise from operators debugging; the useful baseline is per identity and namespace, not per cluster. The Kubernetes Audit Log Detection Guide covers audit policy design; make sure your policy records pods/exec at least at Metadata level, and Request if you want the command array.
Measuring it
- Exec holders: number of identities with
pods/execin production, split human and non-human; trend down. - Ticketed exec: percentage of production exec events linked to a change or incident.
- Kubelet hardening: share of nodes with anonymous authentication disabled and Webhook authorisation.
- Audit coverage: clusters whose audit log reaches the SIEM within 15 minutes.
- Time to revoke: minutes from suspicious exec alert to revoked credential in exercises.
Prevention and hardening
ATT&CK lists M1018 User Account Management, M1026 Privileged Account Management, M1042 Disable or Remove Feature or Program, M1035 Limit Access to Resource Over Network and M1038 Execution Prevention. Mapped to settings:
- RBAC for exec: remove
pods/exec,pods/attachandpods/ephemeralcontainersfrom standing developer roles in production; grant them through a time-bound access request. Remember the built-ineditandadminroles include exec in their namespace. See the Kubernetes RBAC Guide. - Kubelet:
authentication.anonymous.enabled: false,authorization.mode: Webhook, client CA set, and port 10250 reachable only from the control plane. - No
nodes/proxyfor anything except tightly controlled monitoring identities. - Docker socket: keep the daemon on its local socket, never mount
/var/run/docker.sockinto containers, and use TLS client authentication where remote access is required. See the Container Runtime Security Guide. - Minimal images: distroless or shell-less images remove the tools an interactive exec session relies on (M1042, M1038).
- Admission policy: deny exec into specific namespaces or labelled pods through a validating admission policy on the
pods/execconnect operation. See the Kubernetes Admission Control Guide.
Rollout
- Enable audit logging and report every exec for 30 days by identity and namespace.
- Agree a just-in-time exec role for production and a break-glass path.
- Remove standing exec from the roles that did not use it; pilot in one production cluster.
- Harden kubelet configuration through the node image or managed node group settings and verify with a configuration scan.
- Roll back by rebinding the previous role from Git if critical support is blocked, and record why.
Where identity fits
T1609 is an authorisation problem on non-human and human identities alike. The identities that hold exec today are often CI service accounts, operators' cloud roles mapped into the cluster through access entries or ConfigMaps, monitoring agents with nodes/proxy, and long-lived kubeconfig files on laptops. Once a command runs in a pod, the pod's own identity becomes available: its projected service account token and any cloud credentials it can obtain. Use short-lived, audience-bound tokens, disable auto-mount where the API is not used, and prefer workload identity federation to static cloud keys in pods, the exact gap in the Tesla case. See the Kubernetes Service Account Token Guide and the Kubernetes NHI Security Guide.
Responding to suspicious exec
- Revoke the caller: remove the binding or disable the identity seen in
user.username; for cloud-mapped identities revoke the cloud session too. - Preserve the pod: do not delete it; isolate with a deny-all NetworkPolicy, capture process and file system state. See the Container and Kubernetes Forensics Guide.
- Rotate what the pod could read: its service account token (by deleting legacy token Secrets or rotating signing keys if needed), mounted secrets and cloud credentials. See How to rotate a Kubernetes service account token and detect old token use.
- Search for reuse: API calls made with the pod's token from elsewhere, and cloud API calls with its credentials.
- Escalate to the Kubernetes Cluster Compromise Playbook if system pods or cluster-admin were reached.
Common failure patterns
- Exec not audited: audit policies that drop subresources or managed clusters with audit logs disabled.
- Everyone has
edit: developers and CI share namespaceedit, which silently includes exec. - Kubelet forgotten: controls on
kubectl execwhile self-managed nodes still allow anonymous kubelet calls. - Docker socket mounted: CI runners or monitoring containers with the host socket mounted, which gives exec into every container on the node.
- Cloud keys in pods: static keys in environment variables, so one exec becomes a cloud compromise, as Tesla found.
Framework mapping
| Framework | Reference | Relevance |
|---|---|---|
| MITRE ATT&CK v20 | T1609; related T1610, T1611, T1552.007, T1613 | Technique and adjacent container steps |
| ATT&CK mitigations | M1018, M1026, M1042, M1035, M1038 | Account and privileged account management, feature removal, network limits, execution prevention |
| NIST SP 800-53 Rev. 5 | AC-3, AC-6, AC-17, CM-7, AU-6, SI-4 | Access enforcement, least privilege, remote access, least functionality, monitoring |
| NIST CSF 2.0 | PR.AA-05, PR.PS-04, DE.CM-09 | Least privilege, logging, monitoring |
| NIST SP 800-190 | Orchestrator administrative access countermeasures | See the NIST SP 800-190 Container Security Guide |
| CIS Controls v8.1 | Controls 5, 6 and 8 | Account management, access control, audit log management |
Practitioner checklist
- List every identity with
pods/exec,pods/attach,pods/ephemeralcontainersornodes/proxyin production. - Replace standing exec with time-bound access and a break-glass role.
- Confirm kubelet anonymous authentication is off and authorisation is Webhook on every node.
- Ensure audit policy records exec and attach, and the logs reach the SIEM.
- Build the six rules above, starting with exec into
kube-systemand exec by non-human identities. - Remove Docker socket mounts from workloads and CI runners.
- Move cloud credentials out of pods into workload identity federation.
Standards and references
- MITRE ATT&CK: Container Administration Command (T1609)
- Kubernetes: Auditing
- Kubernetes: Kubelet authentication and authorization
- Docker: Protect the Docker daemon socket
- AWS: GuardDuty EKS protection finding types
- AWS: Send control plane logs to CloudWatch Logs (Amazon EKS)
- MITRE ATT&CK: Container API (T1552.007)
- NIST: SP 800-53 Rev. 5 Security and Privacy Controls
Related NHI Mgmt Group resources: Kubernetes Audit Log Detection Guide · Kubernetes RBAC Guide · Kubernetes Service Account Token Guide · T1611 Escape to Host Defensive Guide · Container Security Guide