
Earliest Known PolinRider Malware Found in 2025 npm Packages
OpenSourceMalware traces nine itsa-* npm package versions published on 4 May 2025 from a hijacked maintainer account to the PolinRider campaign, eight months before documented victims. It decodes the EtherHiding chain (BNB Smart Chain and Ethereum calldata, JADESNOW, INVISIBLEFERRET bootstrapper, Socket.IO RAT, Python stealer) and links the 2025 sample to 2026 force-push infections. It lists IOCs, hashes, a timeline and hunting guidance.
What it is
OpenSourceMalware found that nine npm versions from the maintainer of the itsa-* packages, published 20:15 to 21:45 UTC on 4 May 2025, carry a payload matching the PolinRider campaign. The post's authors confirm the payload in four of the nine. The other five were removed before they could be read and are counted as infected because they sit in the same burst. The sample carries PolinRider's payload but not its force-push spread behaviour, so the authors call it a building block of the campaign.
Affected
Check lockfiles and node_modules for these versions. Three are still live on npm as of the post (late October 2026):
itsa-jsext@2.0.3itsa-react-button@16.0.11itsa-react-docviewer@16.1.2
Six have been removed from the registry: itsa-utils@1.4.2, itsa-cli@16.5.3, itsa-react-maskedinput@16.1.2, itsa-react-checkbox@16.0.5, itsa-react-focuscontainer@16.0.10 and itsa-react-input@16.1.2. A lockfile or mirror can still pin them.
The maintainer published seven clean replacements the next morning, including itsa-utils@1.4.3. These did not remove the infected versions, so anyone pinning a version can still install them.
The payload runs when an application imports the package. There are no install hooks. In index.js or webpack.config.js, a single long obfuscated line is appended after hundreds of spaces.
How it works
The chain uses EtherHiding. The encrypted stages stay in blockchain transaction calldata, and the loader fetches them through public explorer APIs.
- The loader sets
global['_V']='5-itsa', queries Binplorer for the attacker wallet's latest transaction, decodes the calldata, XORs it with$v$5;kmc$ldm*5SAand runs it withnode -e. - JADESNOW sits in a BNB Smart Chain transaction dated 7 February 2025. It switches to Ethereum, reads one transaction via Ethplorer, BlockCypher and Blockchair, and decrypts it with
ThZG+0jfXE6VAGOJ. - The bootstrapper contacts
154.91.0.103:27017. It exits if ip-api.com reports country code RU. Otherwise it installs Node dependencies and Python 3.12.7, then reports toPOST /verify-human/5-itsa. - A Socket.IO RAT connects to
85.239.62.36:3306and runs shell commands and file uploads. A 65,500-byte Python stealer runs on Windows, Linux and macOS.
The stealer targets nine browsers, more than 80 wallet extensions, Git credentials, GitHub CLI tokens, Solana keys, 1Password and Dashlane data, and cloud storage clients. It stages loot in %USERPROFILE%\.npm or /tmp/.npm and uploads AES-encrypted ZIPs to 85.239.62.36:27017/u/f. Telegram is the fallback for archives under 50 MB.
Nothing creates a run key, scheduled task, launch agent or service, so the malware does not survive a reboot. It stays alive through detached Node processes and Socket.IO reconnects every five seconds.
What to do
Hunt for:
- Node command lines containing both
-eandglobal['_V']. - Very long lines after runs of spaces in
index.jsorwebpack.config.js, and the stringsglobal['_V'],global.i=andglobal.o=. - Node processes querying Binplorer, Ethplorer, BlockCypher or Blockchair just before spawning
node -e. - Node connections on port 3306 that speak HTTP or Socket.IO instead of MySQL.
- Contact with
154.91.0.103,85.239.62.36or85.239.60.213. - New
tmp7A863DD6.tmp,/tmp/.npm,~/.node_modulesor~/.pyenvcreated by Node processes. - Runtime installs of
socket.io-client,pyzipper,pycryptodomex,portalockerorsecretstorageby a dependency. - Telegram
sendDocumenttraffic from developer machines.
For source repositories, look for GitHub force-pushes that change only webpack.config.js, keep the commit message and author date, and carry a committer date in a different timezone offset. Several repositories force-pushed within one minute is another sign. Trust GitHub push times over commit dates, because some July 2026 commits were back-dated by 34 to 152 days.
The post lists SHA-256 hashes for four tarballs and the payload stages, 10 infected 2026 commit SHAs, and blockchain addresses. The BNB Smart Chain wallet is 0x9BC1355344B54DEDf3E44296916eD15653844509. The Telegram bot is @file_1018_bot (ID 7870147428).
Caveats
- The 2026 variants (B, B2, C) were not decoded, so it is unknown whether they use the same route. They were found only in the maintainer's GitHub repositories, never in npm.
- The account-takeover explanation is the authors' inference. They note the burst used npm 10.9.2 and Node 22.14.0, while every other publish from May 2025 to April 2026 used npm 5.5.1 and Node 8.9.1. The npm client self-reports these versions, so they are not proof.
- The authors suspect the infection stayed on the maintainer's machine from 2025 and drove the 2026 force-pushes. This is their reading of the evidence, not a confirmed finding.
- Binplorer no longer accepts the loader's
type=mintrequest, so that exact request fails today. The on-chain data remains and was recovered through public RPC. - The Telegram bot is send-only, and no victim archives were retrieved.
- It is not known who removed the six packages from the registry.
Organisations named here
- EtherHiding
- Google Threat Intelligence Group
- itsa-utils
- JADESNOW
Technologies named here
- ip-api.com
- Telegram Bot API
- npm
- OpenSourceMalware
- Google Threat Intelligence
- Socket.IO
- Node.js
- Python
- Ethereum
- Telegram
- GitHub
- Binplorer
- Blockchair
- BlockCypher
- Browsers targeted by the stealer: Chrome, Chromium, Opera, Opera GX, Brave, Edge, Arc, Vivaldi, Firefox
- Cloud storage targeted: Dropbox, Google Drive, OneDrive, iCloud, Box, MEGA, pCloud
- Ethplorer
- npm/itsa-cli@16.5.3 (removed)
- npm/itsa-jsext@2.0.3 (payload in index.js line 11)
- npm/itsa-react-button@16.0.11 (payload in webpack.config.js line 26)
- npm/itsa-react-checkbox@16.0.5 (removed)
- npm/itsa-react-docviewer@16.1.2 (payload in webpack.config.js line 23)
- npm/itsa-react-focuscontainer@16.0.10 (removed)
- npm/itsa-react-input@16.1.2 (removed)
- npm/itsa-react-maskedinput@16.1.2 (removed)
- npm/itsa-utils@1.4.2 (removed)
- Wallets and credential stores targeted: MetaMask, Phantom, Coinbase, Binance, Trust Wallet, TronLink, OKX, Ronin, Keplr, Rabby, Exodus, SafePal, 1Password, Dashlane, Electrum, Atomic
Techniques named here
- EtherHiding
- Account Takeover
- Account takeover / compromised maintainer publishing
- Code appended after whitespace padding
- Detached process execution and silent error handling
- Exfiltration of AES-encrypted ZIP archives
- Geofencing kill switch
- Git force-push of amended commits with backdated dates
- Remote access via Socket.IO
- Use of non-standard port for C2 (3306)
- XOR decryption of staged payloads
Threat actors named here
- PolinRider
- TasksJacker
- UNC5342
- InvisibleFerret
- BeaverTail
- DPRK
- JADESNOW (second-stage obfuscated loader reading Ethereum calldata via Ethplorer, BlockCypher and Blockchair)
- North Korean payload (as described by the page)
- Python credential stealer (65,500 bytes unpacked, exfiltrates via 85.239.62.36:27017/u/f with Telegram fallback)
- Socket.IO RAT (Node.js, connects to 85.239.62.36:3306)
Related in Supply Chain


