Panther | The Complete AI SOC Platform

A Patient Trojan Dropper: polymarket-stake-math Steals Wallet Keys, Browser Sessions, and Telegram from Crypto Developers

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 FrondEnt/PolymarketBTC15mAssistant created on GitHub
2026-06-22 — Sibling package decimal-format-utils published with identical stealer code
2026-06-23 19:58 v3.1.0 Pure Kelly math, no postinstall — benign bait
2026-06-23 19:58 v3.3.0 Refactored to kelly.js, still clean — benign bait
2026-06-23 19:58 v3.4.0 collector.js infostealer injected (2,255 LOC) — malicious
2026-06-23 19:58 v3.5.0 postinstall dropper pulls v3.4.0 from npm — malicious
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:

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
polymarket-stake-math 2026-06-23 6 (3.1.0–3.5.1) Trojan dropper + infostealer Polymarket / Kelly criterion utility
decimal-format-utils 2026-06-22 2 (1.0.0–1.0.1) Infostealer + postinstall dropper big.js / decimal-math utility

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:

Indicators of Compromise

IOC Type Notes
polymarket-stake-math npm package Malicious — all versions 3.1.0–3.5.1
decimal-format-utils npm package Malicious — all versions 1.0.0–1.0.1
haha1999 npm publisher account Throwaway publisher of both packages
sahautpol33@gmail[.]com Email npm account email
sixhotcats@gmail[.]com Email GitHub account email (FrondEnt / Krajekis)
FrondEnt (GitHub ID 109918389) GitHub account Lure-repo owner
Krajekis GitHub persona Same actor; shares email with FrondEnt
FrondEnt/PolymarketBTC15mAssistant GitHub repo Social-proof lure, created 2026-01-29
vercel-backend-myapp[.]vercel[.]app Domain C2 (introduced v3.5.1)
hxxps://vercel-backend-myapp[.]vercel[.]app/releases/psm-peer.tgz URL Payload tarball
scripts/sync-peer.cjs File Dropper (v3.5.0)
scripts/verify-peer.cjs File Dropper + C2 fetch (v3.5.1)
collector.js File Infostealer payload (2,255 LOC)
/tmp/psm-sync-* Path Dropper staging directory
TDATA_SENT_MARKER File Exfiltration state tracker
PSM_PEER_URL, PSM_API_URL Env var C2 override
BACKUP_PACKAGE_NAME, BACKUP_TARGET_VERSION, TARGET_VERSION, BACKUP_PAYLOAD_SPEC, BACKUP_INSTALL_FAST, BACKUP_TDATA_FORCE 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.