Skip to content

The capstone: a 9.8 in a privileged DaemonSet, a Falco rule that survives a variant, and a postmortem with no payload in it

Artifact — three committed things and one that is destroyed. Committed: a behavioral Falco rule you wrote that fires on the exploit and on an unseen variant of it; a defanged postmortem with a timeline whose exploit description is technique-level, never runnable; and three file:line citations a hostile reader can re-derive. Destroyed with the cluster: the working exploit itself, which is never committed — the repo is a curriculum, not an exploit kit, and that is true whether or not the repo is private. This exercise is the phase's synthesis: every mechanism read in isolation above is here at once, in an incident, against a real CVE.

Rests on — the whole phase, load-bearingly: the node-authorizer graph boundary (why a compromised node does not automatically own its neighbours — the boundary that holds), the bound-token blast-radius argument, the behavioral Falco rule (its seed is the detector here), and the wildcard-verb escalation. Do not attempt this before those; it assumes each as read.

Topology — pair — the phase's cluster, and this exercise is what destroys it. Falco and the exercise 24 rule must still be installed on the worker. The CVE numbers, the chaos-daemon's privileged/hostPID/host-mount facts, and the standing remediated config are in chaos.md#install — read there, not restated here.

Read before you enable anything — the containment story. The isolated NAT'd 10.10.10.0/24 bridge, reachable only through the bastion, is the containment boundary, and it has to be: the injection runs in the chaos-daemon's privileged, hostPID, host-mounted context, where there is no in-cluster boundary to contain it — not a namespace, not RBAC, not a NetworkPolicy. A 9.8 in a privileged DaemonSet is a full-cluster compromise. Two rules are non-negotiable: the PoC is self-contained — no second-stage fetch from the internet — and egress from the cluster is dropped for the exploit window; the working payload is never written to the repo and dies with teardown.

Do — enable, exploit, detect, remediate. Four movements, in order:

  1. Enable the surface. Turn on the pinned-vulnerable chaos-dashboard on the isolated cluster — the same dashboard the P6 reader turned off, now re-enabled as the target. Drop cluster egress first (record which mechanism enforced it — a NetworkPolicy, a dropped default route — for the postmortem).
  2. Exploit. Reach the dashboard's unauthenticated endpoint and trigger the command injection that CVE-2025-59359 describes; the injected command executes in the chaos-daemon context. Keep it self-contained: everything the PoC needs is already on the cluster. Write the payload to the isolated cluster only — never to a file in this repo.
  3. Detect. Your exercise 24 behavioral rule — keyed on an unexpected exec within the chaos-daemon container context, not on any command string — must fire on the exec your exploit caused. Confirm it did (kubectl -n falco logs ds/falco | grep chaos-daemon), and confirm the same exec appears in the audit log from exercise 13.
  4. The variant gate. Only after your rule passes on your own attempt, open the phase's SEALED variant spec — do not read it before then — construct the variant at the technique level it describes, run it on the isolated cluster, and confirm your rule still fires. A rule keyed on the original command, argv, or process name misses it; a rule keyed on context does not. The runnable variant is destroyed with teardown like everything else.
  5. Remediate. Return to the standing chaos.md#install config — v2.7.3, dashboard off. Remediation is the restoration of the config P6 prescribed; incident response lands on the hardening the curriculum already required.

Observe — the exploit runs commands as root on the host via a privileged daemon, and no in-cluster control narrowed it — the lesson stated as fact in the phase: once the daemon is the executor, containment is the bridge, full stop. Yet the node-authorizer graph boundary from exercise 2 still held — a compromised node did not automatically read its neighbour's Secrets — which is the one boundary that survives and is why the postmortem distinguishes "full-cluster compromise" from "every-node's-secrets compromise".

Gate — three file:line citations a hostile reader checks: 1. Why it is a full-cluster compromise: the chaos-daemon DaemonSet manifest fields — securityContext.privileged, hostPID, the host mounts — cited by line. 2. Why a compromised node does not automatically own its neighbours: the graph.go edge from exercise 2, cited file:line — the boundary that held. 3. The detection: the line of your Falco rule that keys on context, plus the audit-log entry for the exec.

Expect — a rule that fires on both your exploit and its variant, a postmortem that describes the technique (unauthenticated request → command injection → privileged daemon context) without ever carrying a runnable payload, and a cluster returned to the remediated config before it is destroyed. If your rule fires on the primary and misses the variant, it is a string rule wearing a behavioral rule's name — go back to exercise 24.

Write down — the committed postmortem. A timeline (enable → exploit → detect → remediate), the defanged technique description, the egress mechanism that held the containment, the three citations above, and the Falco rule inline. The working exploit is not in it and not anywhere in the repo.

Teardown — mandatory and immediate. just tofu labs destroy after the postmortem is written. Teardown is the remediation's completion: the payload, the variant and the vulnerable surface all die with the cluster, and only the rule and the defanged postmortem survive. This is the exercise that releases the phase's topology — the CKS drill block provisions its own fresh pair afterward.

just tofu labs destroy