DEV#POPPER RAT Delivered Through Compromised Joyfill npm Releases
Detection stack
- AIDR
- Alert
- ETL
- Query
Summary
Two compromised beta releases of the @joyfill npm package were found containing an import-time JavaScript implant. The implant uses blockchain transactions across Tron, Aptos, and BNB Smart Chain to resolve and download the DEV#POPPER remote access trojan (RAT). The campaign targets developer workstations and CI/CD pipelines by executing malicious code as soon as the affected module is imported.
Investigation
The Socket Research Team uncovered the compromise while analyzing beta versions of @joyfill/layouts and @joyfill/components. Researchers identified a multi-stage payload delivery chain that combined obfuscated JavaScript with blockchain-backed dispatch mechanisms. The investigation linked the initial loader to the PolinRider family and confirmed that the final payload belonged to the DEV#POPPER malware family.
Mitigation
Developers should immediately remove the affected @joyfill beta versions from lockfiles, package caches, build environments, and deployment artifacts. Pinning dependencies to verified releases such as @joyfill/layouts@0.1.1 or @joyfill/components@4.0.0-rc24 is recommended. Security teams should also block the compromised versions through registry proxies and dependency governance tools.
Response
Any system that imported the affected packages should be isolated, and all credentials accessible to the compromised Node.js process should be rotated. Investigators should inspect developer applications, including VS Code, GitHub Desktop, and Discord, for unexpected changes to core modules. Endpoint and CI/CD telemetry should also be reviewed for detached Node.js processes, known C2 addresses, and suspicious blockchain RPC traffic.
Attack Flow
Detections
Possible Publicnode Ethereum Abuse Attempt As C2 Channel (via dns_query)
View
Possible IP Lookup Domain Communications Attempted (via dns)
View
Possible Linux Screenshot was Taken (via cmdline)
View
Hidden File Was Created On Linux Host (via file_event)
View
IOCs (HashSha256) to detect: Two Joyfill npm Beta Releases Compromised to Deliver DEV#POPPER Remote Access Trojan
View
IOCs (SourceIP) to detect: Two Joyfill npm Beta Releases Compromised to Deliver DEV#POPPER Remote Access Trojan
View
IOCs (DestinationIP) to detect: Two Joyfill npm Beta Releases Compromised to Deliver DEV#POPPER Remote Access Trojan
View
Detection of DEV#POPPER Malware Indicators [Windows Network Connection]
View
Detection of Compromised Joyfill npm Packages Delivering Remote Access Trojan [Linux File Event]
View
Detection of Node.js Module Injection and Detached Process Execution [Linux Process Creation]
View
Simulation Execution
Prerequisite: The Telemetry & Baseline Pre-flight Check must have passed.
Rationale: This section details the precise execution of the adversary technique (TTP) designed to trigger the detection rule. The commands and narrative MUST directly reflect the TTPs identified and aim to generate the exact telemetry expected by the detection logic. Abstract or unrelated examples will lead to misdiagnosis.
-
Attack Narrative & Commands: The adversary has successfully injected malicious code into a widely used npm dependency (Supply Chain Compromise). When a developer runs
npm installor starts a project, the malicious script executes. The script first attempts to hide its intent by assigning therequirefunction to a global variable (global.r = require), allowing it to load modules anywhere in the application without callingrequiredirectly (obfuscation). Finally, it useschild_process.spawnto launch a detached shell process that connects back to a Command & Control (C2) server, attempting to evade detection by decoupling the malicious process from the parent Node.js process. -
Regression Test Script:
#!/bin/bash # Simulation script to trigger the Node.js injection detection rule. # This script creates a temporary malicious JS file and executes it via Node.js. MALICIOUS_FILE="malicious_pkg.js" echo "[+] Creating malicious Node.js script..." cat << 'EOF' > $MALICIOUS_FILE // Simulate global module injection (T1027) global.r = require; // Simulate detached process execution via child_process.spawn (T1059.006) const cp = require('child_process'); cp.spawn('bash', ['-c', 'sleep 30 &'], { detached: true, stdio: 'ignore' }); console.log("[!] Malicious payload executed."); EOF echo "[+] Executing malicious script via Node.js..." node $MALICIOUS_FILE echo "[+] Simulation complete. Check SIEM for Alert: Detection of Node.js Module Injection and Detached Process Execution." -
Cleanup Commands:
# Remove the simulated malicious file rm -f malicious_pkg.js # Kill any orphaned sleep processes spawned by the simulation pkill -f "sleep 30"