Frontend Labs
⋯

Chapter 22 — Hands-on: attack a cluster, then harden it

Brief

Take a deliberately-vulnerable Kubernetes cluster, walk a full attack path from "I can deploy one pod" (or "I have a low-priv SA token") to cluster-admin and the node, then apply the Part 4 controls one at a time, re-testing after each, until every path is cut. Finish with runtime detection proven against the attacks.

Setup

   * A kind (or k3d) cluster with a CNI that enforces NetworkPolicy
     (Cilium/Calico).
   * Deploy KubernetesGoat (`madhuakula/kubernetes-goat`) AND the
     BishopFox `badPods` manifests. Optionally the "Kubernetes CTF" / kctf.
   * Tools: kubectl (+ krew: who-can, rakkess, access-matrix), KubeHound,
     rbac-police, KubiScan, kube-bench, kubescape, peirates, Falco,
     Tetragon, Kyverno.

Part 1 — Model (30 min)

   1. kube-bench + kubescape (NSA + CIS frameworks) -> baseline score and
      top findings.
   2. KubeHound -> the attack-path graph. Note the paths from
      `serviceaccount` nodes and from `container` nodes to
      `node`/`cluster-admin`.
   3. Pick two goal paths to walk end to end.

Part 2 — Attack (75 min) — document every command + output

   [ ] RBAC escalation: from a low-priv SA with `create pods`, schedule a
       pod with a powerful `serviceAccountName` (or hostPath/privileged)
       -> read kube-system secrets -> steal a powerful token -> `auth
       can-i --list` == `*`.
   [ ] Node escape: run a badPod (privileged / hostPath `/` / hostPID) ->
       get a node shell -> read `/var/lib/kubelet` secrets and the kubelet
       cert -> talk to the API as `system:node:<name>`.
   [ ] Metadata: from a pod, `curl 169.254.169.254` -> node role creds
       (if the goat/cluster exposes it).
   [ ] Persistence: create a MutatingWebhookConfiguration or a
       ClusterRoleBinding or a static pod.
   [ ] Lateral: reach another namespace's service with no NetworkPolicy.
   Use `peirates` to automate some of this and compare.

Part 3 — Harden (90 min) — re-test after each

   [ ] PSA `restricted` (warn+audit -> enforce) on all non-system
       namespaces -> badPods now rejected at creation. Re-run each.
   [ ] Kyverno: deny `serviceAccountName` outside an allowlist per
       creator; deny hostPath except named system DaemonSets; require
       signed images by digest; generate a default-deny NetworkPolicy per
       namespace.
   [ ] RBAC: remove the `create pods` -> `powerful SA` path (scope the
       operator SA; `automountServiceAccountToken: false` default; deny
       broad `secrets`). Re-run KubeHound -> path gone.
   [ ] NetworkPolicy (default-deny + explicit allows) in every namespace;
       block `169.254.169.254`; make etcd/kubelet unreachable from pods.
   [ ] etcd encryption at rest (KMS/aesgcm provider); verify a raw etcd
       read of a Secret is now ciphertext.
   [ ] Node: IMDSv2 hop-limit-1 (or the cloud equiv); kubelet
       `--anonymous-auth=false`, `--authorization-mode=Webhook`.
   [ ] Alert on MutatingWebhookConfiguration / ClusterRoleBinding creates
       (audit policy -> SIEM).

Part 4 — Detect (45 min)

   [ ] Install Falco (eBPF) + a custom escape-attempt rule + "shell in
       container" + "contact API server from unexpected pod".
   [ ] Re-run the (now-blocked) attacks and any that still partially work;
       confirm Falco fires; record fidelity + latency.
   [ ] Add Tetragon with an ENFORCING TracingPolicy that kills
       `nsenter -t 1` / release_agent writes; verify the process dies.
   [ ] Wire Falco -> a webhook that cordons the node + scales the pod to
       0 (a script is fine for the lab).

Deliverable

~/sec-lab/adv/reports/p4-k8s.md: the KubeHound graph before/after, every attack command with output, every control with its passing re-test, the kube-bench/kubescape score delta, and the Falco/Tetragon detections with evidence. Plus: "the three controls that cut the most paths, ranked".

Definition of done

  • Two full attack paths (RBAC->admin and pod->node) walked and documented.
  • PSA restricted enforced; Kyverno policies in Enforce; the specific RBAC escalation edges removed.
  • NetworkPolicy default-deny everywhere; metadata blocked; etcd encrypted at rest.
  • KubeHound shows no remaining path from a workload SA / container to node/cluster-admin.
  • Falco detecting the residual attempts; one Tetragon enforcement policy proven to kill an escape.
  • kube-bench/kubescape score materially improved, remaining findings explained.

Rubric (/100)

   Attack paths walked + documented .............. 20
   PSA + admission policy in Enforce ............ 20
   RBAC escalation edges removed (KubeHound clean) 20
   NetworkPolicy + etcd encryption + node hardening 20
   Runtime detection + one enforcement, proven ... 15
   Report ...................................... 5

Further reading

  • Practice: KubernetesGoat (with its walkthrough), badPods, kctf / "Kubernetes CTF", the "Kubernetes LAN Party" (k8slanparty.com), pwnedlabs.io k8s tracks.
  • Tools: KubeHound, rbac-police, KubiScan, peirates, kube-bench, kubescape, Falco, Tetragon.
  • Guidance: NSA/CISA "Kubernetes Hardening Guidance" (work through it as a checklist); CIS Kubernetes Benchmark; the Kubernetes "Security Checklist" in the official docs.
  • Book: Hacking Kubernetes (Martin & Hausenblas) — structured almost exactly as this Part; do its labs.

End of Part 4 — Milestone check

  • I can list the container isolation primitives and the escape classes as concrete review items
  • I can name the three components where cluster security is decided and the trust boundaries between pod, node, and cluster
  • I have escalated a low-priv SA to cluster-admin and to a node shell in a lab, then cut every path (KubeHound clean)
  • I can roll out Pod Security Admission restricted without an outage and add a signed-image admission gate
  • I can write default-deny NetworkPolicy + FQDN egress + mesh AuthorizationPolicy and explain what each layer adds
  • I have runtime detection (Falco) and one enforcement policy (Tetragon) proven against real attack techniques
  • I can choose a multi-tenancy isolation model from the trust level and justify it
  • I completed the attack-then-harden cluster lab end to end

Generated from real-life-security-guide-v1.md · 8 Oct 2026 16:36