# `ts-einkle` + `ts-ankle` + `ts-einkle-slot` - crypto-wallet drainer / SSH backdoor / big.js typosquat cluster

> Between 2026-06-26 and 2026-06-27 a single naming-cluster operator published three new malicious npm packages - `ts-einkle` (5 versions), `ts-einkle-slot` (5 versions), and `ts-ankle` (1 version). All three execute install-time payloads: `ts-einkle` is a full credential and crypto-wallet stealer exfiltrating to `datasecure-service.vercel.app/api/v1`; `ts-ankle` recursively walks the home directory for credential files and installs an SSH public key in `~/.ssh/authorized_keys`; `ts-einkle-slot` typosquats `big.js` and shadow-loads `node-slot` on every `require()`. npm-support replaced all three with `0.0.1-security` holders on 2026-06-29.

- Published: 2026-06-27
- Severity: critical
- Kind: Typosquat - A package that never had a legitimate version, named to be mistaken for a real one - a misspelling, a lookalike scope, or an impersonated vendor SDK.
- Ecosystems: npm
- Scope: 3 packages, 10 compromised versions
- Tags: typosquat, credential-theft, crypto-wallet-drain, infostealer
- Also known as: ts-einkle / ts-ankle cluster
- Detected by: Amazon Inspector, OpenSSF Package Analysis, GitHub Security Advisory
- Incident ID: npm-2026-06-27-ts-einkle-ankle-wallet-cluster

## Affected packages (3)

Only the exact versions listed were named by the source advisories. Other versions are not implicated.

| Package | Ecosystem | Compromised versions |
|---|---|---|
| [ts-ankle](https://dependencywatch.io/package/npm/ts-ankle) | npm | 1.1.0 |
| [ts-einkle](https://dependencywatch.io/package/npm/ts-einkle) | npm | 1.0.9, 1.1.0, 1.1.2, 1.1.3 |
| [ts-einkle-slot](https://dependencywatch.io/package/npm/ts-einkle-slot) | npm | 0.0.8, 0.0.9, 0.1.0, 0.1.1, 0.1.2 |

## What happened

Between 2026-06-26 08:58 UTC and 2026-06-27 16:24 UTC, an operator published three closely-named npm packages - `ts-einkle`, `ts-einkle-slot`, and `ts-ankle` - that together implement three orthogonal supply-chain attack primitives. The shared `ts-*` naming convention and the 28-hour publish window strongly imply a single operator. Amazon Inspector flagged all three; npm-support seized the names and published `0.0.1-security` holders early on 2026-06-29.

## `ts-einkle` - credential and crypto-wallet stealer

`ts-einkle` was published across `1.0.9`, `1.1.0`, `1.1.2`, and `1.1.3` between 2026-06-26 08:58 UTC and 2026-06-27 16:02 UTC. Its `package.json` declares `"postinstall": "node test.js"`, triggering on every `npm install`. The shipped `test.js` is a multi-stage stealer covering: SSH key files under `~/.ssh/`, AWS credentials and config (`~/.aws/`), GPG keyrings (`~/.gnupg/`), npm and PyPI auth files (`~/.npmrc`, `~/.pypirc`), Docker settings, git credentials, and the GitHub CLI token via `gh auth token`. On Windows it pivots to PowerShell DPAPI to decrypt the Chromium passwords store and read the Firefox profile vault. Browser-extension wallet targeting covers MetaMask, Phantom, Solflare, OKX, Coinbase Wallet, TrustWallet, Backpack, and TronLink, plus a recursive seed-phrase scan over shell history, `.env`, and clipboard contents. Everything is POSTed to `https://datasecure-service.vercel.app/api/v1`. SHA-256 of the dropped `index.js` is published in the OSV record. CIRCL / vulnerability-lookup tracks the package under `MAL-2026-6524`; the corresponding GHSA is `GHSA-mjcv-m7fg-mg8j`.

## `ts-ankle` - home-directory walker and SSH backdoor

`ts-ankle@1.1.0` was published 2026-06-27 16:23 UTC. Its `postinstall` hook recursively walks the user's home directory on Unix systems and every mounted drive on Windows, collecting files that match credential patterns fetched dynamically from an attacker server (so the operator can re-target which files get stolen without republishing the package). The stolen file payload is exfiltrated. On Linux the hook additionally appends a fixed attacker SSH public key to `~/.ssh/authorized_keys` and inserts a host-firewall rule to allow inbound SSH - turning every infected host into a persistent attacker-accessible foothold. SHA-256 `28a7cbf43fc7ea473a83f25e5449d25806c1902bc8b90c085e21b7da6e064073` is the published IOC; CIRCL identifier `MAL-2026-6548`; GHSA `GHSA-992p-988h-h55j`.

## `ts-einkle-slot` - `big.js` typosquat with shadow-loaded `node-slot` dependency

`ts-einkle-slot` was published across `0.0.8`, `0.0.9`, `0.1.0`, `0.1.1`, and `0.1.2` between 2026-06-26 09:00 UTC and 2026-06-27 16:24 UTC. The published metadata is copied verbatim from Michael Mclaughlin's legitimate `big.js` arbitrary-precision arithmetic library - same description, same keywords, same README, same author block - to defeat surface-level review by anyone who checks the package page before installing. The shipped code adds a hidden module-load block that `require`s an attacker-controlled package named `node-slot` whenever any consumer `import`-s or `require`-s `ts-einkle-slot`. The shadow-loaded `node-slot` is the code-execution primitive; the typosquatted `big.js` surface is the social-engineering vector. CIRCL identifier `MAL-2026-6525`; GHSA `GHSA-8cxx-rp6g-mcr9`.

## Disclosure timeline

- **2026-06-26 08:58–09:00 UTC** - `ts-einkle@1.0.9` and `ts-einkle-slot@0.0.8` published.
- **2026-06-27 08:06–09:25 UTC** - `ts-einkle@{1.1.0,1.1.2}` and `ts-einkle-slot@{0.0.9,0.1.0}` published.
- **2026-06-27 16:02–16:24 UTC** - final pre-takedown versions `ts-einkle@1.1.3`, `ts-einkle-slot@{0.1.1,0.1.2}`, and `ts-ankle@1.1.0` published.
- **2026-06-29 03:17 UTC** - npm-support replaces all three names with `0.0.1-security` holders; CIRCL / vulnerability-lookup publishes `MAL-2026-6524`, `MAL-2026-6525`, and `MAL-2026-6548`; GHSA mirrors them.

## Impact

- `ts-einkle@{1.0.9,1.1.0,1.1.2,1.1.3}` - `postinstall: node test.js` triggers a multi-stage stealer that harvests SSH keys, AWS credentials, GPG keys, npm/PyPI configs, Docker settings, git credentials, and GitHub CLI tokens; on Windows uses PowerShell DPAPI to decrypt Chromium passwords and read Firefox vault data; targets MetaMask, Phantom, Solflare, OKX, Coinbase, TrustWallet, Backpack, and TronLink browser-extension wallets; captures Telegram Desktop tdata, browser cookies, clipboard contents, shell history, and recursively scans for seed phrases; exfiltrates everything to `https://datasecure-service.vercel.app/api/v1`
- `ts-ankle@1.1.0` - `postinstall` hook recursively walks the user's home directory on Unix and every mounted drive on Windows, collects files matching dynamically-fetched credential patterns, exfiltrates them, AND on Linux appends an attacker SSH public key to `~/.ssh/authorized_keys` plus opens inbound SSH in the host firewall - persistent remote access on top of credential theft
- `ts-einkle-slot@{0.0.8,0.0.9,0.1.0,0.1.1,0.1.2}` - copies `big.js` metadata verbatim to defeat surface-level review, then injects a hidden module-load block that imports the attacker-controlled `node-slot` shadow dependency whenever the package is `import`-ed or `require`-d, executing it silently even if the host module-load throws
- Crypto-wallet seed phrases and exchange API keys harvested from `ts-einkle` typically convert to on-chain withdrawal attempts within minutes - anyone who ran `npm install` against a manifest referencing these names should treat connected wallets and exchange accounts as actively under attack

## What to do

1. Remove every reference to `ts-einkle`, `ts-einkle-slot`, and `ts-ankle` from `package.json` / lockfiles / CI image layers - all three names now serve `0.0.1-security` holders, so previously-pinned high versions no longer resolve and a fresh `npm install` will fail loudly until you delete the line
2. Treat any host that ran `npm install` against these names as fully compromised: rotate every secret reachable from that host from a separate clean device - npm tokens, GitHub tokens, AWS access keys, SSH private keys, GPG keys, cloud CLI tokens, Docker registry credentials, and any browser-stored or extension-stored crypto wallet seed phrase or exchange API key
3. For `ts-ankle` victims specifically: inspect `~/.ssh/authorized_keys` on every Linux host that ran the install and remove any attacker-added key; review host firewall rules for unexpected inbound SSH allows added since 2026-06-26
4. Block `datasecure-service.vercel.app` at egress; hunt firewall and DNS logs for outbound HTTPS to that host since 2026-06-26
5. For `ts-einkle-slot` victims: search `node_modules` for any `node-slot` directory and `package-lock.json` for a `node-slot` entry - the package was loaded as a shadow dependency at install time and should not have been requested directly
6. Scan internal Artifactory / Nexus / Verdaccio mirrors for cached tarballs of these names and purge them - the npm-support `0.0.1-security` replacement does not flush private caches

## Check your own dependencies

- Check a package-lock.json against this incident: https://dependencywatch.io/check/package-lock-json

The scan runs entirely in the browser; lockfile contents are never uploaded.

## References

- [GHSA-mjcv-m7fg-mg8j - Malicious code in ts-einkle (npm)](https://github.com/advisories/GHSA-mjcv-m7fg-mg8j) - GitHub
- [GHSA-992p-988h-h55j - Malicious code in ts-ankle (npm)](https://github.com/advisories/GHSA-992p-988h-h55j) - GitHub
- [GHSA-8cxx-rp6g-mcr9 - Malicious code in ts-einkle-slot (npm)](https://github.com/advisories/GHSA-8cxx-rp6g-mcr9) - GitHub
- [MAL-2026-6524 - ts-einkle credential/wallet stealer](https://github.com/ossf/malicious-packages/blob/main/osv/malicious/npm/ts-einkle/MAL-2026-6524.json) - OpenSSF Malicious Packages
- [MAL-2026-6548 - ts-ankle home-dir walker and SSH backdoor](https://github.com/ossf/malicious-packages/blob/main/osv/malicious/npm/ts-ankle/MAL-2026-6548.json) - OpenSSF Malicious Packages
- [MAL-2026-6525 - ts-einkle-slot big.js typosquat](https://github.com/ossf/malicious-packages/blob/main/osv/malicious/npm/ts-einkle-slot/MAL-2026-6525.json) - OpenSSF Malicious Packages

---

Canonical page: https://dependencywatch.io/incident/npm-2026-06-27-ts-einkle-ankle-wallet-cluster
Markdown version: https://dependencywatch.io/incident/npm-2026-06-27-ts-einkle-ankle-wallet-cluster.md
Site index for agents: https://dependencywatch.io/llms.txt
DependencyWatch.io is operated by Precursor Security (https://precursorsecurity.com).
