Published September 21, 2026 · Added September 21, 2026

Encrypted loader in mathmain npm packages hides a remote-access implant

SafeDep reports that npm packages mathmain, mathsbase, and math-universe — mathmain presenting itself as a renamed copy of the open-source mathjs — carried an encrypted loader that stays dormant until a caller runs the linear solver with a matching input. Solving lusolve() with a 3-by-3 Pascal matrix yields the lower-triangular factor whose JSON form is the AES-GCM password, decrypting graph.js plus two payload files that form a remote access implant: it reads host data, generates X25519 keys, runs shell commands, reads a Base Sepolia smart contract through a bundled ethers copy, and takes commands from Slack and Telegram, polling Slack every 10 seconds. The loader appears only in the published npm builds, not the packages' public GitHub repositories, and npm reported download counts far above the packages' real-world use, with no public dependents.

SafeDep reports that npm packages mathmain, mathsbase, and math-universe — mathmain presenting itself as a renamed copy of the open-source mathjs — carried an encrypted loader that stays dormant until a caller runs the linear solver with a matching input. Solving lusolve() with a 3-by-3 Pascal matrix yields the lower-triangular factor whose JSON form is the AES-GCM password, decrypting graph.js plus two payload files that form a remote access implant: it reads host data, generates X25519 keys, runs shell commands, reads a Base Sepolia smart contract through a bundled ethers copy, and takes commands from Slack and Telegram, polling Slack every 10 seconds. The loader appears only in the published npm builds, not the packages’ public GitHub repositories, and npm reported download counts far above the packages’ real-world use, with no public dependents.

Read the original story.

Source: Safedep