Un'ondata precedente dello stesso exploit ha spazzato via 594 BTC (~38 milioni di dollari) da circa 500 wallet a firma singola in un'esplosione di 25 minuti intorno alle 01:31 UTC . Galaxy Research, Chainalysis e il team di ingegneria di Block hanno tutti collegato indipendentemente i furti alla stessa vulnerabilità Coldcard .
Il team di ingegneria e sicurezza Bitcoin di Block, guidato dall'ingegnere Clay Garrett, ha identificato che l'attaccante ha utilizzato un account a pagamento presso un noto fornitore di servizi blockchain per identificare e interrogare in modo efficiente gli indirizzi vulnerabili . Il pattern on-chain dell'attaccante — operazioni di prelievo insolitamente rapide e sequenziali su indirizzi con la stessa debolezza — ha insospettito gli investigatori. Block ha confermato prove che collegano l'attività dell'operatore direttamente all'infrastruttura di quel fornitore .
L'indagine di Block ha scoperto quella che Garrett ha descritto come "una specificità straordinaria, fino al livello dell'account" . Il servizio di analisi ha funzionato di fatto come uno strumento di ricognizione, permettendo all'attaccante di mappare rapidamente quali indirizzi fossero stati generati su firmware vulnerabili e di dare priorità ai target più ricchi .
Il bug è stato introdotto in un commit del firmware di marzo 2021 (a partire dalla versione 4.0.1 del firmware Mk3) durante una migrazione alla libreria libsecp256k1 di Bitcoin Core . Un errore macro nella configurazione di build ha fatto sì che il firmware bypassasse il generatore hardware di numeri casuali (TRNG) STM32 dedicato del dispositivo, ricadendo invece sul generatore software deterministico Yasmarang di MicroPython .
La configurazione della scheda di produzione impostava MICROPY_HW_ENABLE_RNG a zero perché Coldcard aveva un wrapper separato per l'RNG hardware. Ma la libreria libngu non riusciva a chiamare correttamente quel wrapper: la sua condizione di guardia (#ifndef MICROPY_HW_ENABLE_RNG) testava solo se la macro fosse definita, non se il suo valore fosse diverso da zero . Poiché la macro era definita (impostata a zero), libngu concludeva silenziosamente che il percorso hardware fosse disponibile e si legava alla funzione software rng_get() di MicroPython .
Questo ha ridotto l'entropia effettiva a circa 32-40 bit (invece dei 128+ bit previsti), il che significa solo circa 4 miliardi di possibili valori di seed — banalmente forzabili con hardware moderno . I seed generati senza lanci di dadi aggiuntivi da parte dell'utente o una passphrase BIP 39 erano completamente esposti .
Il CEO di Coinkite, Rodolfo Novak (NVK), ha poi riconosciuto l'errore: "Ho impostato esplicitamente MICROPY_HW_ENABLE_RNG a zero, pensando che non avessimo bisogno di nessuna delle due versioni, ma non è quello che fa" .
| Interessati | Non interessati |
|---|---|
| Coldcard Mk3, firmware 4.0.1 fino a 5.0.3 | Mk4, Q, Mk5 (secondo l'analisi iniziale di Coinkite) |
| Seed generati senza lanci di dadi aggiuntivi o passphrase BIP 39 | Seed generati con lanci di dadi aggiuntivi o passphrase |
Coinkite ha poi esteso il suo avviso ad alcune versioni firmware di Mk4, Mk5 e Q dopo ulteriori analisi, rilasciando aggiornamenti firmware di emergenza per tutti i modelli interessati .
Questo exploit ha scosso una delle promesse fondamentali del self-custody — che l'elemento sicuro di un hardware wallet garantisca la sicurezza crittografica indipendentemente dai bug software .
Per un'analisi tecnica dettagliata, consulta il rapporto di engineering di Block e il documento tecnico di Coinkite .