Malware Discovered in Imitation Puppeteer Packages

A typosquatting campaign published malicious npm packages impersonating Puppeteer and crypto libraries; postinstall hooks and obfuscated JavaScript fetch and execute remote payloads during installation. The installer code uses an Ethereum smart contract to retrieve IP addresses for payload hosting, allowing the operator to change infrastructure without updating the packages. #Puppeteer #daun124wdsa8

Keypoints

  • Attackers published typosquat npm packages targeting Puppeteer and multiple cryptocurrency-related libraries to trick developers into installation.
  • Early package “daun124wdsa8” included a postinstall script that attempted to run clzypp8j.js during installation.
  • Other packages contained obfuscated JavaScript that constructs download URLs, fetches remote executables, and executes them.
  • The malware queries an Ethereum smart contract (0xa1b40044EBc2794f207D45143Bd82a1B86156c6b) via ethers.js to retrieve an IP address used as the payload host.
  • Downloaded binaries are launched detached (background) and configure persistence (add to startup); the payload fetches additional JS and posts system information back to the server.
  • The campaign is active and widespread, with many similarly-named packages published (~219 additional typosquats observed).

MITRE Techniques

  • [T1203] Typosquatting – Attackers publish malicious packages with names similar to legitimate software to trick developers into installation. [‘Attackers publish malicious packages with names similar to legitimate software to trick developers into installation.’]
  • [T1059] Command and Scripting Interpreter – Malicious scripts are executed during the package installation via npm postinstall hooks. [‘Malicious scripts are executed during the installation of the packages.’]
  • [T1547] Startup Items – The delivered binary adds itself to start on login to maintain persistence on infected systems. [‘Malware adds itself to startup to maintain persistence on the infected machine.’]
  • [T1041] Exfiltration Over Command and Control Channel – The payload collects system information (GPU, CPU, memory, username, OS) and posts it back to the attacker’s server. [‘Malware sends system information back to the attacker’s server.’]

Indicators of Compromise

  • IP addresses (payload hosts) – 193.233.201.21:3001, 194.53.54.188:3001, and 3 more IP:port entries.
  • Ethereum contract (control channel) – 0xa1b40044EBc2794f207D45143Bd82a1B86156c6b (used with getString to retrieve IP addresses).
  • File hashes – 7ac12ba9822df1f6652fd3dd67f61e026719a76a, 5ded160d97657902a14ecca95acfb01c7bf957d1, and 1 more hash.
  • Package names (typosquats) – daun124wdsa8, pupeter, pupetier, and many others (≈219 additional packages observed).
  • File names / scripts – package.json postinstall invoking clzypp8j.js; downloader filenames like node-win.exe, node-linux, node-macos (OS-specific payload names).

The installation-time payload is an obfuscated Node.js script executed from an npm postinstall hook. It requires ethers.js and axios, defines an ABI for a getString(address) view function, and connects to the Ethereum mainnet via ethers.getDefaultProvider to create a contract instance for address 0xa1b40044EBc2794f207D45143Bd82a1B86156c6b. The script calls contract.getString with a provided account ID to retrieve a string containing the IP:port of the payload server; Ethereum’s immutable history is then used by the attacker to rotate hosts without changing package code.

After obtaining the host address, the script builds an OS-specific download URL (e.g., host/node-win.exe, host/node-linux, host/node-macos), downloads the binary to the system tmp directory, sets execute permissions on non-Windows platforms, and launches it detached using child_process.spawn with unref() so it runs in the background. Error handling in the async functions retries contract reads and logs failures, while download/execute functions ensure the fetched binary is run with minimal user visibility.

The fetched binary is a packed (Vercel) executable that persists by adding itself to startup, periodically updates its configured IP using the same Ethereum-contract lookup, requests additional JavaScript modules from the control server, and exfiltrates host telemetry (GPU, CPU, memory, username, OS) back to the attacker’s infrastructure. Because the control IPs are stored on-chain, defenders can enumerate historical IPs (e.g., http://45.125.67.172:1228, http://193.233.201.21:3001, http://194.53.54.188:3001) to block or sinkhole servers and to triage affected systems.

Read more: https://blog.phylum.io/supply-chain-security-typosquat-campaign-targeting-puppeteer-users/