CE_NSENTER
Source | Destination | MITRE |
---|---|---|
Container | Node | Escape to Host, T1611 |
Container escape via the nsenter built-in linux program that allows executing a binary into another namespace.
Details
When both hostPID: true
and privileged: true
are set, the pod can see all of the processes on the host, and you can enter the init system (PID 1) on the host, and execute your shell on the node
Prerequisites
Execution within a container process created with --privileged
AND the --pid=host
enabled.
See the example pod spec.
Checks
There is no straightforward way to detect if hostPID
is activated from a container. The only way is to detect host program running from a pod. The most common way is to look for the kubelet
binary running:
Exploitation
nsenter
is a tool that allows us to enter the namespaces of one or more other processes and then executes a specified program. When you exec a binary into a container using the docker exec command:
You could do the same with nsenter:
+ Target a specific container
+ Look for PID of the targetted container
+ Execute nsenter
of this specific PID and ask for all namespaces
docker ps | grep <container name>
CONTAINER_PID=$(docker inspect <container name> --format='{{ .State.Pid }}')
sudo nsenter -t $CONTAINER_PID -m -u -n -i -p sh
So to escape from a container and access the pod you just run, you need to target running on the host as root (PID of 1 is running the init for the host) ask for all the namespaces:
The options -m -u -n -i -p
are referring to the various namespaces that you want to access (e.g mount, UTS, IPC, net, pid).
Defences
Monitoring
- Monitor for the use of the nsenter binary.
- Monitor the
setns
syscall
Implement security policies
Use a pod security policy or admission controller to prevent or limit the creation of pods with privileged
or hostPid
enabled.
Least Privilege
Avoid running containers as the root
user. Enforce running as an unprivileged user account using the runAsNonRoot
setting inside securityContext
(or explicitly setting runAsUser
to an unprivileged user). Additionally, ensure that allowPrivilegeEscalation: false
is set in securityContext
to prevent a container running as an unprivileged user from being able to escalate to running as the root
user.