BONAN RUAN / SECURITY RESEARCH

KUBERNETES POST-EXPLOITATION

k0otkit

Turn orchestration into
persistent cluster control

k0otkit is technical research I carried out in industry. Starting with Kubernetes administrator access, it uses native resources to turn a single foothold into persistent control across cluster nodes.

CIS 2020 · Kubernetes + rootkit · Original mechanism diagrams

Orchestration from administrator access to persistent node controlAdministrator access modifies the kube-proxy DaemonSet Pod template. A Secret supplies the payload. The controller distributes updated Pods to eligible nodes and reconciles the desired state as nodes change. DESIRED STATE 01 / ACCESSAdmin accessAlready obtained 02 / SecretEncoded payloadpayload → env DaemonSet / kube-proxyPod template Controller reconciliation NODE APod / kube-proxyOriginalInjectedNODE BPod / kube-proxyOriginalInjectedNODE CPod / kube-proxyOriginalInjectedEligible nodesOrchestration from administrator access to persistent node controlAdministrator access modifies the kube-proxy DaemonSet Pod template. A Secret supplies the payload. The controller distributes updated Pods to eligible nodes and reconciles the desired state as nodes change.01 / ACCESSAdmin access02 / SecretEncoded payloadDaemonSet / kube-proxyPod templateNODE ANODE BNODE COriginalInjected
One template change, distributed by orchestrationNode joins / Pod rebuilds → same template
Research from industryNSFOCUS · Nebula Lab
Post-penetration

Administrator access first

DaemonSet

Node coverage and Pod replicas

CIS 2020

Shanghai · Technical research talk

With administrator access,
why turn to orchestration

A large cluster contains many nodes. Accessing each one and maintaining individual connections repeats the same work. k0otkit explores how native mechanisms amplify existing control-plane privileges.

01 / ACCESS

Administrator access comes first

The original scenario escapes a container on a control node to obtain root and an administrator kubeconfig. k0otkit takes over in the post-exploitation stage, using those existing API privileges.

02 / COVERAGE

Delegate repetition to a controller

A DaemonSet describes node workloads through a template. Its controller maintains Pods on eligible nodes and reconciles that desired state when nodes join or Pods are deleted.

03 / OBSERVATION

From new objects to an existing template

The initial design creates a separate DaemonSet. Later stages modify the kube-proxy Pod template, separate the payload, reuse an image, and execute from memory. The observable changes shift with each stage.

Prerequisites and mechanisms: the README, CIS 2020 slides pp. 11–14, and the write-up’s basic design. Node coverage depends on the existing DaemonSet’s scheduling conditions. README ↗

Delete a Pod.
The template brings it back

Play or select the stages to trace the final design from API objects to node processes. Then add a node, delete a Pod, or restore the original template.

K0OTKIT / ACCESS → TEMPLATE → NODES → PROCESSESBrowser illustration / no cluster connection
DaemonSet / kube-proxyOriginal Pod template
containers: kube-proxy
Secret / payloadNot created yet
Distribute to eligible nodes
NODE A
Pod / kube-proxy
Original

Admin access

NODE B
Pod / kube-proxy
Original

Admin access

NODE C
Pod / kube-proxy
Original

Admin access

Waiting for runtime sessions
Original containerContainer added to the template

After the flow, change nodes and desired state

Starting point: administrator access; original Pods on nodesExplore the evolution ↘

This browser model illustrates the final design; node counts are illustrative. Actual updates depend on the DaemonSet update strategy, admission rules and node conditions. A deleted Pod is recreated from the current template. If only a container process exits, kubelet typically restarts that container according to its restart policy. k0otkit_template.sh ↗

Each iteration shifts an observable signal

From a separate DaemonSet to an existing Pod template, and from a payload image to memory execution. Switch versions to compare objects, payload location, images and execution.

v1.0 / TECHNICAL EVOLUTION

Move payload execution into memory

Need
Even with deployment handled through pipes, the final payload file remains a disk-based detection point.
Change
Use Perl and memfd_create to decode the payload into a memory file and execute it through a /proc file descriptor. No target-side YAML or payload executable file is required.
Limits
API templates, Secrets, processes and outbound traffic still provide detection signals. The implementation also requires existing admin access, a compatible kube-proxy image and a Linux runtime.

FOUR IMPLEMENTATION SURFACES

API / OBJECTS

Existing kube-proxy template change + Secret

DATA / PAYLOAD

Secret → environment variable → memory file

IMAGE / SOURCE

Existing kube-proxy image, with Perl

EXEC / LOCATION

Execution from a memfd_create memory file

v0.1–v1.0 are design-stage labels from CIS 2020 slides, corresponding to the baseline and seven iterations in the write-up. They do not represent eight repository releases. This comparison describes mechanisms and signals, without performance or success-rate claims.

Control leaves observable changes

The 2020 implementation connects several existing features. Its prerequisites and traces explain where the talk’s detection and defense ideas apply.

API / OBJECTS & ACCESS

Inspect templates, beyond Pod counts

The final design still creates a Secret and changes the containers and volumes in a system DaemonSet. An almost unchanged object inventory does not replace checking template differences and administrator privileges.

Template and Secret source ↗

HOST / IMAGE & ISOLATION

An existing image has prerequisites

The script depends on a kube-proxy DaemonSet, sh, echo and Perl in its image, and Linux payload and system-call conventions. Acceptance of privileged containers and host mounts also affects operation.

README prerequisites ↗

RUNTIME / PROCESS & NETWORK

Memory execution is observable

Executing from memory reduces target-side payload-file traces. Processes, memory files and outbound communication remain observable. The talk discusses object audits and detection of abnormal processes, system calls and network activity.

Memory execution source ↗

“Fileless” refers to target-side YAML and payload executables. The Secret and DaemonSet remain persistent API objects, and the preparation script generates files on the operator side. This exhibit explains the historical design and its environment assumptions.

From technical research
to engineering and detection

k0otkit: A Universal Manipulation Technique in Post-Penetration against Kubernetes. An industry talk at CIS 2020, followed by a technical write-up in January 2021. The project connects native Kubernetes features for post-exploitation control and discusses corresponding detection ideas.

Bonan Ruan · NSFOCUS / Nebula Lab · Security Researcher at the time

Source scope and pinned snapshot

Source checked on 2026-10-10 at commit 1101f06162ebbcd382bcde9a5a364ed45476d4de. The interaction follows the final local-template design. The repository also contains a remote API variant added in 2021. The evolution comes from historical slides and the write-up; node counts and animation illustrate mechanisms.