Compromised AsyncAPI npm Packages Deliver Miasma Botnet Loader

Summary
Socket researchers found compromised AsyncAPI npm releases that run an obfuscated loader when imported, fetch Miasma from IPFS, and can enable remote tasking and persistence. The poisoned source commit was published through GitHub Actions.
Key points
- Affected releases are @asyncapi/generator-helpers@1.1.1, @asyncapi/generator-components@0.7.1, @asyncapi/generator@3.3.1, and @asyncapi/specs@6.11.2 and 6.11.2-alpha.1.
- The injected code runs when an infected module is loaded—not through an npm install hook—and launches a detached Node.js process to fetch a second stage from IPFS.
- The second-stage loader decrypts a Miasma-family framework with command-and-control, shell, file-management, update, and persistence capabilities.
- The recovered configuration identifies npm as the target ecosystem; a safe command exercise demonstrated a Linux systemd user-service persistence mechanism.
- npm provenance points to a GitHub Actions release workflow and a source commit that already contained the implant; public metadata did not reveal the workflow actor or job logs.
- Treat hosts that imported or executed affected versions as potentially compromised; presence in a lockfile alone does not establish execution. Review developer and CI environments for the listed payload and persistence indicators.
Article Details
- Attack Vectors
- A poisoned source commit on refs/heads/next contained implants that the GitHub Actions trusted-publishing workflow built into five malicious releases of four @asyncapi packages. The public workflow actor and job logs could not be recovered from unauthenticated data.
- Importing an infected Node.js module executes obfuscated JavaScript at module load time. It launches a detached, hidden node -e child process without relying on an npm lifecycle script.
- The child process downloads sync.js from a specific IPFS resource, saves it in a directory disguised as Node.js runtime state, and executes it. The downloaded loader decrypts a larger Miasma payload.
- The final payload contains REST-based C2 tasking, file-management and shell-execution handlers, and a persistence writer. In a safe command exercise, the persistence writer produced a Linux systemd user service; this was not an observed write to a real host.
- The decrypted code includes additional channel and ecosystem-propagation modules, but the recovered configuration disables propagation and recon.
- Defensive Notes
- Avoid the affected package versions and upgrade to patched releases when available. Review developer and CI environments that used them.
- An affected version in a lockfile alone does not establish execution. Determine whether a build, CLI, test, application, or developer workflow loaded an infected module; if that cannot be determined, handle the host as exposed.
- Look for node -e processes launched by package code, detached Node.js children, unexpected IPFS requests, and Node.js execution from the listed application-data paths.
- Hunt for connections to 85[.]137[.]53[.]71, unexpected Nostr or DHT traffic from build runners, writes under .config/.miasma or .cache/mesa_shader_cache, and miasma-named systemd user services.
- Install-script blocking alone does not prevent this implant from running when an infected module is later imported. Deleting node_modules alone may not remove a downloaded payload or its persistence artifacts.
Indicators of compromise
| Type | Indicator | Context |
|---|---|---|
| IPV4 | 85[.]137[.]53[.]71 | IP address identified for Miasma C2, upload, and C2 proxy-management services. |
| SHA256 | 082d733db0687dcd768104972b065d4b58cb1e6043688c6c20fa3702337f36ab | Malicious @asyncapi/generator-components@0.7.1 tarball. |
| SHA256 | 24b9ee242f21a73b55f7bb3297eafb33c60840907386b542ed79fc6b72365168 | Malicious IPFS-hosted sync.js payload. |
| SHA256 | 34014776d3d3ff11bc4439b02fd7ac0f02a887eb3a052eeafff236e2f6db8ad1 | Malicious @asyncapi/generator-helpers@1.1.1 tarball. |
| SHA256 | 550af477c12192a22f5c9edb9c8081c0a789b3a1a2992a7ecb157cca1c975e10 | Decoded second-stage downloader. |
| SHA256 | 6e78713b75bd34828d49896176627f7face7aa9036cd874f2e02d9f23a9a9c71 | Infected src/utils.js file. |
| SHA256 | 8351d251cf0b5a0bd82242deaa0a14e3e1394418d55c0f4259dac4303b79fc0c | Infected index.js file. |
| SHA256 | 9b2e65db653ca8575c9b10eefb9a80c6006404812c2ec212bf5675e3c690233b | Malicious @asyncapi/specs@6.11.2 tarball. |
| SHA256 | 9e214f38537e69bf51c7fa1ddd35ae495e9cb897231ec010baf9e4f29407ee9a | Decrypted final Miasma payload. |
| SHA256 | 9f1a709310824f9110c6203d861a721ebefba8b204a8657057fe57efb961c850 | Decrypted baked configuration from the malicious payload. |
| SHA256 | b270bdf8e2274ea1af0a6eed74d8f10e5fe61012d6cc226a43cc7cc7fd9f6292 | Infected lib/utils/ErrorHandling.js file. |
| SHA256 | b9993a8ad0518849416798cf29668256ccb96598fc4423501ccab5312812653a | Infected lib/templates/config/validator.js file. |
| SHA256 | bfaeb987faa6de2b5a5eb63b1233d055215b09b0349a9394f2175fd7cdf385e4 | Malicious @asyncapi/generator@3.3.1 tarball. |
| SHA256 | d425e4583cc6185d41e95c45eda00550045a5d1919b9a012236a4520d009dbd7 | Malicious @asyncapi/specs@6.11.2-alpha.1 tarball. |
| URL | hxxp[:]//85[.]137[.]53[.]71:8080 | Configured Miasma C2 server. |
| URL | hxxp[:]//85[.]137[.]53[.]71:8080/api/v1/beacon | Listed Miasma C2 beacon endpoint. |
| URL | hxxp[:]//85[.]137[.]53[.]71:8080/api/v1/file-content/<cid> | Listed Miasma C2 file-content endpoint template. |
| URL | hxxp[:]//85[.]137[.]53[.]71:8080/api/v1/file-result | Listed Miasma C2 file-result endpoint. |
| URL | hxxp[:]//85[.]137[.]53[.]71:8081 | Configured Miasma upload server. |
| URL | hxxp[:]//85[.]137[.]53[.]71:8091 | Configured Miasma C2 proxy-management server. |
| URL | hxxps[:]//ipfs[.]io/ipfs/QmQobZSp1wRPrpSEQ56qnyq7ecZh5Bg5k1fnjt4SUwwHb9 | Specific IPFS resource from which the first-stage downloader retrieves the malicious sync.js payload. |
MITRE ATT&CK
T1027 · Obfuscated Files or InformationThe injected JavaScript uses encoded strings and a decoder; the downloaded loader contains encrypted payload blobs that it decrypts before execution.T1041 · Exfiltration Over C2 ChannelThe framework includes file retrieval and posts command results to its C2 infrastructure; the article lists C2 file-result and file-content endpoints.T1059.004 · Unix ShellThe decrypted framework has a working ShellExec handler; its Linux service command also invokes a background Node.js process through shell syntax.T1059.007 · JavaScriptInjected JavaScript executes when an affected Node.js module is loaded and starts the next stage with node -e.T1102 · Web ServiceThe package-stage downloader uses an IPFS gateway resource to obtain the off-registry malware payload.T1105 · Ingress Tool TransferThe package-stage downloader retrieves the malicious sync.js loader from an IPFS resource onto the host.T1195.002 · Compromise Software Supply ChainA poisoned AsyncAPI source commit was built and published as compromised npm package releases through the trusted-publishing workflow.T1543.002 · Systemd ServiceA safe exercise of the payload's persistence writer produced a miasma-monitor systemd user unit and commands to enable it.T1564.001 · Hidden Files and DirectoriesThe payload uses hidden .miasma state paths and a camouflaged .cache/mesa_shader_cache runtime path.
Malware
Vendors
AsyncAPISocket's Threat Research Team identified four compromised npm packages in the @asyncapi namespace distributing a multi-stage botnet loader. The affected packages are @asyncapi/generator-helpers@1.1.1,GitHubThe npm metadata attributes all three publishes to GitHub Actions <npm-oidc-no-reply@github.com> through npm trusted publishing. The three package records share:npmSocket's Threat Research Team identified four compromised npm packages in the @asyncapi namespace distributing a multi-stage botnet loader. The affected packages are @asyncapi/generator-helpers@1.1.1,
Products
@asyncapi/generatorin the @asyncapi namespace distributing a multi-stage botnet loader. The affected packages are @asyncapi/generator-helpers@1.1.1, @asyncapi/generator-components@0.7.1, @asyncapi/generator@3.3.1 ,@asyncapi/generator-componentsa multi-stage botnet loader. The affected packages are @asyncapi/generator-helpers@1.1.1, @asyncapi/generator-components@0.7.1, @asyncapi/generator@3.3.1 , @asyncapi/specs(v6.11.2, v6.11.2-alpha.1)@asyncapi/generator-helpersin the @asyncapi namespace distributing a multi-stage botnet loader. The affected packages are @asyncapi/generator-helpers@1.1.1, @asyncapi/generator-components@0.7.1, @asyncapi/generator@3.3.1 ,@asyncapi/specs@asyncapi/generator-helpers@1.1.1, @asyncapi/generator-components@0.7.1, @asyncapi/generator@3.3.1 , @asyncapi/specs(v6.11.2, v6.11.2-alpha.1)GitHub ActionsThe npm metadata attributes all three publishes to GitHub Actions <npm-oidc-no-reply@github.com> through npm trusted publishing. The three package records share:Node.jspreinstall, postinstall, or any package lifecycle script. It runs when the infected module is loaded by Node.js, then launches a detached background node -e process that downloads and executes a much larger payloadnpmSocket's Threat Research Team identified four compromised npm packages in the @asyncapi namespace distributing a multi-stage botnet loader. The affected packages are @asyncapi/generator-helpers@1.1.1,