IronWorm — Rust-Built npm Supply-Chain Worm

An evolved Shai-Hulud-family worm (JFrog, 3 Jun 2026). A malicious npm install hook drops a ~976 KB Rust ELF that harvests ~86 env vars + 20+ credential files, steals Exodus wallet seeds, ships an eBPF kernel rootkit (process/socket hiding), beacons over Tor, and self-propagates using stolen npm Trusted-Publishing creds. Targets Web3/crypto developers. Defensive hunt & harden pack.
Threat
IronWorm (Shai-Hulud-family Rust npm worm)
Severity
WORM · eBPF ROOTKIT · TOR C2
Type
OSS supply chain · infostealer · self-propagating
Scope
~37–43 npm packages (asteroiddao) · Web3/crypto devs
Discovered
JFrog · 3 Jun 2026 · No CVE
Version
v0.3 · 2026-06-12
Author
HuntPack
01

Executive Summary

IronWorm (identified by JFrog on 3 Jun 2026) is an evolved variant of the Shai-Hulud worm family, distributed through ~37–43 npm packages published from the compromised asteroiddao account and aimed at the Arweave/WeaveDB decentralized-database and broader Web3/crypto developer ecosystem. Unlike the JS-only Shai-Hulud waves, IronWorm's install hook drops a ~976 KB native Rust ELF (tools/setup, UPX-packed with an overwritten magic to defeat unpackers).

The ELF aggressively harvests ~86 environment variables and 20+ credential file paths (cloud keys, AI API keys, SCM/registry/CI tokens, Kubernetes/Vault secrets), captures Exodus desktop-wallet seed phrases, and deploys an eBPF kernel rootkit to hide its processes/sockets and resist debugging. It exfiltrates to a Tor hidden service (path /api/agent) with a temp.sh fallback, and self-propagates by abusing stolen npm publishing credentials — including npm's Trusted Publishing workflow. The actor made 57 backdated malicious commits across nine organizations to muddy the timeline.

Defender priority: Dev/CI-CD threat with kernel-level evasion. Hunt SCA inventory + npm-token audit first; the strongest endpoint signals are Q1 (npm hook → a native ELF in node_modules being chmod'd/executed) and Q3 (an eBPF program load by a non-system process). Treat any affected dev host/runner as fully compromised — the eBPF rootkit means you can't trust on-host visibility; rebuild.

02

Source Review & Web Hunter Notes

TierSourceKey FindingCarry
1 · Vendor researchPhoenix Security — IronWorm (Rust/eBPF/Tor)Rust ELF, eBPF rootkit, Tor C2, self-propagation; 37 packages; full chainyes
1 · Vendor researchSafeDep / OX Security — IronWorm campaignasteroiddao account; cred/env harvesting scope; npm Trusted-Publishing abuseyes
1 · News of recordBleepingComputer / The Hacker News / Dark Reading36–37 packages; Shai-Hulud-family lineage; Miasma variant alongsideyes
2 · VendorCyberpress — developer-secret theft86 env vars, 20+ cred files, Exodus wallet seeds, temp.sh fallbackyes

Decisions: dev/CI-CD-first (native SCA + npm-token audit are primary); endpoint CQL covers the install-hook → ELF → eBPF/Tor behaviors on Linux/macOS dev hosts; flagged that the eBPF rootkit undermines on-host trust (rebuild, don't clean); cross-references the Shai-Hulud "Hades" + Mini Shai-Hulud sibling packs (same worm family).

03

Hunt Brief & Attack Chain

Working hypothesis: A dev/runner installs a trojanized npm package; the install hook drops and runs the Rust ELF, which harvests secrets + wallet seeds, loads an eBPF rootkit, exfiltrates over Tor, and re-publishes via stolen npm tokens.

StepBehaviorTelemetryHunt Angle
1 · Installnpm installs a trojanized package; install hook firesnpm execN1; Q1
2 · Drop ELF~976 KB Rust ELF written to tools/setup in node_modules; chmod +x; executefile write; ProcessRollup2Q1 / Q2
3 · RootkiteBPF program loaded to hide processes/sockets; anti-debugbpf syscall (eBPF)Q3; N3
4 · HarvestRead ~86 env vars + 20+ cred files; Exodus wallet seedsfile readQ4
5 · ExfilBeacon to Tor hidden service /api/agent; temp.sh fallbacknetwork; DNSQ5
6 · WormRe-publish to npm via stolen Trusted-Publishing credsnpm publish auditQ6; N4

Affected surface & telemetry

SurfaceRequired TelemetryPriorityGap Risk
Developer workstations (Linux/macOS)Process + file telemetry; eBPF/syscall visibilityCriticalHigh — eBPF rootkit hides on-host artifacts
CI/CD runnersRunner process/network; npm token useCriticalHigh — ephemeral & often unmonitored
npm registrySCA + Trusted-Publishing token auditHighLow — lockfile/SBOM + token review
Network egressTor / temp.sh connectionsMediumMedium — Tor blends/rotates
04

Consolidated IOC Table

The eBPF rootkit hides on-host artifacts — prefer off-host detection (network egress, SCA, npm audit). Package versions rotate as the worm spreads. Copy-ready blocks in §9.
TypeValueConfActionContext
Filetools/setup (~976 KB UPX-packed Rust ELF, overwritten magic)highhuntThe dropped implant
Accountnpm publisher: asteroiddao (43 packages)highdetectCompromised publisher — pin away
BehavioreBPF program load by a non-system process (rootkit)highdetectProcess/socket hiding
NetworkTor hidden-service beacon (/api/agent) · temp.sh fallback exfilmediumhuntC2 / exfil
Behaviornpm re-publish via stolen Trusted-Publishing credsmediumhuntSelf-propagation
05

ATT&CK Mapping

TacticTechniqueObserved BehaviorQuery / Control
Initial AccessT1195.002 — Compromise Software Supply ChainTrojanized npm packages (asteroiddao)N1; SCA (§10)
ExecutionT1059.007 / T1106 — JS hook / native ELFinstall hook drops + runs Rust ELFQ1, Q2
Defense EvasionT1014 / T1562.001 — Rootkit (eBPF)Process/socket hiding; anti-debugQ3; N3
Credential AccessT1552.001 / .005 / T1539 — Files / env / wallet seeds86 env vars, 20+ cred files, Exodus seedsQ4
C2 / ExfiltrationT1090.003 / T1567 — Tor / web exfilTor hidden service + temp.shQ5
Lateral / ImpactT1195.002 (worm) — re-publish via stolen tokensnpm Trusted-Publishing abuseQ6; N4
06

Native Audit-Log Hunts (dev / CI-CD — primary surface)

HuntSourceLogicResponse
N1 · Affected-package inventorySCA / SBOM / lockfilesAny project resolving a package from the asteroiddao publisher / IronWorm advisory listPin away; rebuild; rotate
N2 · Rust-ELF artifact scanEndpoint file scan (where eBPF hasn't hidden it)~976 KB UPX-packed ELF at node_modules/.../tools/setup with overwritten magicRebuild host (don't trust clean)
N3 · eBPF / kernel object auditbpftool prog list / kernel audit / Falcon kernel telemetryUnexpected eBPF programs/maps loaded by a non-system processTreat host as rootkitted; rebuild
N4 · npm token / publish auditnpm publish + Trusted-Publishing logsUnexpected publishes / OIDC-trusted-publish from your org's tokensRevoke tokens; unpublish; report
N5 · Tor / temp.sh egressProxy / firewall / DNSDev-host connections to Tor entry nodes or temp.shBlock; isolate the source
07

CrowdStrike LogScale CQL Hunt Queries

Pick your tenant's cloud first — every "Open in Falcon" button below uses this selection.
These target Linux/macOS dev & CI hosts. The eBPF rootkit can blind on-host telemetry once loaded — Q1–Q3 are most reliable before the rootkit activates; lean on off-host signals (N4/N5) afterward. Field names validated against the Falcon event reference.
Q1 · npm install hook dropping/executing a native binary
CONF HIGHFP LOW-MEDCOST LOW

Looks for: npm/node spawning chmod/exec of a binary under node_modules (esp. tools/setup). Accomplishes: catches the ELF drop+run. FP: some native modules ship binaries — verify path/size.

// HUNT: IronWorm install hook drops/executes a native ELF (tools/setup)
// MITRE: T1195.002, T1106 | CONF: high  FP: low-med  COST: low
// FP NOTES: some native modules ship binaries; flag tools/setup + chmod + exec from node_modules
#event_simpleName=/ProcessRollup2|SyntheticProcessRollup2/
| ParentBaseFileName=/^(npm|node|yarn|pnpm)$/i
| (CommandLine=/node_modules\/.+\/tools\/setup/i or (FileName=/^chmod$/i and CommandLine=/node_modules\/.+(setup|bin)/i))
| table([@timestamp, ComputerName, UserName, ParentBaseFileName, FileName, CommandLine], limit=200)
Q2 · Native ELF written into node_modules
CONF HIGHFP LOW-MEDCOST LOW

Looks for: an ELF/Mach-O written to a tools/ path inside node_modules during install. Accomplishes: catches the implant drop pre-execution.

// HUNT: IronWorm native implant written into node_modules
// MITRE: T1105 | CONF: high  FP: low-med  COST: low
// TUNING: correlate to Q1; ~976KB UPX-packed; tools/setup path
#event_simpleName=/ELFFileWritten|NewExecutableWritten/
| TargetFileName=/node_modules\/.+\/tools\/(setup|bin)/i
| table([@timestamp, ComputerName, UserName, ContextBaseFileName, TargetFileName, SHA256HashData], limit=200)
Q3 · eBPF program load by a non-system process (rootkit)
CONF HIGHFP LOW-MEDCOST MED

Looks for: a non-system process loading an eBPF program (BPF_PROG_LOAD) or invoking bpf(). Accomplishes: the rootkit load. FP: observability/security agents use eBPF — allow-list them. Requires Linux sensor eBPF/syscall telemetry.

// HUNT: IronWorm eBPF rootkit load (non-system process)
// MITRE: T1014, T1562.001 | CONF: high  FP: low-med  COST: med
// REQUIRES: Linux sensor eBPF/syscall telemetry
// TUNING: allow-list observability/security agents
#event_simpleName=/BpfProgramLoad|SyscallBpf|KernelModuleLoad/
| ImageFileName!=/\/(usr\/(s)?bin|opt\/(falcon|datadog|sysdig|cilium))\//i
| table([@timestamp, ComputerName, UserName, ImageFileName, CommandLine], limit=200)
Q4 · Process reading many credential / env files
CONF MEDFP MEDCOST MED

Looks for: a single process opening many credential files (.aws, .npmrc, kube config, Vault, Exodus wallet). Accomplishes: the harvest stage. FP: dev tooling reads some — flag breadth + a node_modules-spawned parent. Requires file-access telemetry.

// HUNT: IronWorm credential/secret harvesting (broad cred-file reads)
// MITRE: T1552.001, T1552.005, T1539 | CONF: medium  FP: medium  COST: med
// REQUIRES: file-access telemetry
// TUNING: flag breadth + a node_modules-derived parent
#event_simpleName=/FileOpen|ProcessFileOpen|OsfmFileOpen/
| TargetFileName=/(\.aws\/credentials|\.npmrc|\.config\/gcloud|kube\/config|\.vault-token|\.docker\/config|Exodus\/exodus\.wallet|\.ssh\/id_)/i
| groupBy([aid, ImageFileName], function=[count(field=TargetFileName, distinct=true, as=files)])
| files>=4
| sort(files, order=desc)
Q5 · Tor / temp.sh exfil from a dev host
CONF MEDFP LOW-MEDCOST LOW

Looks for: DNS/connections to temp.sh or Tor entry-node patterns from a dev host. Accomplishes: the exfil channel. FP: low for temp.sh on a dev host; Tor requires an entry-node feed.

// HUNT: IronWorm exfil (temp.sh fallback / Tor)
// MITRE: T1567, T1090.003 | CONF: medium  FP: low-med  COST: low
// TUNING: enrich with Tor entry-node feed; temp.sh from a dev host is suspicious
#event_simpleName=DnsRequest
| DomainName=/(^|\.)(temp\.sh)$/i
| table([@timestamp, ComputerName, ContextBaseFileName, DomainName], limit=200)
Q6 · Runtime contacting npm registry to publish (worm)
CONF MEDFP MEDCOST MED

Looks for: the dropped implant / node contacting registry.npmjs.org outside a sanctioned publish pipeline. Accomplishes: worm re-publish. FP: legit dev tooling — correlate with Q1–Q3 + non-CI host.

// HUNT: IronWorm self-propagation (publish to npm outside a pipeline)
// MITRE: T1195.002 | CONF: medium  FP: medium  COST: med
// TUNING: exclude sanctioned publish runners; correlate to Q1-Q3
#event_simpleName=DnsRequest
| DomainName=/(^|\.)registry\.npmjs\.org$/i
| ContextBaseFileName=/^(node|setup|npm)$/i
| table([@timestamp, ComputerName, ContextBaseFileName, DomainName], limit=200)
08

Detection Recommendations (SCA / npm / kernel)

Because of the eBPF rootkit, prioritize off-host + pre-execution detections: SCA package gating, npm Trusted-Publishing audit, and kernel/eBPF monitoring from a trusted layer.
DetectionLogicBenign ExclusionsDeployment Path
Affected-publisher gateBlock/alert on packages from asteroiddao / the IronWorm advisory listNone — hard-blockSCA / dependency firewall / CI gate
Unexpected eBPF loadQ3: eBPF program loaded by a non-allow-listed processObservability/security agentsFalcon kernel IOA / eBPF monitoring
Anomalous npm publishN4: publishes / trusted-publish events outside expected workflowsSanctioned pipelinesnpm audit / SIEM correlation
09

Machine-Readable IOC Appendix

Grouped IOC Quick-Copy

One-click blocks for SCA gating, endpoint/kernel sweeps, and response. The eBPF rootkit hides on-host artifacts — favour off-host signals and rebuild affected hosts.

Package / PublisherSCA gate
# Compromised npm publisher: asteroiddao (~37-43 packages)
# Targets Arweave / WeaveDB / Web3 / crypto-developer packages
# Pin away from ALL asteroiddao-published packages; re-verify the exact list vs JFrog/SafeDep advisory
# Sibling worm packs (same family): Shai-Hulud "Hades" (PyPI), Mini Shai-Hulud (npm/PyPI)
# Hunt package-lock.json / yarn.lock for asteroiddao-published deps
Host Artifactsmay be eBPF-hidden
# Implant
node_modules/.../tools/setup    # ~976 KB Rust ELF, UPX-packed with overwritten magic
# Rootkit
unexpected eBPF programs/maps (bpftool prog list / bpftool map list)
# Exfil
Tor hidden-service beacon, path /api/agent ; temp.sh fallback upload
# Harvest targets (read by the ELF)
~86 env vars + 20+ cred files: ~/.aws, ~/.npmrc, ~/.config/gcloud, ~/.kube/config,
  ~/.vault-token, ~/.docker/config.json, ~/.ssh/id_*, Exodus wallet seed
Behavioral Signaturesdetection logic
npm/node install hook -> chmod +x + exec of node_modules/.../tools/setup
~976 KB ELF/Mach-O written into a node_modules tools/ path
eBPF program/map loaded by a non-system process (process/socket hiding)
One process reading many cred/env files (>=4 of: .aws/.npmrc/kube/vault/ssh/Exodus)
Dev host connecting to temp.sh or a Tor entry node
node/setup contacting registry.npmjs.org outside a sanctioned publish pipeline
Response Checklistrebuild & rotate
# eBPF rootkit = do NOT trust on-host cleanup:
1. Network-isolate affected dev hosts/runners
2. REBUILD from clean images (the rootkit can hide processes/sockets/files)
3. Rotate EVERYTHING reachable: cloud keys, AI API keys, SCM/registry/CI tokens,
   Kubernetes/Vault secrets, SSH keys, npm publish/Trusted-Publishing tokens
4. Move any Exodus wallet funds to a NEW seed (seed phrase assumed stolen)
5. Audit npm publishes; unpublish worm-pushed versions; SCA hard-block asteroiddao
6. Block Tor + temp.sh egress on dev/build networks
10

Hardening — Tiered & Deployable

Stop install-time native code and starve the worm of tokens and egress.

Immediate — Block install-time native code
  • SCA / dependency-firewall: hard-block asteroiddao packagesM1016.
  • Disable npm lifecycle scriptsM1042: npm ci --ignore-scripts; vet native binaries before allowing.
  • Egress allow-list on dev/build hosts; block Tor + temp.shM1037. Starves exfil (Q5).
  • Protect npm Trusted-Publishing: scoped, short-lived OIDC publish; no standing tokensM1015 / M1026. Breaks self-propagation.
Near term — Kernel & secret hygiene (pilot first)
  • Restrict unprivileged eBPF (kernel.unprivileged_bpf_disabled=1)M1038. Raises the bar for the rootkit.
  • Keep secrets out of env/files on dev hosts; use a broker / short-lived credsM1015. Shrinks the harvest.
  • Hash-pinned lockfiles + dependency review gateM1016.
Strategic — Isolate builds, verify provenance
  • Ephemeral, network-restricted, secretless build runnersM1015 / M1030.
  • Independently verify package provenance; internal mirror with reviewM1016.
  • Crypto-dev hardware wallets / cold storage; never store seeds on dev hostsM1027.
11

Containment Runbook

PhaseActionsOwnerEvidence
IsolateNetwork-contain affected dev hosts/runners; freeze affected pipelines; capture network evidence off-host (eBPF hides on-host)SOC / PlatformContainment timestamp; net evidence
TriageConfirm via SCA (asteroiddao deps) + off-host egress (Tor/temp.sh); enumerate reachable secrets/tokensIRSCA results; secret reachability
EradicateRebuild hosts/runners from clean images (do not clean — rootkit); revoke npm tokens; unpublish worm versionsIR / PlatformRebuild tickets; revoked tokens
RecoverRotate ALL reachable creds; move Exodus funds to a new seed; restore clean pinned depsIR / ITRotation log; new wallet
HardenSCA gate; disable lifecycle scripts; restrict eBPF; egress allow-list; scope OIDC publish; promote Q1/Q3Platform / Detection EngControl status; detections enabled
12

Detection Coverage Map & Validation

TechniqueBehaviorCQLNativeCoverage
T1195.002Trojanized package install + ELF dropQ1, Q2N1, N2Good via SCA
T1014eBPF rootkit loadQ3N3Partial needs kernel telemetry; pre-rootkit best
T1552 / T1539Cred/env/wallet harvestQ4Partial needs file-access telemetry
T1090.003 / T1567Tor / temp.sh exfilQ5N5Partial off-host best (rootkit)
T1195.002 (worm)npm re-publishQ6N4Partial npm audit primary
On-host visibility after rootkitGAP eBPF hides artifacts — rebuild

Validation gates: (1) confirm process/file/eBPF telemetry on dev/CI hosts + npm audit ingestion; (2) baseline legit native-module installs + eBPF-using agents (allow-list for Q3); (3) lab-test a benign package dropping a binary to node_modules/tools/setup (Q1/Q2) and a benign temp.sh upload (Q5); (4) promote Q1/Q3 + the asteroiddao SCA gate; treat any confirmed host as rootkitted (rebuild).

13

Hunt Summary Ticket

TITLE:        Hunt — IronWorm (Rust npm supply-chain worm; eBPF rootkit; Tor C2)
SEVERITY:     Critical (kernel rootkit; credential + wallet theft; self-propagating)
SCOPE:        Developer workstations + CI/CD runners (esp. Web3/crypto) using asteroiddao deps
HYPOTHESIS:   Trojanized npm package -> install hook drops ~976KB Rust ELF (tools/setup) ->
              eBPF rootkit hides it -> harvest 86 env vars/20+ cred files + Exodus seed ->
              Tor /api/agent exfil (temp.sh fallback) -> re-publish via stolen npm tokens.
QUERIES RUN:  Q1 hook -> native exec | Q2 ELF in node_modules | Q3 eBPF load | Q4 cred harvest |
              Q5 Tor/temp.sh exfil | Q6 npm re-publish
              + Native N1-N5 (SCA, ELF scan, eBPF audit, npm token audit, Tor/temp.sh egress)
DO FIRST:     N1 (asteroiddao inventory) + Q1/Q3; ISOLATE + REBUILD (don't clean - rootkit)
FINDINGS:     <pending analyst execution>
GAPS:         eBPF hides on-host artifacts -> off-host detection + rebuild
ACTIONS:      SCA hard-block asteroiddao; --ignore-scripts; restrict eBPF; egress allow-list;
              scope OIDC publish; rotate all creds; move Exodus to new seed; promote Q1/Q3
OWNER:        HuntPack
VERSION:      v0.3 - 2026-06-12
14

Changelog

v0.52026-07-24CQL correctness pass. All table() calls now carry an explicit row limit: the default is 200 and truncation is silent, so a capped result was indistinguishable from a complete one. Atomic-IOC sweeps (filters over 5+ hashes or C2 IPs) use limit=max so a wide infection is never silently under-scoped; behavioural hunts use limit=200, where exceeding the cap indicates the query needs tuning. Where present, event names that do not exist in the Falcon data model were corrected (e.g. ServiceInstalled is a Sysmon concept, not a Falcon event; ElfFileWritten is ELFFileWritten) — such queries could never return a row. No detection logic, fields, or IOCs changed.
v0.42026-06-29CQL syntax review (crowdstrike-logscale-v3): removed invalid FileCreateInfo event (Q2).
v0.32026-06-12Re-hunt + reformatted to the review-v2 gold layout (fixed left-sidebar scrollspy TOC, collapsible, cloud selector inside the CQL section, per-card Copy/Open-in-Falcon, Grouped IOC Quick-Copy grid, coverage+validation, .ticket). Refreshed from JFrog/Phoenix/SafeDep: Rust ELF (tools/setup, ~976KB, overwritten magic), eBPF rootkit, Tor /api/agent + temp.sh exfil, 86-env/20+-cred harvest, Exodus seed theft, asteroiddao publisher, npm Trusted-Publishing self-propagation. Cross-linked the Shai-Hulud "Hades" + Mini Shai-Hulud sibling packs. 6 CQL + 5 native hunts.
v0.12026-05-26Initial pack: IronWorm Rust npm worm overview + hunts. Pre-gold top-bar layout.
15

References

TierSourceUsed For
1Phoenix Security — IronWorm (Rust/eBPF/Tor)Full chain: ELF, eBPF rootkit, Tor C2, self-propagation
1SafeDep — IronWorm campaign · OX Security — IronWormasteroiddao account; harvest scope; Trusted-Publishing abuse
1BleepingComputer — IronWorm (36 packages) · The Hacker News — IronWorm & MiasmaScope, lineage, timing
2Cyberpress — developer-secret theft86 env vars, 20+ cred files, Exodus seeds, temp.sh

HuntPack v0.3 · IronWorm · Generated 2026-06-12 · Defensive use only. The eBPF rootkit undermines on-host trust — favour off-host detection and rebuild affected hosts. Package set rotates; keep SCA + npm-token monitoring live. See the Shai-Hulud "Hades" + Mini Shai-Hulud packs for the related worm family. Validate field names in your tenant before promoting any query.