Compromised npm Packages in the AsyncAPI Namespace Deliver Miasma Botnet Loader
Socket's Threat Research Team identified four compromised npm packages in the @asyncapi namespace delivering a multi-stage botnet loader called Miasma. The attack injects obfuscated JavaScript into package source files that executes at module load time (bypassing npm lifecycle script blocking), spawns a detached Node.js process to download an encrypted payload from IPFS, and deploys a 3+ MB tasking framework with multi-channel C2 capabilities including HTTP, Nostr, IPFS, and Ethereum RPC. The malicious packages were published via GitHub Actions trusted publishing from a compromised source commit on the 'next' branch.
- ip85[.]137[.]53[.]71Primary C2 infrastructure hosting HTTP C2 server (port 8080), upload server (port 8081), and proxy management (port 8091) for the Miasma tasking framework
- sha256082d733db0687dcd768104972b065d4b58cb1e6043688c6c20fa3702337f36abSHA-256 hash of @asyncapi/[email protected] npm tarball
- sha25624b9ee242f21a73b55f7bb3297eafb33c60840907386b542ed79fc6b72365168SHA-256 hash of the IPFS-delivered sync.js encrypted loader (8.25 MB) containing AES-256-GCM decryption wrapper and baked configuration
- sha25634014776d3d3ff11bc4439b02fd7ac0f02a887eb3a052eeafff236e2f6db8ad1SHA-256 hash of @asyncapi/[email protected] npm tarball
- sha256550af477c12192a22f5c9edb9c8081c0a789b3a1a2992a7ecb157cca1c975e10SHA-256 hash of the decoded second-stage JavaScript downloader that retrieves sync.js from IPFS
- sha2566e78713b75bd34828d49896176627f7face7aa9036cd874f2e02d9f23a9a9c71SHA-256 hash of infected src/utils.js in @asyncapi/[email protected]
- sha2568351d251cf0b5a0bd82242deaa0a14e3e1394418d55c0f4259dac4303b79fc0cSHA-256 hash of infected index.js in @asyncapi/specs packages
- sha2569b2e65db653ca8575c9b10eefb9a80c6006404812c2ec212bf5675e3c690233bSHA-256 hash of @asyncapi/[email protected] npm tarball
- sha2569e214f38537e69bf51c7fa1ddd35ae495e9cb897231ec010baf9e4f29407ee9aSHA-256 hash of the decrypted final Miasma tasking framework payload (3.09 MB of JavaScript)
- sha2569f1a709310824f9110c6203d861a721ebefba8b204a8657057fe57efb961c850SHA-256 hash of the decrypted baked configuration blob from the Miasma loader
- sha256b270bdf8e2274ea1af0a6eed74d8f10e5fe61012d6cc226a43cc7cc7fd9f6292SHA-256 hash of infected lib/utils/ErrorHandling.js in @asyncapi/[email protected]
- sha256b9993a8ad0518849416798cf29668256ccb96598fc4423501ccab5312812653aSHA-256 hash of infected lib/templates/config/validator.js in @asyncapi/[email protected]
- sha256bfaeb987faa6de2b5a5eb63b1233d055215b09b0349a9394f2175fd7cdf385e4SHA-256 hash of @asyncapi/[email protected] npm tarball
- sha256d425e4583cc6185d41e95c45eda00550045a5d1919b9a012236a4520d009dbd7SHA-256 hash of @asyncapi/[email protected] npm tarball
- urlhxxp://85[.]137[.]53[.]71:8080/api/v1/beaconC2 beaconing endpoint where Miasma implant checks in for encrypted tasking
- urlhxxp://85[.]137[.]53[.]71:8080/api/v1/file-resultC2 endpoint for posting command execution results back to attacker infrastructure
- urlhxxp://85[.]137[.]53[.]71:8081Upload server endpoint for exfiltrating files from compromised hosts
- urlhxxp://85[.]137[.]53[.]71:8091C2 proxy management endpoint for managing proxy infrastructure
- urlhxxps://ipfs[.]io/ipfs/QmQobZSp1wRPrpSEQ56qnyq7ecZh5Bg5k1fnjt4SUwwHb9IPFS gateway URL used by stage 2 downloader to retrieve the encrypted Miasma sync.js loader payload (8.25 MB)
Detection / Hunteropenrouter
What Happened
Several popular programming packages used by JavaScript developers were compromised to secretly deliver malicious software called Miasma through the official npm package registry. The malicious code hides inside legitimate package files and runs when developers use these packages in their code, not just when they install them, which means standard security checks that focus on installation scripts would not catch it. This matters because the attack was published through trusted channels with security provenance, yet the provenance only verifies the build process, not whether the source code itself was safe. The malicious software can take over computers, execute commands, steal files, and spread to other systems. Organizations using the affected package versions should remove them immediately, upgrade to safe versions, and check their systems for signs of infection.
Key Takeaways
- Four compromised npm packages in @asyncapi namespace deliver Miasma botnet loader through injected source code (not lifecycle hooks), executing at module load time
- Multi-stage attack: obfuscated JS spawns detached node -e process, downloads encrypted payload from IPFS, decrypts 8.25 MB Miasma tasking framework with AES-256-GCM and ROT94
- Miasma framework supports multi-channel C2 (HTTP, Nostr, IPFS, Ethereum RPC, BitTorrent DHT), file management, shell execution, and systemd persistence on Linux
- Attack bypasses npm install-script blocking because malicious code runs on import, not during install; trusted-publishing provenance does not verify source integrity
- Five malicious package versions identified: @asyncapi/[email protected], @asyncapi/[email protected], @asyncapi/[email protected], @asyncapi/[email protected], @asyncapi/[email protected]
Affected Systems
- Node.js environments importing @asyncapi packages (all platforms)
- npm package consumers including developer workstations, CI/CD pipelines, and production systems
- Linux systems targeted for systemd user service persistence
- Windows systems targeted for %LOCALAPPDATA% persistence
- macOS systems targeted for ~/Library/Application Support persistence
Vulnerabilities (CVEs)
None identified.
Attack Chain
- Initial Access: Malicious npm packages published to @asyncapi namespace via compromised GitHub trusted-publishing workflow from poisoned commit on refs/heads/next branch
- Execution: Obfuscated JavaScript in package source files spawns detached node -e process with hidden window and ignored stdio at module load time
- Ingress Tool Transfer: Stage 2 downloader retrieves encrypted sync.js (8.25 MB) from IPFS gateway and writes it to fake NodeJS directory in user application data
- Defense Evasion: sync.js loader decrypts final payload using HKDF-SHA256 key derivation, AES-256-GCM authenticated decryption, and ROT94 character transform before eval()
- Persistence: Miasma framework writes systemd user service (miasma-monitor.service) on Linux and lock file to ~/.config/.miasma/run/node.lock
- C2 and Actions: Miasma tasking framework beacons to HTTP C2 at 85.137.53.71:8080 and supports file management, shell execution, data collection, and multi-channel C2 via Nostr, IPFS, and Ethereum RPC
Detection Availability
- YARA Rules: No
- Sigma Rules: No
- Snort/Suricata Rules: No
- KQL Queries: No
- Splunk SPL Queries: No
- EQL Queries: No
- Other Detection Logic: No
The article provides IOCs (package names, hashes, network indicators, file paths) and behavioral detection indicators but does not include formal YARA, Sigma, Snort/Suricata, KQL, SPL, or EQL rules. Socket AI Scanner is mentioned as having detected the malicious package, but no rule content is provided.
Detection Engineering Assessment
| Dimension | Rating | Rationale |
|---|---|---|
| EDR Visibility | Medium | The attack uses legitimate Node.js processes and APIs which may not trigger EDR alerts by default. However, detached child processes with hidden windows and ignored stdio, spawned from package code at import time, are anomalous behaviors that EDR can detect. systemd user service creation on Linux is also visible to EDR. |
| Network Visibility | Medium | C2 traffic uses HTTP (not HTTPS) to a raw IP address on non-standard ports, which is detectable by network monitoring. IPFS gateway requests and Nostr relay connections from build/CI environments are unusual. However, decentralized protocol traffic (IPFS, Nostr, DHT) may bypass traditional network controls focused on domain-based filtering. |
| Detection Difficulty | Moderate | The initial compromise is difficult to detect because it uses legitimate Node.js APIs and runs within expected package execution context. However, the C2 traffic to a raw IP address, creation of systemd services with miasma naming, file writes to fake NodeJS directories, and IPFS/Nostr traffic from build runners are more detectable with appropriate telemetry. |
Required Log Sources
- Process creation logs (Sysmon Event ID 1 on Windows, auditd on Linux)
- Process command line logging
- Network connection logs (Sysmon Event ID 3, firewall/IDS logs, NetFlow)
- File system monitoring (Sysmon Event ID 11, EDR file write telemetry)
- npm install logs and package-lock.json change tracking
- systemd journal logs for user service creation
- DNS resolution logs for IPFS gateway and Nostr relay lookups
Hunting Hypotheses
| Hypothesis | Telemetry | ATT&CK Stage | FP Risk |
|---|---|---|---|
| Consider hunting for Node.js child processes spawned with the -e flag from package code in a detached configuration with hidden windows and ignored standard streams, which would indicate malicious code execution at module load time (T1059.007) | Process creation logs (Sysmon Event ID 1, EDR process telemetry), process command line logging | Execution | Low - legitimate Node.js applications rarely spawn detached processes with hidden windows and ignored stdio from package import paths |
| Consider hunting for outbound HTTP connections to raw IP addresses on non-standard ports from Node.js processes or CI/build environments, which would indicate C2 beaconing to attacker infrastructure (T1041, T1102) | Network connection logs (Sysmon Event ID 3, firewall logs, IDS/IPS alerts, NetFlow) | Command and Control | Low-Medium - some CI tools may connect to raw IPs, but non-standard ports from Node.js processes are unusual |
| Consider hunting for file writes to directories named NodeJS in user application data paths containing a file named sync.js, which would indicate the Miasma stage 2 payload being dropped (T1105, T1564.001) | File system monitoring (Sysmon Event ID 11, EDR file write telemetry), file integrity monitoring | Ingress Tool Transfer | Low - the specific combination of a NodeJS directory in application data with a sync.js file is distinctive |
| Consider hunting for systemd user service creation with names containing miasma or descriptions containing miasma-monitor, which would indicate Miasma persistence on Linux hosts (T1543.002) | systemd journal logs, auditd, EDR Linux telemetry, file system monitoring for ~/.config/systemd/user/ writes | Persistence | Very Low - the miasma naming is distinctive and unlikely to appear in legitimate services |
| Consider hunting for outbound connections to IPFS gateways, Nostr relay endpoints, or BitTorrent DHT nodes from CI/build runner environments where such protocols are not expected, which would indicate Miasma multi-channel C2 activity (T1102) | Network connection logs, DNS logs, proxy logs, IDS/IPS alerts for decentralized protocol traffic | Command and Control | Medium - some development tools may use IPFS or decentralized protocols legitimately; context of build runner environment is important |
Control Gaps
- npm lifecycle script blocking alone would not prevent execution when the infected module is imported by application code, tests, or build scripts
- Static analysis of package.json alone would not detect malicious code injected into source files within the package
- Trusted-publishing provenance verifies build and publish identity but does not verify source code integrity
- Traditional signature-based AV may not detect obfuscated JavaScript payloads using hex-like variable names and base64-encoded string tables
- Network controls focused on domain-based blocking may miss C2 traffic to raw IP addresses on non-standard ports
Key Behavioral Indicators
- node -e child processes spawned from package code with detached:true, windowsHide:true, and stdio:ignore options
- File writes to fake NodeJS directories in user application data paths (e.g., %LOCALAPPDATA%\NodeJS\sync.js, ~/.local/share/NodeJS/sync.js)
- systemd user service named miasma-monitor.service with description miasma-monitor
- Outbound HTTP connections to raw IP address on ports 8080, 8081, or 8091 from Node.js processes
- File writes under .config/.miasma/ or .cache/mesa_shader_cache/ directories
- Obfuscated JavaScript with hex-like variable names (e.g., _0x1dd48b) and base64-encoded string tables in package source files
- IPFS gateway requests from CI/build runner environments where such traffic is not expected
- Infected source files within packages: src/utils.js, lib/utils/ErrorHandling.js, lib/templates/config/validator.js, index.js
False Positive Assessment
Low - The IOCs are highly specific (particular npm package versions, C2 IP address, file hashes, file paths with miasma naming). The behavioral indicators (detached Node.js processes with hidden windows, IPFS requests from build runners, systemd services with miasma naming) have low false positive rates in typical environments. The narrowest indicator (miasma in service names and file paths) is unlikely to appear in legitimate software.
Recommendations
Immediate Mitigation
- Verify against your organization's incident response runbook and team escalation paths before acting. Identify and remove all affected npm package versions from package-lock.json, yarn.lock, and npm cache across development, CI/CD, and production environments.
- Consider identifying any hosts that imported or executed affected package versions and treat them as potentially compromised, as mere presence in a lockfile does not prove execution.
- If your EDR supports host isolation, consider isolating systems that executed the malicious packages pending further investigation.
- Consider blocking network connections to 85.137.53.71 on ports 8080, 8081, and 8091 at perimeter controls if consistent with your network security policy.
Infrastructure Hardening
- Evaluate whether your CI/CD pipelines can enforce package version pinning and automated vulnerability scanning for npm dependencies.
- Consider implementing package integrity verification beyond npm lifecycle scripts, as this attack bypasses install-hook monitoring by executing at import time.
- Evaluate whether your organization can adopt software composition analysis (SCA) tools that inspect package source code, not just metadata.
- If applicable, consider monitoring for and alerting on IPFS gateway, Nostr relay, or DHT traffic from build runners where such protocols are not expected.
User Protection
- Consider deploying EDR detections for detached Node.js child processes with hidden windows and ignored standard streams spawned from package code.
- Evaluate whether your endpoint protection can alert on file writes to fake NodeJS application data directories (e.g., %LOCALAPPDATA%\NodeJS\sync.js).
- On Linux systems, consider monitoring for systemd user service creation, particularly services with 'miasma' in the name or description.
- Consider rolling out detections for outbound HTTP connections to raw IP addresses on non-standard ports from Node.js processes.
Security Awareness
- Consider reminding developers that npm package provenance does not guarantee source integrity, and that importing untrusted packages carries execution risk beyond install time.
- Where supported by your training program, consider adding guidance on reviewing package diffs and monitoring for obfuscated code in dependencies.
- Consider informing development teams about the affected AsyncAPI package versions and the importance of upgrading to patched releases when available.
MITRE ATT&CK Mapping
Initial Access
Execution
Persistence
Command and Control
Exfiltration
Additional IOCs
- Urls:
hxxp://85[.]137[.]53[.]71:8080/api/v1/beacon- C2 beaconing endpoint where Miasma implant checks in for encrypted taskinghxxp://85[.]137[.]53[.]71:8080/api/v1/file-result- C2 endpoint for posting command execution results back to attacker infrastructurehxxp://85[.]137[.]53[.]71:8081- Upload server endpoint for exfiltrating files from compromised hostshxxp://85[.]137[.]53[.]71:8091- C2 proxy management endpoint for managing proxy infrastructurewss://relay[.]damus[.]io- Nostr relay used as alternative C2 communication channel by Miasma frameworkwss://relay[.]nostr[.]com- Nostr relay used as alternative C2 communication channel by Miasma framework
- File Hashes:
34014776d3d3ff11bc4439b02fd7ac0f02a887eb3a052eeafff236e2f6db8ad1(SHA256) - SHA-256 hash of @asyncapi/[email protected] npm tarball082d733db0687dcd768104972b065d4b58cb1e6043688c6c20fa3702337f36ab(SHA256) - SHA-256 hash of @asyncapi/[email protected] npm tarballbfaeb987faa6de2b5a5eb63b1233d055215b09b0349a9394f2175fd7cdf385e4(SHA256) - SHA-256 hash of @asyncapi/[email protected] npm tarball9b2e65db653ca8575c9b10eefb9a80c6006404812c2ec212bf5675e3c690233b(SHA256) - SHA-256 hash of @asyncapi/[email protected] npm tarballd425e4583cc6185d41e95c45eda00550045a5d1919b9a012236a4520d009dbd7(SHA256) - SHA-256 hash of @asyncapi/[email protected] npm tarball6e78713b75bd34828d49896176627f7face7aa9036cd874f2e02d9f23a9a9c71(SHA256) - SHA-256 hash of infected src/utils.js in @asyncapi/[email protected]b270bdf8e2274ea1af0a6eed74d8f10e5fe61012d6cc226a43cc7cc7fd9f6292(SHA256) - SHA-256 hash of infected lib/utils/ErrorHandling.js in @asyncapi/[email protected]b9993a8ad0518849416798cf29668256ccb96598fc4423501ccab5312812653a(SHA256) - SHA-256 hash of infected lib/templates/config/validator.js in @asyncapi/[email protected]8351d251cf0b5a0bd82242deaa0a14e3e1394418d55c0f4259dac4303b79fc0c(SHA256) - SHA-256 hash of infected index.js in @asyncapi/specs packages9f1a709310824f9110c6203d861a721ebefba8b204a8657057fe57efb961c850(SHA256) - SHA-256 hash of the decrypted baked configuration blob from the Miasma loader
- File Paths:
%LOCALAPPDATA%\NodeJS\sync.js- Windows path where stage 2 IPFS downloader writes the Miasma sync.js payload~/Library/Application Support/NodeJS/sync.js- macOS path where stage 2 IPFS downloader writes the Miasma sync.js payload~/.local/share/NodeJS/sync.js- Linux path where stage 2 IPFS downloader writes the Miasma sync.js payload~/.config/node/sync.js- Fallback path (other platforms) where stage 2 IPFS downloader writes the Miasma sync.js payload~/.config/.miasma/run/node.lock- Linux lock file created by Miasma runtime to prevent duplicate instances~/.cache/mesa_shader_cache/gl_cache.bin- Camouflaged runtime file written by Miasma update handler disguised as Mesa shader cache~/.config/systemd/user/miasma-monitor.service- Linux systemd user service unit file created for Miasma persistence across reboots~/.cache/.sys_cache/.diag.enc- Encrypted file written by Miasma payload under disguised system cache directory
- Command Lines:
- Purpose: Execute inline JavaScript stage 2 downloader in a detached, hidden background process at module load time | Tools:
node| Stage: Execution |node -e - Purpose: Execute the downloaded Miasma sync.js payload from a fake NodeJS directory in a detached background process | Tools:
node| Stage: Execution |node <target_file> - Purpose: Reload systemd user service configuration after writing miasma-monitor.service unit file | Tools:
systemctl| Stage: Persistence |systemctl --user daemon-reload - Purpose: Enable miasma-monitor systemd user service for persistence across reboots | Tools:
systemctl| Stage: Persistence |systemctl --user enable
- Purpose: Execute inline JavaScript stage 2 downloader in a detached, hidden background process at module load time | Tools:
- Other:
@asyncapi/[email protected]- Fifth compromised npm package version with injected malicious code in index.jsQmQobZSp1wRPrpSEQ56qnyq7ecZh5Bg5k1fnjt4SUwwHb9- IPFS content identifier (CID) for the encrypted Miasma sync.js loader payload retrievable from any IPFS gateway04166c33b1bcbd7a76bc68d1e4a5b795f334e5bd9c64007b1c30715b1b1044fd6d7490cd5e6e69b9b5988049cf707bc1f58b9ace7255b00ad4425760180a2d8723- Elliptic-curve parent public key embedded in Miasma tasking framework for cryptographic verification0432fa4ba871877d94081fe83323fa24dfa1491e9de8725cbab7b734de9e9be3b233ef6742fd6264437c9532223d687b05fa540b70af6a516b8539af84d0eeb48e- Elliptic-curve baked operator public key embedded in Miasma tasking framework for command authentication