Kubernetes Pentesting
Kubernetes (K8s) orchestrates containers at scale, and its security is a world of its own: the surface includes the API server, secrets, RBAC, network policies, pod service accounts, and the possibility of escaping a container to the node (see Container and Docker Escapes). The attacker’s goal is usually to go from “I have access to a pod” to “I control the cluster” (cluster-admin) or the underlying node.
Architecture (the minimum)
Section titled “Architecture (the minimum)”API server the brain: every operation goes through it (port 6443)etcd the cluster database (includes SECRETS if not encrypted)kubelet agent on each node (port 10250)pods containers; each with a service account (mounted token)RBAC who can do what over which resourcesRecon and access
Section titled “Recon and access”# API exposed? anonymous?curl -k https://<ip>:6443/versionkubectl get pods --insecure-skip-tls-verify # anonymous access?# inside a compromised pod: the service account tokencat /var/run/secrets/kubernetes.io/serviceaccount/tokencat /var/run/secrets/kubernetes.io/serviceaccount/namespace# exposed kubelet (10250) -> sometimes allows executing in podsFrom inside a pod
Section titled “From inside a pod”The pod’s mounted service account can usually talk to the API; with its permissions you enumerate and sometimes escalate:
# use the pod's tokenexport TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)curl -k -H "Authorization: Bearer $TOKEN" https://kubernetes.default/api/v1/namespaces/default/pods# or kubectl if availablekubectl auth can-i --list # what I can do (KEY)kubectl get secrets -A # can I read secrets? (credentials, tokens)kubectl auth can-i --list is Kubernetes’s sudo -l: it tells you exactly what your service account allows.
Escalation vectors
Section titled “Escalation vectors”# excessive RBAC- create pods -> launch a privileged pod mounting the node FS -> node root- get/list secrets -> steal more privileged SA tokens (including cluster-admin)- impersonate -> act as another user/SA- exec in pods -> enter others' pods (lateral)# container escape (see lin-docker)- privileged pod / hostPath / hostPID / hostNetwork -> node access- mount /var/run/docker.sock or the host FS# unencrypted/unauthenticated etcd -> all cluster secrets# open kubelet (10250) -> exec in pods without going through the APIClassic example: with permission to create pods, you launch one with hostPath mounting the node’s / → read/write the node filesystem → node root → from there, the cluster.
kubectl # official client (auth can-i, get, exec)kube-hunter # discovers and tests cluster weaknesseskubeletctl # abuse the kubelet (10250)peirates # K8s escalation/pivoting frameworkkdigger / BOtB # in-pod enum and escapesFor the defense
Section titled “For the defense”- Minimal RBAC: no cluster-admin except where essential; no broad
create pods/secrets; audit withkubectl auth can-i. - Pod Security Standards / admission controllers (OPA/Gatekeeper, Kyverno): forbid privileged pods, hostPath, hostPID.
- Encrypted etcd secrets (encryption at rest) and external manager; network policies (segment pods).
- Non-anonymous API server, authenticated kubelet (no open 10250), don’t mount docker.sock or the host FS.
- API server logging/auditing; image scanning;
automountServiceAccountToken: falsewhere unused.
Testing checklist
Section titled “Testing checklist”- Is the API server (6443) or kubelet (10250) exposed/anonymous?
- Pod service account token and
auth can-i --list - get/list secrets → steal privileged tokens
- create pods → privileged pod/hostPath → node
- exec/impersonate for lateral/escalation
- Container escape to the node (Container and Docker Escapes)
- Unencrypted etcd → cluster secrets
- Map up to cluster-admin or node root