I promised that the first thing we will show is getting admin rights to the cluster. We need a specially prepared pod that will hack the Kubernetes cluster. All we need to do is apply it to the Kubernetes cluster.
kubectl apply -f pod.yaml
This pod will come to one of the masters of the Kubernetes cluster. And after that, the cluster will happily return a file called admin.conf. In K8s, this file stores all the administrator's certificates, and at the same time, the cluster API configuration. It's so easy to get admin access, I think, to 98% of Kubernetes clusters are vulnerable in such a way.
Again, this pod was made by one developer in your cluster who has access to deploy his projects in a tiny namespace; he is all squeezed by RBAC limits. He had no rights. Nevertheless, the certificate was returned.
Let's discuss the pod in detail. We can run it on any image - let's take debian: jessie as an example. Here is the thing:
tolerations:
- effect: NoSchedule
operator: Exists
nodeSelector:
node-role.kubernetes.io/master: "" What is toleration? Master nodes in a Kubernetes cluster are usually labelled with a thing called taint. And the essence of this "taint" is that it says that pods cannot be assigned to master nodes. But no one bothers to prohibit any pod to be tolerant of "taint". The Toleration section just declares that if there is
NoSchedule on some node, our pod is tolerant of such a taint — and there are no problems with taint labels.
Further, we declare that our pod is not just tolerant but wellbeing from hitting the master nodes precisely. Because the masters carry the most delicious thing that we need — all the certificates. Therefore, we declare
nodeSelector — and we have a standard label on the masters, which allows you to select from all the nodes in the cluster, precisely those nodes that are masters.
With these two sections, the pod will become the master node, and he will be allowed to live there.
But just becoming the master is not enough for us. It won't give us anything. Because, further, we have the following two security controls applied:
hostNetwork: true
hostPID: true We indicate that our pod, which we're running, will live in the kernel namespace, network namespace, and PID namespace. As soon as the pod is launched as the master one, it will see all the node's live interfaces, listen to all traffic, and see all processes' PIDs.
The rest is self-explanatory. Grab etcd daemon and read whatever you want.
The most interesting thing is the following Kubernetes feature, which is default one:
volumeMounts:
- mountPath: /host
name: host
volumes:
- hostPath:
path: /
type: Directory
name: host In essence, we can say that we want to create a volume
hostPath in the pod that we will run, even without having rights in this cluster. It means we want to take the path from the host on which we will start — and take it as volume. Then we call it
name: host. We mount this
hostPath inside the pod. In this example, to the
/ host directory.
That's our attack chain - we told the pod to become the master, get
hostNetwork and
hostPID there - and mount the entire root master inside this pod.
Please remember - in Debian, we have bash inside, and this bash is running under root. That means we just received root access for the master node while not having any rights in the Kubernetes cluster itself.
The task is to go into the
/host/etc/kubernetes/pki directory; if I'm not mistaken, take all the master certificates of the cluster there and become the cluster administrator.
If you look at it this way, these are some of the most dangerous rights in pods — regardless of what rights the user has:
- Privileged
- Root user
- Host namespace
- Host path volume
If I have the rights to run a pod in some cluster namespace, then this pod has these rights by default. I can run privileged pods, which means I generally have all rights, practically root access to the master node.
My favourite is the Root user. You see, Kubernetes has this Run As Non-Root option. This is a type of protection control. Do you know what the "Moldovan virus" is? If you are suddenly a hacker and come to my Kubernetes cluster, then we, poor administrators, ask: "Please indicate in your pods with which you will hack my cluster, to run as non-root. Otherwise, it so happens that you start the process in your pod under the root, and it will be straightforward for you to hack me. Please protect us from yourself. "
Host path volume is the fastest way to hack a Kubernetes cluster.
In next section we'll study how to prevent pod rights abuse and privilege escalation.