
BLOG
A Patient Trojan Dropper: polymarket-stake-math Steals Wallet Keys, Browser Sessions, and Telegram from Crypto Developers
Ariel
Ropek
TL;DR: polymarket-stake-math is a two-stage npm supply chain attack against cryptocurrency and prediction-market developers. It poses as a Kelly criterion stake-sizing helper for Polymarket and was published by the throwaway npm account haha1999. Over roughly 12 hours on 2026-06-23 the attacker escalated through six versions, shipping a clean, working math library first, then injecting a 2,255-line infostealer (collector.js) in a later version that harvests browser passwords and cookies, crypto wallets, Telegram sessions, shell history, and cloud/dev credentials. A postinstall dropper pulls the payload after the fact, and within 12 hours the attacker pivoted delivery from npm to a Vercel-hosted C2 it can hot-swap at will. A sibling package, decimal-format-utils, carries the identical stealer code, confirming an active campaign. This is the latest entry in a sustained 2026 wave of Polymarket-themed npm malware.
What happened
On 2026-06-23, an npm account named haha1999 (sahautpol33@gmail[.]com) published polymarket-stake-math, a package presenting itself as a stake-sizing utility built on the Kelly criterion, exactly the kind of helper a developer writing Polymarket trading logic would search for. Panther Threat Research identified it during routine supply chain monitoring.
The package did not start out malicious, and that is the point. Its first two versions were clean, functional Kelly math with no install hooks. The payload arrived only in later versions, published minutes apart, before delivery pivoted to attacker-controlled infrastructure the following morning. The staging is deliberate: a reviewer who glances at an early release sees a legitimate library.
The lure goes back further than the package itself. The attacker's GitHub repository, FrondEnt/PolymarketBTC15mAssistant, was created on 2026-01-29 nearly five months before the npm packages appeared. It is a credible-looking Polymarket trading terminal with a detailed README, proxy documentation, and a real commit history, and the malicious packages cite it as their source. A developer who finds the repo first sees social proof, not a fresh throwaway account.
Date / time (UTC) | Version | Event |
|---|---|---|
2026-01-29 | — | Lure repo |
2026-06-22 | — | Sibling package |
2026-06-23 19:58 | v3.1.0 | Pure Kelly math, no |
2026-06-23 19:58 | v3.3.0 | Refactored to |
2026-06-23 19:58 | v3.4.0 |
|
2026-06-23 19:58 | v3.5.0 |
|
2026-06-24 08:04 | v3.5.1 | Dropper pivots to Vercel-hosted C2 — malicious |
Who is targeted
The direct targets are developers building on Polymarket and adjacent crypto tooling. These are the people most likely to search npm for a Kelly stake-sizer or a decimal-math helper, and the people most likely to keep wallet keys, exchange sessions, and exchange API credentials on the same machine they develop on. The stealer's own source makes the targeting explicit: a code comment notes that traders keep exchange sessions in secondary browser profiles, and the collection logic walks all browser profiles rather than just the default.
The indirect targets are everyone whose funds those developers can move. A stolen wallet seed phrase or private key is a direct path to draining an account; a stolen exchange or Polymarket session is a path to hijacking trades. Because the payload also sweeps cloud and CI credentials (AWS secrets, npm _authToken, GitHub ghp_ tokens, PyPI tokens) a single compromised developer can become a pivot into the organizations and pipelines they have access to.
How it works
The attack separates the installer from the payload using a classic two-stage trojan dropper. That separation is what lets the early versions stay clean and the later ones stay quiet.
Stage 1: the dropper. A postinstall hook ("postinstall": "node scripts/sync-peer.cjs") fires on install. In v3.5.0 (sync-peer.cjs) the dropper downloads a pinned version of the same package from the npm registry, extracts it to a temporary directory, and overwrites the installed package files with the payload version, defaulting to the infostealer build v3.4.0. Critically, every parameter of that fetch is controllable through environment variables (BACKUP_PACKAGE_NAME, BACKUP_TARGET_VERSION, TARGET_VERSION, BACKUP_PAYLOAD_SPEC, BACKUP_INSTALL_FAST), so the operator can redirect any victim to any payload at any time without republishing.
Stage 1: evolved. Within 12 hours, v3.5.1 (verify-peer.cjs) abandoned npm as the delivery channel and began fetching the payload tarball directly from hxxps://vercel-backend-myapp[.]vercel[.]app/releases/psm-peer.tgz, with the C2 URL itself overridable via PSM_API_URL / PSM_PEER_URL. Moving off npm reduces the attacker's exposure to registry takedowns and gives them a persistent, hot-swappable payload server. The speed of the pivot (roughly half a day) suggests operational awareness of supply chain scanning.
Stage 2: the infostealer. The payload, collector.js, is 2,255 lines and, notably, unobfuscated, a sign of confidence that the package will execute before anyone inspects it. It is a comprehensive, professionally built stealer. What it collects:
Browser credentials and sessions. Chromium
Login Data,Cookies,Web Data, andLocal State(which holds the DPAPI-wrapped AES key used to decrypt Chrome v80+ cookies) across all profiles; Firefoxlogins.json,key4.db, andcert9.db.Crypto wallets. Desktop wallets including Ledger, Trezor, Exodus, MetaMask, Phantom, and Solflare, plus the MetaMask browser extension targeted directly by extension ID (
nkbihfbeogaeaoehlefnkodbefgpgknn).Crypto keys by pattern. A regex sweep for EVM private keys (
0x+ 64 hex), Solana 64-element secret arrays, and BIP39 12/24-word mnemonics, including Hardhat/Foundry mnemonics.Telegram. The full
tdatadirectory (sessions, contacts, encrypted messages) on Windows and macOS.Shell history. Bash, Zsh, sh, Fish, and PowerShell history across Linux, macOS, and Windows.
Cloud and developer secrets.
AWS_SECRET_ACCESS_KEY, genericAPI_KEY/API_SECRET/ACCESS_TOKEN, npm_authToken, GitHubghp_tokens, and PyPI tokens, plus.envand config files in the current project (with.git,coverage,terraform, and similar directories excluded to cut noise).Clipboard. Periodic clipboard capture governed by
CLIPBOARD_MONITOR_MS.
Exfiltration. Collected files are chunked by size and POSTed as HTTP multipart form-data to the C2. The package's only two real runtime dependencies, axios and form-data (both added in v3.4.0), exist solely to support this. A marker file (TDATA_SENT_MARKER) tracks what has already been sent to avoid duplicate uploads, and a BACKUP_TDATA_FORCE=1 switch forces re-exfiltration.
Key finding: a benign-first staging pattern that defeats snapshot review
Most supply chain detection and human review looks at a package as it exists at a single point in time. This campaign is built to beat exactly that. The first published versions are genuinely clean and functional; the payload is introduced in a later version, and the dropper can swap it again post-install. A developer who audits the version they think they installed may be looking at code the dropper has already replaced.
Why this matters: Verifying a package once, at install time or in a one-shot scan, is not sufficient. Detection has to account for what a package does after install (network egress, file overwrites in node_modules, child processes spawned by install hooks) not just what its published source looks like.
Key finding: environment-variable indirection turns one package into a delivery platform
The dropper hardcodes nothing it doesn't have to. Package name, target version, payload spec, and C2 URL are all overridable at runtime through environment variables. That design lets the same published artifact serve different payloads to different victims and lets the operator move infrastructure without touching the registry.
Why this matters: IOC-only defenses that pin to a single C2 domain or a single payload hash will age out fast against an actor who has engineered for hot-swapping. Behavioral signals (install-time network activity, post-install file rewrites) are more durable than any single indicator here.
Campaign scope: decimal-format-utils
The same collector.js stealer appeared one day earlier, on 2026-06-22, in decimal-format-utils, published under the same haha1999 account. That package impersonates the widely-used big.js decimal-math library: it lists the legitimate big.js maintainer in its author field and points its repository URL at the real MikeMcl/big.js project. This is a package-identity spoof aimed at developers who pull in decimal-math utilities.
Package | First seen | Versions | Technique | Impersonation target |
|---|---|---|---|---|
| 2026-06-23 | 6 (3.1.0–3.5.1) | Trojan dropper + infostealer | Polymarket / Kelly criterion utility |
| 2026-06-22 | 2 (1.0.0–1.0.1) | Infostealer + |
|
Shared stealer code plus a shared publisher account ties these two packages to one operator. The broader pattern of Polymarket-themed lures, throwaway publisher accounts, wallet-and-credential theft, and a pivot to Vercel-hosted exfiltration also echoes other Polymarket-targeting npm campaigns documented across 2026, including a hijacked-GitHub-org campaign that likewise exfiltrated to Vercel endpoints. We are not asserting a single shared operator across those campaigns; we note the convergence in tradecraft and the clear, sustained focus on this developer population.
Who is behind this
We attribute both packages to a single financially motivated actor operating under the npm handle haha1999 and the GitHub identities FrondEnt and Krajekis. The two GitHub display names share one email (sixhotcats@gmail[.]com) and alternate across the same commit history, indicating one identity. We are not attributing this actor to a named APT or nation-state group; the targeting (crypto wallets, exchange sessions, Telegram) and the absence of persistence or espionage tooling are consistent with direct financial theft.
The five-month gap between the GitHub lure repo (2026-01-29) and the npm publication (2026-06-23) indicates premeditation rather than opportunism: the credibility scaffolding was built and aged before the payload shipped.
Detection
Panther Threat Research recommends the following detection and hunting approaches. These favor behavior over single indicators, given the actor's demonstrated hot-swapping:
nodespawned by an npm install hook making outbound network connections. Flagnodeprocesses whose parent is an npm/yarn/pnpm install lifecycle and that make outbound HTTP/S or DNS requests to novel domains. Covers MITRE ATT&CK T1195.002 (Compromise Software Supply Chain) and T1105 (Ingress Tool Transfer). (Panther rule:npm_install_hook_network_egress.)Post-install file rewrites inside
node_modules. Alert when a package's own files are overwritten shortly after install by a process extracting from a temp path (e.g./tmp/psm-sync-*) — the dropper's signature behavior.nodereading browser credential and wallet stores. Alert onnodeaccessingLogin Data,Cookies,Local State, Firefoxkey4.db/logins.json, or wallet directories (MetaMask, Ledger, Exodus, Phantom) and Telegramtdata. Covers T1555.003 (Credentials from Web Browsers), T1539 (Steal Web Session Cookie), and T1005 (Data from Local System).nodereading shell history or.envoutside the project root. Covers T1552.001 (Credentials in Files) and T1552.003 (Bash History).Outbound multipart POST to the known C2. Block or alert on traffic to
vercel-backend-myapp[.]vercel[.]app, and more durably, flag large multipart uploads to newly-seen domains immediately following an install event. Covers T1567 (Exfiltration Over Web Service). (Panther rule:npm_c2_vercel_backend_myapp.)
Indicators of Compromise
IOC | Type | Notes |
|---|---|---|
| npm package | Malicious — all versions 3.1.0–3.5.1 |
| npm package | Malicious — all versions 1.0.0–1.0.1 |
| npm publisher account | Throwaway publisher of both packages |
| npm account email | |
| GitHub account email (FrondEnt / Krajekis) | |
| GitHub account | Lure-repo owner |
| GitHub persona | Same actor; shares email with FrondEnt |
| GitHub repo | Social-proof lure, created 2026-01-29 |
| Domain | C2 (introduced v3.5.1) |
| URL | Payload tarball |
| File | Dropper (v3.5.0) |
| File | Dropper + C2 fetch (v3.5.1) |
| File | Infostealer payload (2,255 LOC) |
| Path | Dropper staging directory |
| File | Exfiltration state tracker |
| Env var | C2 override |
| Env vars | Dropper / exfil overrides |
If you have installed either package: Remove it immediately, but treat removal as insufficient. Assume everything the stealer targets has been exfiltrated and rotate accordingly: browser-saved passwords and active sessions (force log-outs), every credential in your .env and project config files, npm/GitHub/PyPI tokens, and AWS keys. Move any crypto holdings to a new wallet generated on a clean machine: any seed phrase, private key, or wallet file present on the affected host must be considered compromised. Clear and re-authenticate Telegram sessions. Because the dropper can replace the on-disk package after install, inspect the actual contents of the installed package directory rather than trusting the version number.
Stay in the Loop
Read the latest from Panther's Threat Research Team

Share:
Threat Research
RESOURCES









