Malicious npm math libraries hide a RAT that unlocks only with a secret matrix
SafeDep found a remote-access implant buried in mathmain 1.0.1, an npm package that clones the popular mathjs library. The malicious code is dormant and encrypted: there are no install hooks, and merely importing the package does nothing. It fires only when a program calls the library’s LU solver, lusolve(), with a specific input matrix. An extra call slipped into the end of the solver routes the solver’s lower-triangular factor L into a hidden isGraph() function, which serializes L to JSON and uses that string as an AES-GCM password (key derived via scrypt, with a fixed salt/IV/auth-tag layout stored as base64). The magic input turns out to be a 3×3 Pascal matrix, whose LU factor produces exactly the right key — a detail SafeDep reproduced after JFrog first identified the triggering input. Brute-force guessing thousands of candidate passwords never worked, because activation was gated on this precise value.
When the key matches, the loader decrypts a staged payload (starting with graph.js, followed by further stages built on a bundled copy of ethers), writes it to disk, and executes it via require() at the Node process’s privileges. The implant fingerprints the host, generates an X25519 key pair, and spawns detached child Node processes. Its command-and-control is deliberately unconventional: it beacons through the Slack (chat.postMessage) and Telegram APIs and reads instructions from a smart contract on the Base Sepolia test network. Encrypted operator code can be pushed to the host and run on demand.
The same loader — identical trigger code, solver modifications, and encrypted blobs — was found in two sibling packages, mathsbase and math-universe, across five versions, with payloads matching byte for byte. The malicious code exists only in the published npm builds, not in the linked GitHub source, pointing to injection at publish time or a compromised publisher account. Notably, the tampering was confined to version 1.0.1; the default published release was clean, so any scan that inspects only the default version would have missed it entirely — a reminder to audit every published version, not just the tagged latest.
Read the full article
Continue reading at Hacker News →This is an AI-generated summary. Read the original for the full story.