CE_NSENTER
| Source | Destination | MITRE ATT&CK |
|---|---|---|
| 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
setnssyscall
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.