StepSecurity Details Import-Triggered RAT in Compromised Joyfill npm Packages

· Original article ↗

Summary

StepSecurity found six 2773 prereleases of @joyfill/components and @joyfill/layouts contained an import-triggered payload with blockchain-based C2, a Socket.IO RAT, persistence and a Python credential stealer. Sandbox runs saw no C2 callback.

Key points

  • The affected releases are @joyfill/components 4.0.0-rc24-2773-beta.4, .beta.5 and .beta.6, and @joyfill/layouts 0.1.2-2773.beta.0, .beta.1 and .beta.2.
  • The obfuscated payload runs when an application imports the package; neither package has an install hook, so npm install --ignore-scripts does not prevent execution.
  • StepSecurity traced a multi-stage chain that resolves C2 information through blockchain transactions, with an Aptos fallback, before launching a Socket.IO remote access trojan.
  • The RAT supports host fingerprinting, arbitrary JavaScript execution, file transfers, directory listing and clipboard theft.
  • The malware can inject a self-reloading loader into developer applications and the global npm CLI, enabling persistence and worm-like propagation.
  • A staged Python stealer targets browser data, credentials, wallet and password-manager data, Git credentials and OS keychains. StepSecurity says it sandboxed all six versions and confirmed injected code by diffing bundles, but observed no outbound C2 callout; its proposed explanation that the C2 configuration had been taken down is speculative.
  • StepSecurity advises removing the affected releases, reinstalling from a clean lockfile, checking developer-tool files and network logs, and rotating credentials present on affected machines.

Article Details

Attack Vectors
  • Malicious beta releases of @joyfill/components (4.0.0-rc24-2773-beta.4, .5, and .6) and @joyfill/layouts (0.1.2-2773.beta.0, .1, and .2) carried an obfuscated payload in their built bundles.
  • The payload executes when an application imports the package; it is not an install hook, so --ignore-scripts does not prevent execution.
  • A blockchain-based resolver retrieves and decrypts staged code using Tron and BNB Smart Chain transactions, with Aptos as a fallback pointer channel.
  • The staged Socket.IO agent provides remote command execution, host and directory information, file transfer, clipboard collection, and C2 redirection.
  • The agent reinjects a loader into developer application files and the global npm CLI, causing it to run again when those applications or npm are invoked.
  • A staged Python infostealer collects browser data, extension wallets, password-manager data, Git and GitHub CLI credentials, and OS keychains, then uploads an encrypted archive to the C2.
Defensive Notes
  • Check lockfiles and environments for any 2773 prerelease of either package; remove affected versions, delete node_modules, and reinstall from a clean lockfile using a known-good release published before July 28, 2026.
  • On machines that imported an affected package, inspect the listed VS Code, Cursor, Antigravity, Discord, GitHub Desktop, and global npm CLI files for the campaign's injected marker blocks; reinstall affected applications if markers are found.
  • Treat affected developer machines and CI/CD environments as compromised, and rotate credentials present on those systems, including browser secrets, Git and GitHub tokens, npm tokens, and wallet keys.
  • Review outbound network logs for the listed C2 addresses and unusual blockchain-lookup traffic from Node.js processes; use egress baselining or allowlisting and file-integrity monitoring.

Indicators of compromise

TypeIndicatorContext
IPV4166[.]88[.]134[.]62Campaign-specific C2 address used by the npm payload for its Socket.IO and upload endpoints.
IPV4198[.]105[.]127[.]210C2 host used by the malware's numeric-campaign branch and second downloader.
IPV423[.]27[.]13[.]43C2 infrastructure identified in the article as serving the /$/boot path.
IPV423[.]27[.]202[.]27Campaign-specific C2 address configured by the malware for an alternate campaign branch.
SHA25626351aed0397158d3a3b8cc8fd3047d4c015d264c9895f10f20f1521b974ed18SHA-256 hash identified for the final Socket.IO RAT.
SHA25636ff00b45e67baa7e3674b0c80f48e88737264c61e5c6b3b091200972de8157cSHA-256 hash identified for the Python credential stealer.

MITRE ATT&CK

T1005 · Data from Local SystemThe Python stealer collects browser data, credentials, extension-wallet data, and OS keychain data from the workstation.T1027 · Obfuscated Files or InformationThe package payload uses shuffled strings, compressed token streams, and layered obfuscation to conceal its stages.T1041 · Exfiltration Over C2 ChannelThe malware uploads collected files and the encrypted credential archive to its C2.T1059.006 · PythonThe agent spawns Python to run the staged credential stealer.T1059.007 · JavaScriptThe loader and staged agent execute JavaScript, including code resolved from blockchain transactions and arbitrary JavaScript received by the RAT.T1071.001 · Web ProtocolsThe RAT communicates with its campaign C2 using a Socket.IO channel over HTTP.T1082 · System Information DiscoveryThe agent fingerprints the host by collecting operating system, hostname, username, and release information.T1105 · Ingress Tool TransferThe malware uses staged downloaders to retrieve boot and subsequent payload code.T1115 · Clipboard DataThe RAT's ss_cb command collects clipboard contents using platform-specific commands.T1140 · Deobfuscate/Decode Files or InformationThe loader decodes and decompresses hidden JavaScript in memory before executing subsequent stages.T1195.002 · Compromise Software Supply ChainThe attacker injected an obfuscated payload into published beta tarballs of the two Joyfill npm packages.T1555.001 · KeychainThe stealer collects OS keychain data from affected workstations.T1555.003 · Credentials from Web BrowsersThe stealer collects browser data and stored browser secrets.T1555.005 · Password ManagersThe article reports collection of password-manager data by the Python stealer.T1573.001 · Symmetric CryptographyThe resolver XOR-decrypts transaction data obtained through the blockchain-based C2 pointer chain.

Vendors

Products

@joyfill/componentsOn July 28, 2026, malicious beta versions of two Joyfill npm packages, @joyfill/components and @joyfill/layouts, were published to the npm registry. Both versions carry the same heavily obfuscated payload injected into@joyfill/layoutsOn July 28, 2026, malicious beta versions of two Joyfill npm packages, @joyfill/components and @joyfill/layouts, were published to the npm registry. Both versions carry the same heavily obfuscated payload injected intoAntigravitythat developer tools run routinely, including the @vscode/deviceid module used by VS Code, Cursor, and Antigravity, the Discord desktop core module, GitHub Desktop main.js, and the global npm CLI. Injected blocks areCursorinto files that developer tools run routinely, including the @vscode/deviceid module used by VS Code, Cursor, and Antigravity, the Discord desktop core module, GitHub Desktop main.js, and the global npm CLI.Discordtools run routinely, including the @vscode/deviceid module used by VS Code, Cursor, and Antigravity, the Discord desktop core module, GitHub Desktop main.js, and the global npm CLI. Injected blocks are idempotent,GitHub Desktop@vscode/deviceid module used by VS Code, Cursor, and Antigravity, the Discord desktop core module, GitHub Desktop main.js, and the global npm CLI. Injected blocks are idempotent, guarded by comment sentinelsNode.jswhen an application imports the package, so npm install --ignore-scripts does not stop it. It exposes Node.js require and module on the global object, resolves a command and control server through a publicnpmOn July 28, 2026, malicious beta versions of two Joyfill npm packages, @joyfill/components and @joyfill/layouts, were published to the npm registry. Both versions carry the same heavily obfuscated payload injected intoVS Codeblock into files that developer tools run routinely, including the @vscode/deviceid module used by VS Code, Cursor, and Antigravity, the Discord desktop core module, GitHub Desktop main.js, and the global npm

Tools

Related Articles