CloudSEK TRIAD uncovered a sophisticated npm supply chain attack using the typosquatted package crypto-javascri to steal npm and GitHub credentials, then republish trojanized packages through compromised maintainer accounts. The final payload was a modified Arti Tor client with persistence, credential theft, and Tor-based C2, making the operation resilient and difficult to disrupt. #crypto-javascri #crypto-js #Arti #Tor #npm #GitHub
Keypoints
- The attack targeted the npm ecosystem with a typosquatted package named crypto-javascri, one character away from the legitimate crypto-js library.
- The package installed a Rust binary that harvested npm and GitHub credentials from victim machines.
- Stolen credentials were used to enumerate maintained packages and silently republish trojanized versions under trusted maintainer accounts.
- The malicious package used multiple execution paths, including npm preinstall hooks, Claude Code SessionStart hooks, and VS Code folderOpen tasks.
- The final-stage payload was a modified build of Arti, the official Rust Tor client, extended with credential theft, cryptomining, privilege escalation, and systemd persistence.
- The malware used Tor hidden services for command and control, reducing the effectiveness of IP- and domain-based blocking.
- The campaign appears designed for Linux developer systems and CI/CD environments, where npm and GitHub tokens are commonly present.
MITRE Techniques
- [T1195.001 ] Supply Chain Compromise: Compromised a public npm package to distribute malicious code, using a typosquatted library to reach downstream developers (‘published crypto-javascri to the public npm registry…’).
- [T1036.005 ] Match Legitimate Name or Location: Used the near-identical name crypto-javascri to imitate crypto-js and evade casual review (‘one character removed from the widely used crypto-js library’).
- [T1552.001 ] Credentials In Files: Read stored tokens from ~/.npmrc and ~/.git-credentials (‘opens two files: ~/.npmrc… ~/.git-credentials…’).
- [T1078 ] Valid Accounts: Validated stolen npm and GitHub tokens and used them to publish packages under the victim’s identity (‘The victim’s token signs the publish.’).
- [T1505.001 ] SQL Stored Procedure / Server Software Component: Server-Side Code Execution: Injected itself into victim-maintained packages and added a preinstall hook to execute automatically (‘Adds “preinstall”: “./.claude/binary” to the package’s scripts field’).
- [T1546.016 ] Event Triggered Execution: Installed execution through Claude Code SessionStart and VS Code folderOpen triggers (‘Claude Code evaluates .claude/settings.json… on every session start’; ‘VS Code’s runOn: folderOpen executes the task automatically’).
- [T1053.005 ] Scheduled Task/Job: Scheduled Task: Achieved persistence and repeated execution through user-level systemd service behavior (‘Restart=always ensures it recovers from kills’).
- [T1105 ] Ingress Tool Transfer: Downloaded tarballs, unpacked them, and repackaged them with the malware inserted (‘Downloads the current published tarball… Repack and publish’).
- [T1027 ] Obfuscated Files or Information: Used high-entropy embedded data and hex-encoded Python payloads to hide functionality (’embedded within this region… lies a specifically placed hex-encoded Python payload’).
- [T1090.003 ] Proxy: Multi-hop Proxy: Used Tor hidden services as the C2 channel to hide infrastructure (‘Using Tor as the command-and-control (C2) channel gives the attacker both anonymity and resilience’).
- [T1041 ] Exfiltration Over C2 Channel: Sent stolen credentials and operational data through the same Tor-based command channel (‘maintains a heartbeat’; ‘builds a circuit to a hidden service’).
- [T1497.001 ] Virtualization/Sandbox Evasion: System Checks: Checked for cloud metadata endpoints and exited if not present to avoid analysis (‘If no cloud environment is detected, it exits cleanly’).
- [T1055 ] Process Injection: Injected shellcode-like functionality via a staged payload chain (‘deliver the Stage 3 shellcode’).
- [T1547.001 ] Boot or Logon Autostart Execution: Registry Run Keys / Startup Folder: Established user-level startup persistence via copied binaries and service files in startup locations (‘~/.local/bin/systemd-broker’ … ‘~/.config/systemd/user/systemd-broker.service’).
- [T1036.004 ] Masquerading: Masquerade Task or Service: Named the persistence component systemd-broker to resemble legitimate system components (‘systemd-broker.service’).
Indicators of Compromise
- [Package Names ] typosquatted and related packages – crypto-javascri, crypto-js, and version 3.0.1
- [File Paths ] credential and persistence targets – ~/.npmrc, ~/.git-credentials, ./.claude/settings.json, ./.vscode/tasks.json
- [File Names ] malicious binaries and service files – .claude/binary, systemd-broker, systemd-broker.service
- [Registry/API Endpoints ] token validation and enumeration – https://registry.npmjs.org/-/whoami, https://api.github.com/user
- [Registry Search Endpoint ] maintainer enumeration – https://registry.npmjs.org/-/v1/search?text=maintainer:
- [Tor Onion Address ] C2 infrastructure – 1cpur2zdsv762uzyoyzma6pvzz4a2xhv64zdouxpjlu3exyks7gh7leyd.onion:80
- [Account Names ] suspected publishing identity – enge31
- [Binary/Artifact Details ] staged payloads and embedded data – 6.4 MB ELF binary, 218-byte stage 3 payload, 0x1A1F7C embedded hex blob
- [Token/Capability Checks ] abuse indicators – bypass_2fa capability, _authToken field
Read more: https://www.cloudsek.com/blog/inside-a-tor-backed-supply-chain-worm