This is a really great analysis of how the coldcard attacker went about identifying and sweeping funds. The author is the maintained of Cove Wallet, @praveenperera.
The most interesting finding is that there are 153 addresses that were swept in the first wave, but which no researcher has been able to reconstruct the seeds for.
All 153 transactions use the same builder as the recovered set. The difference therefore appears upstream of transaction construction: candidate generation, device state, derivation coverage, or the data used to select targets.
The search history makes the gap more interesting than a normal incomplete scan.Across the PRNG paths and address derivations I tested, I checked 104 billion candidate seeds and performed 5.60 trillion address checks, at a GPU cost of about $200. That search effort is why I think a missed path is unlikely, although a shared blind spot remains possible.
- Expanding BIP49 receive coverage past index 25 recovered a new Wave 1 seed at index 40.
- Searching nonzero BIP84 accounts recovered two more Wave 1 seeds.
- Checking more address indexes on both the receive and change branches recovered additional Wave 1 sources.
- Nine alternative Coldcard event traces matched new candidate seeds to historically funded addresses outside Wave 1 and reproduced already-known Wave 1 sources, but found no new source in the 153.
- Searches above the observed pad range, plus partial and evenly spaced tests across the full 32-bit pad range, found no new member of the 153.
- An independently reported full raw-pad search also found none, although its full artifacts are not public.
Praveen also also notes that no other researcher he has spoken with has reproduced a seed from one of these 153 addresses. Clearly, there is some missing piece of information or non obvious method that the attacker had but that the researchers lack.
Perhaps the information that allows researchers to figure out how the attacker swept these 153 addresses will reveal something about the approach that helps to identify the attacker.
The whole article is full of interesting observations and well worth the read. Here are a few highlights:
Once I had recreated the affected seed-generation process, I generated candidate seeds, derived their Bitcoin addresses, and compared those addresses with the Wave 1 transaction set. This linked 1,042 of the 1,195 sweep transactions to 328 reconstructed seeds. They account for 949.70395260 BTC, or 87.72% of the value. The final 153 transactions contain 132.94923662 BTC.
No researcher I have spoken with has reproduced a seed for any of those 153 source addresses. That repeated failure may be the most useful clue about what the attacker knew or did differently. The last part of this post examines that gap.
- The final 153 source addresses, containing 132.94923662 BTC, remain unexplained. No researcher I have spoken with has reproduced a seed for any of them. They use the same transaction builder as the recovered set, so the missing difference appears to be earlier in the attacker’s process. Public reconstruction attempts may be missing an input or a candidate-generation method.
All 1,195 traceable source transactions have the same basic form:The input order is more distinctive. There are 145 transactions with more than one input. All 145 spend the source address’s UTXOs from newest funding transaction to oldest. This is not BIP69 ordering, wallet coin selection, or the natural order produced by most general wallet software. It looks like an address API returned transaction references in reverse blockchain order and the sweep builder kept that order.
- transaction version 2;
- locktime 0;
- final input sequence
0xffffffff, so no opt-in RBF;- one destination output;
- one source address per transaction;
- a fee equal to 30 times the same static size estimate;
- no low-R signature grinding.
The results were still handled as separate address records. The 1,042 source transactions map to 328 seeds, with as many as 58 swept addresses from one seed. That behavior fits a process that derived standard paths, ranked addresses by balance, and saved address-and-key records without preserving the wallet as the unit of work.
I think the attacker used a paid blockchain-data API to discover balances and UTXOs, then signed the transactions with separate code. BlockCypher is the closest technical match I have found. Its Bitcoin address endpoint returns newest records first, defaults to 200 records, and tells the caller when another page exists. For the address with 225 UTXOs, I reproduced the exact 200 selected UTXOs, in the same order, with the live BlockCypher endpoint. This makes BlockCypher my leading hypothesis for the UTXO-discovery step.
~lol
This answer is great!
source
https://twiiit.com/KLoaec/status/2088209131731648928
Maybe the 153 addresses was attacker ‘stealing’ from themselves? A sort of red herring?
It seems like that would be a lot of added risk for the attacker with very little gain.
the 153 addresses nobody can rebuild a seed for is the scariest part of this. the rest all trace to the same RNG flaw, so the attacker had another derivation path or another leak nobody's found yet. and it cost two hundred bucks of gpu time to map a thousand btc drain, that ratio is the whole story