Saltearse al contenido

Pentesting Kubernetes

Kubernetes (K8s) orquesta contenedores a escala, y su seguridad es un mundo propio: la superficie incluye el API server, los secretos, los RBAC, las políticas de red, los service accounts de los pods y la posibilidad de escapar de un contenedor al nodo (ver Escape de contenedores y Docker). El objetivo del atacante suele ser pasar de “tengo acceso a un pod” a “controlo el clúster” (cluster-admin) o al nodo subyacente.

API server el cerebro: toda operación pasa por él (puerto 6443)
etcd base de datos del clúster (incluye SECRETOS si no está cifrada)
kubelet agente en cada nodo (puerto 10250)
pods contenedores; cada uno con un service account (token montado)
RBAC quién puede hacer qué sobre qué recursos
# ¿API expuesto? ¿anónimo?
curl -k https://<ip>:6443/version
kubectl get pods --insecure-skip-tls-verify # ¿acceso anónimo?
# dentro de un pod comprometido: el token del service account
cat /var/run/secrets/kubernetes.io/serviceaccount/token
cat /var/run/secrets/kubernetes.io/serviceaccount/namespace
# kubelet expuesto (10250) -> a veces permite ejecutar en pods

El service account montado en el pod suele poder hablar con el API; con sus permisos enumeras y a veces escalas:

# usar el token del pod
export TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)
curl -k -H "Authorization: Bearer $TOKEN" https://kubernetes.default/api/v1/namespaces/default/pods
# o kubectl si está disponible
kubectl auth can-i --list # qué puedo hacer (CLAVE)
kubectl get secrets -A # ¿leo secretos? (credenciales, tokens)

kubectl auth can-i --list es el sudo -l de Kubernetes: te dice exactamente qué permite tu service account.

# RBAC excesivo
- create pods -> lanzar un pod privilegiado que monta el FS del nodo -> root del nodo
- get/list secrets -> robar tokens de SAs más privilegiados (incluido cluster-admin)
- impersonate -> actuar como otro usuario/SA
- exec en pods -> entrar en pods de otros (lateral)
# escape de contenedor (ver lin-docker)
- pod privilegiado / hostPath / hostPID / hostNetwork -> acceso al nodo
- montar /var/run/docker.sock o el FS del host
# etcd sin cifrar/autenticar -> todos los secretos del clúster
# kubelet (10250) abierto -> exec en pods sin pasar por el API

Ejemplo clásico: con permiso para crear pods, lanzas uno con hostPath montando / del nodo → lees/escribes el filesystem del nodo → root del nodo → desde ahí, el clúster.

kubectl # cliente oficial (auth can-i, get, exec)
kube-hunter # descubre y prueba debilidades del clúster
kubeletctl # abusar del kubelet (10250)
peirates # framework de escalada/pivoting en K8s
kdigger / BOtB # enum desde dentro de un pod y escapes
  • RBAC mínimo: nada de cluster-admin salvo lo imprescindible; sin create pods/secrets amplios; auditar con kubectl auth can-i.
  • Pod Security Standards / admission controllers (OPA/Gatekeeper, Kyverno): prohibir pods privilegiados, hostPath, hostPID.
  • Secretos cifrados en etcd (encryption at rest) y gestor externo; network policies (segmentar pods).
  • API server no anónimo, kubelet autenticado (no 10250 abierto), no montar docker.sock ni el FS del host.
  • Logging/auditoría del API server; escaneo de imágenes; automountServiceAccountToken: false donde no se use.
  • ¿API server (6443) o kubelet (10250) expuesto/anónimo?
  • Token del service account del pod y auth can-i --list
  • get/list secrets → robar tokens privilegiados
  • create pods → pod privilegiado/hostPath → nodo
  • exec/impersonate para lateral/escalada
  • Escape de contenedor al nodo (Escape de contenedores y Docker)
  • etcd sin cifrar → secretos del clúster
  • Mapear hasta cluster-admin o root del nodo