the_open_door
café
ESEN
← Volver al índice

Abusing a Kubernetes cluster

Cuando la shell cae dentro de un pod de Kubernetes, la escalada deja de ser un problema del sistema operativo y pasa a ser un problema de permisos del cluster. Lo primero es saber si el pod lleva montado un token de cuenta de servicio, que es la credencial con la que hablar con la API:

ls /var/run/secrets/kubernetes.io/serviceaccount/
cat /var/run/secrets/kubernetes.io/serviceaccount/token

Con ese token, kubectl responde a la única pregunta que importa al principio:

kubectl auth can-i --list

Si la respuesta incluye pods/exec, se puede entrar en cualquier pod del namespace; si incluye secrets, se leen las credenciales que guarde el cluster; y si permite crear pods, se puede pedir uno privilegiado que monte el nodo entero:

kubectl get secrets -A
kubectl exec -it <pod> -- /bin/sh

Un segundo camino no pasa por la API sino por el kubelet de cada nodo, que escucha en el 10250. Si acepta peticiones anónimas, se listan sus pods y se ejecuta código dentro sin credencial alguna:

kubeletctl --server <ip> pods
kubeletctl --server <ip> scan rce
kubeletctl --server <ip> exec "id" -p <pod> -c <container>

Matices. Un token de cuenta de servicio no implica privilegios: muchos son de solo lectura y sobre un único namespace. El auth can-i --list es lo que separa el pod anecdótico del que lleva a todo el cluster.

Cómo detectarlo. El audit log del kube-apiserver es la fuente principal: llamadas selfsubjectaccessreviews (el auth can-i --list), get/list sobre secrets, o create de pods con securityContext.privileged: true o hostPath montando el nodo, todo desde una cuenta de servicio que normalmente no hace eso, son la firma. Dentro del pod, la lectura de /var/run/secrets/kubernetes.io/serviceaccount/token por un proceso que no es el de la app la detecta una regla de Falco. En el nodo, peticiones anónimas al kubelet (10250) y el patrón de kubeletctl (escaneo de pods + exec) delatan el segundo camino.

Defensa. No montar el token cuando el pod no lo necesita (automountServiceAccountToken: false), RBAC mínimo por cuenta de servicio, y cerrar el 10250 a la red del plano de control.