OAK — OnChain Attack Knowledge

Worked example · 2026-05

Ill Bloom — recovery phrases from less-common mobile wallets were generated by an insecure PRNG, and 431 accounts across five chains were swept in one coordinated action — multi-wallet cohort (multi-chain) — first sweep 2026-05-27, disclosed July 2026, root cause named 2026-08-05 as CryptoJS.lib.WordArray.random() (CVE-2026-71851)

Loss
$5,690,922 measured, stated as a lower bound, across two documented sweeps: ~$3.14M from 431 accounts on 2026-05-27, and ~$2.55M from 522 seeds between 2026-05-30 and 2026-07-13. The first sweep hit Bitcoin, Ethereum, Tron, Rootstock and Polygon in a single coordinated action. Reporting at the July disclosure put 2,114 wallets at identified risk, and the researchers state explicitly that the address sets are incomplete — a negative result from their checker does not establish safety, so the true affected population is unknown and larger.
OAK Techniques observed
OAK-T11.004 (Insufficient-Entropy Key Generation — primary, confirmed mechanism. Affected wallets generated BIP-39 recovery phrases using weak randomness (an insecure PRNG), producing phrases with materially less cryptographic strength than the 128-bit floor implies. Attackers can therefore predict or reconstruct recovery phrases offline, without ever needing the user's password, device, or consent. See techniques/T11.004-insufficient-entropy-key-generation.md). OAK-T5.001 (Hard Drain — the on-chain manifestation: coordinated multi-chain sweeps against precomputed keys).
Attribution
pseudonymous. No named individual or group, and no public link to a tracked OAK actor. The operational signature is the coordinated, simultaneous, cross-chain sweep — 431 accounts across five distinct networks in one action — which requires a precomputed key inventory and per-chain tooling prepared in advance. The research and disclosure are attributed to Coinspect, which published the on-chain forensics and operates a public address checker at illbloom.org.
Key teaching point
The affected population is defined by a property of the software, not by anything the user did — and here nobody has been able to enumerate that software completely. The exposure traces to less widely used mobile software wallets; hardware wallets are unaffected, and most current software wallets appear not to be vulnerable. That framing is the problem. A user cannot act on "less common mobile wallets" without knowing whether theirs is on a list nobody has finished writing, and the researchers are explicit that their address sets are incomplete, so a negative check result does not mean safe. This is the defining operational difference between Ill Bloom and its cohort siblings: Milk Sad named a tool and a version range, Coldcard named a vendor, models, and firmware versions, and in both cases an affected user could reach certainty. Here the boundary is fuzzy, which means the only safe response for anyone who generated a seed in an uncommon mobile wallet is to migrate regardless of check results — treat unresolved provenance as compromised. The generalisable point for the ecosystem: a wallet's key-generation path deserves scrutiny in proportion to nothing about its popularity, and the long tail of small mobile wallets is where this class concentrates precisely because it receives the least review.

Summary

Ill Bloom is an actively exploited weakness in how certain cryptocurrency wallets generate recovery phrases. The defect is weak randomness — an insecure PRNG — used during recovery-phrase generation, which yields BIP-39 phrases with far less cryptographic strength than their word count implies.

Because the phrases are reconstructible offline, an attacker can systematically predict or derive them without the user's password, device, or any interaction. The wallets remain fully functional and indistinguishable from correctly generated ones until they are swept.

First confirmed on-chain exploitation occurred on 2026-05-27, when 431 crypto accounts were drained in a coordinated sweep spanning Bitcoin, Ethereum, Tron, Rootstock and Polygon. A second wave of drains was documented across May to July 2026, with total losses passing $5M by the time of public disclosure in July 2026. Reporting at that point identified 2,114 wallets at risk.

The exposure is concentrated in less common mobile software wallets. Hardware wallet users are not affected, and research indicates most current software wallets are also not vulnerable — but the affected-software boundary has not been fully enumerated.

Coinspect published the technical research and on-chain forensics and operates a public checker for wallet addresses at illbloom.org. The researchers caution that the address sets are incomplete and that a negative result does not guarantee safety.

Remediation requires creating an entirely new wallet with a fresh recovery phrase and migrating funds to it. Updating the app or re-importing the same phrase accomplishes nothing.

The root cause, named on 2026-08-05

The "insecure PRNG" was, for two months, deliberately unnamed. Coinspect founder Juliano Rizzo reported the underlying issue on 2026-06-10 and withheld technical detail for two months while vendors were notified. On 2026-08-05, CryptoJS maintainer Evan Vosberg published GHSA-rg76-677x-56q9 — titled, explicitly, "CryptoJS.lib.WordArray.random() uses a weak PRNG (Ill Bloom)" — rated Critical, CVSS 9.0, and tracked as CVE-2026-71851.

The defective function is CryptoJS.lib.WordArray.random(), used by downstream wallet applications as the entropy source for BIP-39 recovery phrases. It implements a custom variant of George Marsaglia's Multiply-With-Carry PRNG seeded from Math.random() — not a CSPRNG. Nominal requests for 128 or 256 bits of entropy produce effective search spaces of roughly 2³⁹ and 2⁴⁷, small enough to enumerate on commodity hardware.

The version history is the part worth reading twice. The weak implementation was introduced in 3.1.2-4 (June 2014) in response to a GitHub issue, and is present in every 3.x release except 3.2.0 and 3.2.1. Those two versions shipped a genuinely secure fix — which was reverted in 3.3.0 because it broke backward compatibility for existing users. A maintainer chose not to break existing deployments over shipping a function that silently produced weak keys, and that decision stood for roughly nine more years. All versions before 4.0.0 are affected; 4.0.0 is the fix.

Five wallet applications were identified as generating recovery phrases from the affected function:

App Status
RRWallet discontinued — no fix
Milo discontinued — no fix
Bexo Wallet fixed in 20.1.0 (builds not yet uploaded as of 2026-08-06)
NanChat fixed in 1.3.0 — the only app to publish its own advisory
Bitcoin Libre fixed in v4 (July 2024)

A phrase generated by an affected version remains guessable wherever it is later imported, including into a hardware wallet, and no amount of subsequent hashing or PBKDF2 stretching restores entropy that was never there.

Timeline (UTC)

When Event OAK ref
2014-06 CryptoJS.lib.WordArray.random() gains a custom Marsaglia Multiply-With-Carry PRNG seeded from Math.random(), shipped in 3.1.2-4 T11.004 defect introduced
2017-ish (3.2.0 / 3.2.1) A genuinely secure implementation ships in two releases (defect briefly closed)
(3.3.0) The secure implementation is reverted for backward compatibility; the weak PRNG returns and persists through the rest of the 3.x line T11.004 defect restored
(standing, undated) Downstream mobile wallets generate BIP-39 recovery phrases from the affected function, yielding ~2³⁹ / 2⁴⁷ effective entropy against 128 / 256-bit nominal T11.004 defect standing
2026-05-27 First confirmed on-chain exploitation: 431 accounts drained (~$3.14M) in one coordinated sweep across Bitcoin, Ethereum, Tron, Rootstock and Polygon T11.004 → T5.001
2026-05-30 → 2026-07-13 Second wave: 522 seeds swept for ~$2.55M; measured total reaches $5,690,922 as a lower bound T5.001
2026-06-10 Coinspect's Juliano Rizzo reports the underlying library issue; technical detail withheld for two months while vendors are notified (coordinated disclosure)
2026-07 Public disclosure of the exploitation; Coinspect publishes forensics and an address checker; 2,114 wallets identified at risk, with address sets stated to be incomplete (disclosure)
2026-08-05 CryptoJS maintainer Evan Vosberg publishes GHSA-rg76-677x-56q9 / CVE-2026-71851 (Critical, CVSS 9.0), naming CryptoJS.lib.WordArray.random(); fixed in 4.0.0; five affected wallet apps enumerated, two of them discontinued with no fix (root cause named)
ongoing Affected-software boundary still not fully enumerated; unmigrated phrases remain at risk, including any imported into hardware wallets (open)

What defenders observed

  • Pre-event (the long tail of wallet software is where this class lives). Hardware wallets and mainstream software wallets were largely unaffected; the damage sits in less widely used mobile wallets, which receive proportionally the least security review while offering identical custody responsibility. Users treat "it's a wallet app" as a uniform category; the key-generation quality behind that category is anything but (M22, M23).
  • Pre-event (weak entropy is invisible from every user-facing position). A weak BIP-39 phrase has the right word count, a valid checksum, and produces addresses and signatures indistinguishable from strong ones at the consensus layer. No amount of user diligence surfaces this — which is why the control has to sit with the software, and why disclosure is the only detection channel available to victims.
  • At-event (coordinated multi-chain sweep is the cohort signature). 431 accounts across five chains in one action indicates a precomputed key inventory plus per-chain tooling staged in advance. Simultaneous unrelated-address draining across multiple networks is the shape a weak-key cohort sweep takes, and it distinguishes this class from a targeted compromise, where the drain path follows one victim's assets.
  • At-event (multi-chain derivation multiplies the loss). One weak mnemonic compromises every chain derived from it. Bitcoin, Ethereum, Tron, Rootstock and Polygon were all swept from the same seed population, so incident scoping must enumerate derivation paths rather than balances on a single chain.
  • Response (an incomplete checker is a partial control and must be labelled as one). Coinspect's checker is genuinely useful and the researchers are appropriately explicit that the address sets are incomplete. The risk is that users read a negative result as an all-clear. Where a checker exists for a key-generation defect, the advice that accompanies it should state plainly that only a positive result is informative.
  • Response (migration, not update). As with every T11.004 case, the entropy was consumed at generation time. Updating the app or re-importing the same phrase changes nothing; only a new phrase from a sound generator, with funds moved to it, closes the exposure.
  • Root cause (a general-purpose crypto library is not a key-generation library, and the API did not say so). WordArray.random() reads like a random-bytes helper and was used as a seed source by five separate wallet teams. The reusable rule for wallet developers is that BIP-39 entropy must come from the platform CSPRNGcrypto.getRandomValues, crypto.randomBytes, the OS RNG — never from a general-purpose library helper whose backing implementation is unspecified. The reusable rule for library authors is the mirror image: a function that returns random-looking bytes without CSPRNG guarantees should say so in its name or refuse to exist (M02, M40).
  • Root cause (backward compatibility outranked correctness for nine years, and that is the durable finding). A secure implementation shipped in 3.2.0/3.2.1 and was reverted in 3.3.0 because it broke existing users. That is a defensible maintenance instinct in almost every other context and a catastrophic one for a key-generation primitive: the "compatibility" being preserved was the ability to reproduce weak keys. Dependency-risk review for anything in a custody path should ask specifically whether a security fix in that dependency's history was ever rolled back (M40).
  • Root cause (two of five affected apps are discontinued, so remediation cannot reach their users). RRWallet and Milo have no fix and no maintainer. Users of abandoned wallet software have no upgrade path and no notification channel; the only workable advice is unconditional migration. This is the concrete form the enumeration problem takes at the end of the long tail.

Public references

  • [illbloomorg2026] — Coinspect, "Ill Bloom: Crypto Wallet Vulnerability" (the primary research site: the insecure-PRNG recovery-phrase root cause, first confirmed on-chain exploitation on 2026-05-27 with a second wave across May–July 2026, the multi-chain scope including Bitcoin / Ethereum / Polygon / Tron / Solana, the finding that hardware wallets and most current software wallets are unaffected while less common mobile wallets are, the public address checker, the explicit caveat that address sets are incomplete and a negative result does not guarantee safety, and the migration-not-update remediation guidance): https://illbloom.org/
  • [thehackernewsillbloom2026] — The Hacker News, "Attackers Exploit 'Ill Bloom' Vulnerability to Drain Over $5 Million From Cryptocurrency Wallets" (the $5M+ figure and the actively-exploited framing): https://thehackernews.com/2026/07/attackers-exploit-ill-bloom.html
  • [cryptonomistillbloom2026] — The Cryptonomist, "Ill Bloom Vulnerability Drains $5 Million from Crypto Wallets" (the 2026-05-27 coordinated sweep of 431 accounts across Bitcoin, Ethereum, Tron, Rootstock and Polygon): https://en.cryptonomist.ch/2026/07/06/ill-bloom-vulnerability-crypto-wallets/
  • [coingeekillbloom2026] — CoinGeek, "'Ill Bloom' flaw puts 2,114 digital wallets at risk: report" (the 2,114-wallet at-risk figure): https://coingeek.com/ill-bloom-flaw-puts-2114-digital-wallets-at-risk-report/
  • [ghsacryptojs2026] — GitHub Security Advisory GHSA-rg76-677x-56q9, "CryptoJS.lib.WordArray.random() uses a weak PRNG (Ill Bloom)" (the upstream advisory published 2026-08-05 by maintainer Evan Vosberg: Critical, CVSS 9.0, all versions before 4.0.0 affected, 4.0.0 the fix): https://github.com/brix/crypto-js/security/advisories/GHSA-rg76-677x-56q9
  • [cve202671851] — GitHub Advisory Database, CVE-2026-71851, "crypto-js: Insufficient Entropy in Cryptographic Secret Generation via Vulnerable CryptoJS Dependency Chain" (the CVE record and affected dependency-chain framing): https://github.com/advisories/GHSA-rg76-677x-56q9
  • [thehackernewscryptojs2026] — The Hacker News, "CryptoJS Weak RNG Behind $5.7 Million in Drains Affects Five Crypto Wallet Apps" (the root-cause reporting: the custom Marsaglia Multiply-With-Carry PRNG seeded from Math.random() introduced in 3.1.2-4 in June 2014 and present in every 3.x release except 3.2.0/3.2.1, the ~2³⁹ / 2⁴⁷ effective search spaces against 128 / 256-bit nominal, the five affected apps and their fix status — RRWallet and Milo discontinued with no fix, Bexo 20.1.0, NanChat 1.3.0, Bitcoin Libre v4 — the sweep breakdown of ~$3.14M from 431 accounts on 2026-05-27 and ~$2.55M from 522 seeds between 2026-05-30 and 2026-07-13 for a measured $5,690,922 lower bound, Juliano Rizzo's 2026-06-10 report with two months of withheld detail, and the point that a weak phrase stays guessable even when imported into a hardware wallet): https://thehackernews.com/2026/08/cryptojs-weak-rng-behind-57-million-in.html
  • [startupfortuneillbloom2026] — Startup Fortune, "The Ill Bloom vulnerability has already drained over $5 million from crypto wallets and thousands more addresses remain at risk" (independent confirmation of losses and the residual at-risk population): https://startupfortune.com/the-ill-bloom-vulnerability-has-already-drained-over-5-million-from-crypto-wallets-and-thousands-more-addresses-remain-at-risk/

Discussion

Ill Bloom is the middle term of a three-case cohort OAK now documents in full — Milk Sad (2023, examples/2023-08-milk-sad-libbitcoin-bx-mersenne-twister-entropy-collapse.md), Ill Bloom (2026-05), and Coldcard (examples/2026-07-coldcard-firmware-rng-fallback-entropy-collapse-sweep.md, 2026-07/08) — and it is the one that adds the enumeration problem.

The other two are bounded. Milk Sad names a tool and a version range; Coldcard names a vendor, specific models, and firmware version windows. An affected user in either case can determine their status and act. Ill Bloom's boundary is "less common mobile software wallets", and the researchers say plainly that their address sets are incomplete. That converts a technical vulnerability into an epistemic one: the population that should migrate cannot be identified, so the correct advice is unavoidably over-broad — anyone who generated a seed in an uncommon mobile wallet should migrate whether or not a checker flags them. OAK should expect this shape to recur, because the long tail of wallet software has no registry, no coordinated-disclosure convention, and in many cases no maintainer left to notify.

There is also a sequencing observation worth recording, and it is uncomfortable. Ill Bloom's first sweep was 2026-05-27 and its public disclosure came in July 2026; the Coldcard sweep began 2026-07-30/31, weeks later. Whether the two share an operator is not established and OAK does not assert it. What can be said is that a weak-key cohort sweep of one wallet population was publicly documented shortly before a much larger one was executed against another, which at minimum demonstrates that the technique — enumerate a weak keyspace offline, stage per-chain tooling, sweep by balance in a single coordinated burst — was being actively practised and publicised in the same quarter. Milk Sad's 2023-07-12 event already showed operators maintaining a standing inventory of weak-key populations and sweeping several cohorts together. Contributors documenting the next case in this class should check explicitly for overlap in attacker addresses and sweep methodology against these three, because the cohort-portfolio behaviour is the part of this class most likely to connect otherwise unrelated incidents.

Update, 2026-08-05 — the enumeration problem is now half-closed, and the half that remains changed shape. With CryptoJS.lib.WordArray.random() named in GHSA-rg76-677x-56q9 / CVE-2026-71851, Ill Bloom is no longer bounded by the phrase "less common mobile wallets". It is bounded by a dependency: any application that called that function to generate BIP-39 entropy on any 3.x version other than 3.2.0/3.2.1. Five apps are named, but the affected set is defined by an SBOM query, not by a vendor list — and crypto-js is one of the most widely depended-upon JavaScript packages in existence. The correct question for any wallet team reading this is no longer "is my wallet on the list" but "did any code path in my key generation ever reach crypto-js below 4.0.0", which is answerable from a lockfile in minutes and was not answerable at all before August.

Two features of the root cause deserve to outlive the incident. The first is that the entropy loss was structural rather than accidental: seeding a Marsaglia MWC generator from Math.random() is a reasonable thing to do for shuffling a list and an indefensible one for a key, and the function's name distinguished neither. The second is the revert. A correct fix shipped in 3.2.0/3.2.1 and was pulled in 3.3.0 to preserve backward compatibility — meaning the ecosystem had the right answer, deployed, and traded it away to avoid breaking users whose only dependency on the old behaviour was reproducibility of weak output. Nine years later that trade cost $5.7M in measured thefts and an unknown number of unswept weak seeds still in circulation. When OAK's cohort framing asks where this class comes from, the honest answer from this case is not "bad cryptography" — someone wrote the good version — but a maintenance decision made under the wrong risk model, which is a far more common and far more reproducible failure.

Techniques demonstrated (2)