Your developer workstation is the ultimate high-value target, and your allowlisted infrastructure is the easiest way to breach it. When threat actors want to slip past enterprise egress filters and perimeter security, they do not spin up raw, suspicious bulletproof hosting anymore. They build their staging grounds right inside the platforms you already trust.
Researchers at OX Security recently tracked a campaign linked to North Korea (DPRK) that turns Hugging Face into a payload delivery pipeline and a live data exfiltration sink, distributed directly through poisoned npm packages.
By leveraging trusted SaaS infrastructure, the attackers bypass legacy network detection while dropping a combined Keylogger, Infostealer, and Remote Access Trojan (RAT) straight onto developer workstations.
INSPECTION / INFECTION PIPELINE
[ Developer Machine ]
│
│ 1. "npm install" runs postinstall hook
▼
[ utils.cjs ] (Fingerprints OS)
│
│ 2. Fetches bundled binary over HTTPS
▼
[ Hugging Face Repo ] ──( Serves Node.js SEA Implant )──┐
│
┌──────────────────────────────────────────────────────────┘
│
▼
[ Windows Host ] ─── Installs to %LOCALAPPDATA%\MicrosoftSystem64
│
├─► [ WebSocket Connection ] ──► Full RAT / Shell / Input Control
│
└─► [ HTTP / Private Dataset ] ─► Exfiltrates Keys, Telegram, Wallets
Patient Zero: Poisoning the Node Ecosystem
The delivery vehicle relies on deceptive naming conventions in the public npm registry. Attackers publish packages that look like basic logging utilities, relying on developers to pull them in directly or inherit them as transitive dependencies.
The infection starts with four interconnected packages:
terminal-logger-utilspretty-logger-utilsts-logger-packpinno-loggers
The root publisher account, jpeek895, was previously flagged on kmsec.uk for deploying similar malicious packages associated with DPRK campaigns. A wider web of linked maintainer accounts, including pvnd3540749, yggedd817513, and jpeek886, helped propagate and sustain the malicious packages across the ecosystem.
The Execution Flow: From postinstall to Bundled SEA
The entry vector exploits the lifecycle hooks in the npm package manifest. The attackers embed an automatic execution trigger right in package.json.
json{ "name": "terminal-logger-utils", "version": "1.0.0", "description": "A development utility.", "scripts": { "postinstall": "node utils.cjs" } }
When an engineer runs npm install, the postinstall trigger executes utils.cjs. This file serves as an obfuscated dropper responsible for environmental reconnaissance.
- System Fingerprinting: The script interrogates the host operating system to determine platform architecture and target viability.
- Payload Retrieval: The script reaches out to Hugging Face to fetch a platform-specific binary.
- Payload Architecture: The binary is packaged as a Node.js Single Executable Application (SEA). This format bundles the Node runtime and the entire malicious JavaScript implant into a standalone, portable binary that runs out of the box without requiring pre-installed system dependencies.
Hugging Face as Living-off-the-Land Infrastructure
Traditional command-and-control (C2) domains get flagged quickly by threat intelligence feeds. The attackers bypassed this limitation by routing both payload distribution and data exfiltration through Hugging Face.
| Lifecycle Stage | Traditional Attack Pattern | DPRK Campaign Vector | Defensive Impact |
|---|---|---|---|
| Payload Delivery | Custom domains, untrusted file hosts | Hosted binaries on Hugging Face | Bypasses standard domain reputation checks |
| Data Exfiltration | Dedicated C2 servers, TCP sockets | Private Hugging Face Datasets | Traffic blends in with regular HTTPS outbound requests |
| Implant Updates | Static configs, hardcoded fallbacks | Dynamic checks against Hugging Face repos | Allows silent binary replacement without reinfection |
By pushing stolen host telemetry and captured credentials directly to a private dataset on Hugging Face, the threat actors ensure the outbound traffic appears indistinguishable from standard AI developer workflows.
Implant Architecture: Deep Triage of Capabilities
Once the Node.js SEA payload runs on the host, it activates three core subsystems simultaneously: an Infostealer, an interactive RAT, and a background Keylogger.
IMPLANT SUBSYSTEM ARCHITECTURE
[ Node.js SEA Binary ]
│
┌───────────────────────┼───────────────────────┐
▼ ▼ ▼
[ InfoStealer ] [ WebSocket RAT ] [ Background Loop ]
- SSH Keys - Interactive Shell - Keystroke Logging
- Telegram Data - File Read / Write - Clipboard Monitor
- Crypto Wallets - Input Injection - HTTP Telemetry Push
- Browser DBs - Screen Captures
- Cloud Configs & Envs
1. The Multi-Vector Infostealer
The implant scans local storage to harvest high-value credentials:
- Developer Credentials: Cloud configuration files and system-wide environment variables (
.env, shell exports). - Cryptographic Assets: Local cryptocurrency wallet databases.
- Authentication Material: SSH private keys, browser login databases, and local Telegram desktop session data.
2. Interactive WebSocket RAT
The implant opens a bidirectional WebSocket link back to operator-controlled infrastructure. This interactive channel exposes complete machine takeover capabilities:
- Arbitrary shell command execution
- Full filesystem read/write access
- Dynamic desktop screenshot capture
- Remote mouse and keyboard input injection
3. Asynchronous Keystroke and Clipboard Logging
A separate background thread spins up at launch to continuously capture clipboard updates and keypress events. This harvested stream is batched and pushed over HTTP back to the attacker infrastructure without interrupting foreground operations.
Persistence and Auto-Update Mechanics
On Windows systems, the implant secures survival across reboots by embedding itself deep inside the user profile:
- Install Target: The payload drops into
%LOCALAPPDATA%\MicrosoftSystem64, intentionally spoofing Windows system naming conventions. - Primary Execution Hook: A hidden VBS launcher triggered via a configured Scheduled Task.
- Fallback Hook: An added entry inside the standard Registry Run keys to ensure execution if the scheduled task fails.
- Self-Updating Loop: On startup, the binary queries the attacker Hugging Face repository. If a new build is present, it downloads and replaces the local binary, enabling instant capability updates without repeating the initial supply chain vector.
Hardening and Remediation Checklist
If any of these packages were installed in your local dev environments or CI runners, treat the affected systems as fully compromised.
bash# Verify whether poisoned packages exist in your dependency tree npm ls terminal-logger-utils pretty-logger-utils ts-logger-pack pinno-loggers
Immediate Incident Response Actions
- Isolate and Wipe: Terminate active sessions and purge the implant directory located at
%LOCALAPPDATA%\MicrosoftSystem64. Remove associated Scheduled Tasks and Registry Run keys. - Rotate All Secrets: Invalidate every SSH key, cloud access token, database password, and Telegram session touched by the host. Enable MFA on all connected accounts immediately.
- Enforce Strict CI Installs: Mandate
npm ciacross all automation pipelines to guarantee deterministic builds strictly against validated lockfiles, preventing dynamic resolution of poisoned versions. - Block Lifecycle Scripts: Disable untrusted lifecycle hooks during ad-hoc installations by passing the
--ignore-scriptsflag:
bash# Install dependencies safely without running postinstall droppers npm install --ignore-scripts
- Network-Level IoC Blocking: Audit firewall logs for unusual, continuous outbound connections to Hugging Face datasets and block known indicators across all network egress points.
The supply chain surface is no longer confined to code logic bugs. Treat every package install and every trusted cloud ecosystem with the zero-trust boundaries they demand.
References
- Source Report: https://cybersecuritynews.com/hackers-use-hugging-face/
