#015Critical2026-04-03

npm Token Worm + ICP Blockchain C2

@opengov/form-renderer@0.2.20

Verdict:MALICIOUS — Self-propagating worm with decentralized C2

Overview

A self-propagating worm that steals npm authentication tokens from .npmrc files, installs a Python backdoor as a systemd service for persistence, and uses Internet Computer Protocol (ICP) blockchain canisters as command-and-control infrastructure. The backdoor fetches executable payloads from icp0.io, making the C2 decentralized and nearly impossible to take down. deploy.js uses stolen npm tokens to publish copies of itself to other packages, creating a worm that spreads through the npm ecosystem.

ICP
C2 Infrastructure
systemd
Persistence
Worm
Propagation
.npmrc
Token Source

Attack Flow

Token Theft
Reads ~/.npmrc and extracts npm authentication tokens. These tokens allow publishing packages to the victim's npm account.
Systemd Persistence
Installs a Python backdoor as a systemd service, ensuring it survives reboots and runs continuously in the background.
ICP C2
Fetches executable payloads from an ICP blockchain canister (icp0.io). Decentralized hosting means the C2 cannot be taken down by seizing a server.
Self-Propagation
deploy.js uses stolen npm tokens to npm publish copies of itself to other packages the victim maintains, spreading the worm through the ecosystem.

MITRE ATT&CK Mapping

T1195.002Supply Chain Compromise — self-propagating via npm tokens
T1528Steal Application Access Token — .npmrc token theft
T1543.002Systemd Service — persistent backdoor
T1102Web Service — ICP blockchain as C2

Tags

WormICPBlockchain C2npm TokensSystemdSelf-Propagation

Full Report

Supply Chain Worm + ICP C2: @opengov/form-renderer@0.2.20

TL;DR

Multi-stage supply chain worm that steals npm tokens, installs a Python backdoor as a systemd service, and uses an ICP (Internet Computer) canister as C2 — making it impossible to takedown.

Package

  • Name: @opengov/form-renderer@0.2.20
  • Maintainer: ashishsharma0101 (aksharma@opengov.com)
  • Versions: 99 (since 2024-09-24)
  • Postinstall: node index.js (runs automatically)

Attack Chain (verified from source code)

Stage 1: npm Token Theft

function findNpmTokens() {
  // Reads ~/.npmrc, ./.npmrc, /etc/npmrc
  // Extracts _authToken values
  // Also checks NPM_TOKEN env vars
  // Also runs: npm config get //registry.npmjs.org/:_authToken
}

Stage 2: Python Backdoor via systemd

Decodes base64 payload → writes to ~/.local/share/pgmon/service.py → installs as systemd user service → enables + starts.

Stage 3: The Python Backdoor (decoded)

C_URL = "https://tdtqy-oyaaa-aaaae-af2dq-cai.raw.icp0.io/"
# Polls ICP canister every 3000 seconds
# Downloads binary from URL returned by canister
# Executes it as /tmp/pglog

Uses ICP blockchain (Internet Computer Protocol) as C2. The canister is decentralized — no server to takedown.

Stage 4: Worm Propagation

If npm tokens found → runs scripts/deploy.js with tokens → publishes malicious versions of other packages using stolen tokens.

What Makes This Novel

ICP (Internet Computer) as C2 — first documented use in npm malware. The C2 URL tdtqy-oyaaa-aaaae-af2dq-cai.raw.icp0.io is a decentralized canister. Unlike traditional C2 servers, it cannot be seized, blocked by IP, or taken down by hosting providers.

IOCs

  • tdtqy-oyaaa-aaaae-af2dq-cai.raw.icp0.io — ICP canister C2
  • ~/.local/share/pgmon/service.py — backdoor
  • pgmon.service — systemd unit
  • /tmp/pglog — downloaded binary
  • /tmp/.pg_state — state file

Credits

Detected by: npm-sentinel automated scanner Verified by: manual code review + base64 payload decoding Date: 2026-04-03