BLOG
Mapping the Infrastructure Behind the kube-health-tools Supply Chain Malware
Alessandra
Rizzo
Introduction
Twenty days ago, we published our analysis of a supply chain attack targeting Kubernetes developers via a malicious npm and PyPI package called kube-health-tools. That report documented the attack chain from trojanized package to persistent Chisel reverse tunnel.
The actor hasn't gone quiet. Our npm scanner picked up a wave of new activity on April 21–22: three new package names, hardened dropper code, and a shift in payload delivery. More importantly, the GitHub release hosting the payloads has expanded to 21 assets, revealing a full operational toolkit that shows what this campaign is actually for.
New Packages and Targeting Expansion
The actor published three new npm packages alongside continued version bumps to kube-health-tools:
Package | Description | Versions |
|---|---|---|
| "Lightweight Kubernetes node health diagnostics" | 2.4.0 → 2.4.4 |
| "Kubernetes pod health and readiness checker" | 0.0.1 → 0.0.4 |
| "Development environment setup and configuration" | 0.0.1 → 0.0.4 |
| "Performance monitoring utilities for Node.js" | 0.0.1 → 0.0.4 |
The first two target Kubernetes operators. But dev-env-setup and node-perf-utils are generic developer tooling names with no Kubernetes association. We assume the actor is casting a wider net of victims. Eighteen package-version combinations were published in a ~14-hour window, rotating binary hashes with each wave to evade detection.
Dropper Hardening
The addon.node dropper has gone through three revisions. The latest adds unsetenv to scrub the KH_EN config variable from /proc/*/environ, uses open64/close to suppress output in the forked child, and replaces readlink with node_api_get_module_file_name for more reliable path resolution inside containers.
The biggest change is payload delivery. The new packages bundle the Chisel implant directly as prebuilt/.d alongside the dropper. The binary tries the GitHub download first, then falls back to the bundled copy, making the attack resilient to takedowns. The bundled hash matches kube-diag-full-linux-amd64-packed on the GitHub release, confirming it's the "full" variant with the LLM proxy capabilities documented by Aikido Security.
The Operator's Toolkit
The GitHub release at gibunxi4201/kube-node-diag now contains 21 assets, which fall into four categories:
Implant variants: Multiple builds of the Chisel tunnel in base, full (with LLM proxy), extended, and client configurations. The "full" variant is what ships in the npm packages.
CLIProxyAPI (cpa-*): Builds of CLIProxyAPI, an open-source project that provides OpenAI-compatible API proxying with multi-account OAuth support for Copilot, Claude Code, Codex, Gemini, and Kimi. The binary contains login functions for AWS, Google, GitHub, GitLab, and Cursor, including a main.setKiroIncognitoMode function targeting AWS's recently launched IDE.
Transport tools: warp is a Cloudflare WARP client incorporating AmneziaWG, a modified WireGuard protocol designed to evade deep packet inspection. warp-pool-linux rotates across multiple WARP connections for IP diversity. ech-workers is a WebSocket proxy with Encrypted Client Hello that hides destination domains from network observers.
VPS provisioner: A 50KB custom C binary that we reverse engineered in detail below.
The kube-diag-* implant variants are custom builds combining open-source components. The cpa-*, warp, warp-pool, and ech-workers binaries are unmodified open-source tools. The entire toolkit is 0/65+ on VirusTotal.
Reversing the VPS Provisioner
kube-diag-legacy-c-linux-amd64 is the smallest binary in the release. At 50KB, compiled with GCC 15.2.0 on Alpine, it has zero detections.
Using Ghidra headless decompilation, we reconstructed its functionality.
The binary reads a base64-encoded, XOR-encrypted config blob from stdin (key: s0m3R4nd0mK3y2026xYz, the same key found in the Go implant), parses seven fields (C2 domain, credentials, install name, download URL, tunnel specs), and runs a five-stage deployment pipeline. It supports a --dry-run flag for operational testing.
The binary first installs OpenSSH if missing, forces PermitRootLogin yes and binds to all interfaces, then resets the root password via chpasswd using credentials from the config:
It then downloads and install the implant and launches the Chisel tunnel via nohup .
After verifying the tunnel is up, it deletes /tmp/.nhc.enc, deletes itself (argv[0]), and exits. A blank server becomes a fully provisioned relay node with SSH backdoor, root access, and active Chisel tunnel in under 30 seconds.
We assess with moderate confidence that this is the tool the operator uses to build out the server-side infrastructure that compromised developer machines connect back to.
The Full Picture
The diagram below maps every binary in the release to its role in the operation. Malicious packages compromise developer machines, which become residential proxy exit nodes, and their clean IPs and network access are the product.
A Chisel tunnel connects each victim back to the operator's infrastructure, where a custom VPS provisioner builds out relay servers and CLIProxyAPI manages API routing. Traffic crosses the Great Firewall through WARP, ECH, and an IP rotation pool before reaching gray market customers buying cheap LLM access.
Every component except the npm dropper and the 50KB provisioner is an open-source project.

Recommendations
If you installed any of the packages listed below, the implant may still be running even though the package deletes itself from node_modules within seconds of install.
Check for a process named
node-health-checkin your process list.Look for
/tmp/.kd,/tmp/.nhc.enc,/tmp/.nhc.log, or/tmp/.diag.logon disk.Review outbound connections to
sync[.]geeker[.]indevs[.]inon port 443.
If you find any of these, assume the machine is compromised: rotate all credentials accessible from that environment, revoke active OAuth sessions for Copilot, Claude Code, Cursor, and any cloud providers, and reimage the machine.
See it in action
Most AI closes the alert. Panther closes the loop.

Indicators of Compromise
New Malicious npm Packages
Package | Version Range | Author |
|---|---|---|
| 0.0.1 – 0.0.4 | hhsw2015 |
| 0.0.1 – 0.0.4 | hhsw2015 |
| 0.0.1 – 0.0.4 | hhsw2015 |
| 2.4.0 – 2.4.4 | hhsw2015 |
File Hashes, Dropper Binaries
File | SHA-256 |
|---|---|
addon.node (v1, kube-health-tools 2.4.0) |
|
addon.node (v2, used across most versions) |
|
addon.node (v3, latest) |
|
File Hashes, Bundled .d Payload (UPX-packed Chisel)
SHA-256 | Used In |
|---|---|
| v2.4.0–2.4.1, 0.0.1 |
| v2.4.2–2.4.3, 0.0.2–0.0.3 |
| v2.4.4, 0.0.4 (= |
File Hashes, Operator Toolkit
File | SHA-256 |
|---|---|
kube-diag-legacy-c-linux-amd64 |
|
cpa-new-server |
|
warp |
|
warp-pool-linux |
|
ech-workers |
|
Network Indicators
Indicator | Context |
|---|---|
| C2 server |
| Payload staging |
| LLM proxy project used by operator |
Host Indicators
Indicator | Context |
|---|---|
| Dropper staging path |
| Encrypted implant config |
| Relay log file |
| VPS provisioner log |
Process name | Disguised implant process |
| Implant install path (VPS provisioner) |
Encryption Key
s0m3R4nd0mK3y2026xYz, XOR key shared between the VPS provisioner and the Go stage-2 binary's ClearEnv() function.
Share:
RESOURCES






