Safeguard
Application Security•

Detecting and Mitigating Container Administration Commands (T1609)

docker exec and kubectl exec are everyday tools and an attacker's shortcut. How MITRE describes the abuse, what to log, and how to lock down who can run commands in containers.

Safeguard Security Team
5 min read

Container Administration Command (T1609) is an Execution technique for the Containers platform. Adversaries abuse a container administration service, such as the Docker daemon, the Kubernetes API server or the kubelet, to run commands inside a container.

The reason it works is that these services are built for remote management. If someone gets access to the management interface, running code inside a workload is a feature, not an exploit.

How attackers use it

MITRE gives these examples of how the abuse looks:

  • Docker: specifying an entrypoint at deployment that runs a script or command, or using docker exec to run a command in a running container.
  • Kubernetes: with enough permissions, gaining remote execution in a container through the Kubernetes API server, the kubelet, or a command such as kubectl exec.

The MITRE page lists several documented software examples. Hildegard was executed through the kubelet API run command and by executing commands on running containers. Kinsing ran through an Ubuntu container entry point that runs shell scripts. Peirates can use kubectl or the Kubernetes API to run commands. Siloscape can send kubectl commands to victim clusters. Both Mini Shai-Hulud and TeamPCP Cloud Stealer are listed as using kubectl get secrets to gather credentials, and CanisterWorm can deploy privileged DaemonSets in Kubernetes clusters using kubectl.

The pattern in these examples is that attackers use the same client tools your engineers use. That makes who runs them, from where and at what time the useful question, not which binary was called.

How to detect it

MITRE's detection strategy looks for anomalous use of management utilities (docker exec, kubectl exec, or API calls to the kubelet) correlated with unexpected process creation inside containers. The behavioral chain it describes is unauthorized API requests followed by command execution within running pods or containers, often from unusual user accounts, automation scripts or IP addresses outside the expected cluster management plane.

Concrete things to collect and review:

  • Kubernetes API audit logs. Exec requests appear as requests on the pods exec subresource. Review who made them and from which source address.
  • Docker daemon and host logs where Docker is used directly.
  • Container runtime process events, so you can see a shell appear in a container that normally runs one fixed program.
  • Network logs for connections to the kubelet port or the Docker API from outside the management plane.

An exec session into a production pod at 03:00 from a new IP address is worth a ticket every time, even when it turns out to be an engineer.

How to reduce the risk

MITRE lists these mitigations:

  1. Authentication and role-based access control. Enforce both on the container service so users have the least privileges required. In Kubernetes, avoid wildcard permissions and avoid adding users to the system:masters group. Use RoleBindings rather than ClusterRoleBindings to keep privileges within specific namespaces.
  2. Do not run containers as root by default. In Kubernetes, define Pod Security Standards that prevent privileged containers, and use the NodeRestriction admission controller to stop the kubelet from reaching nodes and pods beyond its own.
  3. Remove unneeded tools from containers. If there is no shell and no package manager in the image, there is much less to run.
  4. Limit network access to the container service. Use managed and secured channels such as local Unix sockets or SSH, require TLS for API ports, and disable unauthenticated access to the Docker API and the Kubernetes API server. In cloud clusters, restrict the IP ranges allowed to reach the API server, and consider just-in-time access to the Kubernetes API.
  5. Use read-only containers, read-only file systems and minimal images. Add application control or SELinux where possible to restrict files, processes and system calls.

Check your own environment

Read-only checks (Kubernetes with kubectl, Docker on Linux). Run them with an account you are allowed to use for audits.

# Kubernetes: can the current identity exec into pods in a namespace?
kubectl auth can-i create pods/exec -n default

# Kubernetes: list who is bound to cluster wide roles
kubectl get clusterrolebindings -o wide

# Docker: is the API listening on a TCP port (2375 is plaintext, 2376 is TLS)?
ss -ltn | grep -E ':2375|:2376'

Then ask:

  • Which humans and which service accounts may exec into production pods?
  • Is the API server reachable from the whole internet or from a limited range?
  • Do your base images contain a shell and package manager they do not need?
  • Do audit logs go somewhere an attacker with cluster access cannot edit?

Quick check

Which kubectl command does MITRE name for running commands in a container?

kubectl exec. In Docker the equivalent is docker exec.

Why prefer RoleBindings over ClusterRoleBindings?

RoleBindings limit a user's privileges to specific namespaces, while ClusterRoleBindings apply across the whole cluster.

What does MITRE suggest to remove from containers?

Unnecessary tools and software, which leaves less for an attacker to use once they can execute commands.

Sources

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.