W skrócie

  • Błąd w oprogramowaniu układowym sprawił, że portfele Coldcard generowały ziarna z programowego generatora pseudolosowego zamiast z układu sprzętowego przeznaczonego do tego zadania.
  • Błąd skutecznie zmniejszył przestrzeń poszukiwań ze 128 bitów do około 40 w starszych modelach.
  • Oto, co to wszystko oznacza i jak doprowadziło do kradzieży ponad 130 milionów dolarów w Bitcoinach.

Ktoś opróżnia portfele Bitcoin, które nigdy nie miały być dostępne.

Monety znajdowały się na urządzeniach Coldcard—portfelach sprzętowych od kanadyjskiego producenta Coinkite, takich, które nigdy nie dotykają internetu. Żaden link phishingowy. Żadne złośliwe oprogramowanie. Żaden skradziony laptop. Atakujący po prostu ustalili, jakie były klucze prywatne.

Galaxy Research prześledziło dotychczas kradzież ponad 1 596 BTC w trzech potwierdzonych falach, z podejrzewaną czwartą falą, która podniosłaby sumę do około 2 055 BTC—około 130 milionów dolarów przy obecnych cenach. Jedno przeszukanie przeniosło 70 milionów dolarów w 41 minut. Coinkite twierdzi, że co najmniej 15 różnych atakujących dołączyło.

Firma opublikowała techniczne wyjaśnienie 1 sierpnia, wyjaśniając, co poszło nie tak. Jest to niezwykle szczery dokument, a w skrócie chodzi o to, że portfel rzucał obciążonymi kośćmi przez osiem lat, nikt tego nie zauważając.

Zero wciąż jest czymś

W 2021 roku Coinkite przeniosło kryptografię Coldcard na libsecp256k1, tę samą bibliotekę, której używa Bitcoin Core. Rozsądna decyzja. Integracja to miejsce, w którym wszystko się rozpadło.

Migracja po cichu przekierowała generowanie ziaren z własnego sprzętowego generatora liczb losowych Coldcard na programową rezerwę MicroPython—mały algorytm o nazwie Yasmarang, który istnieje dla urządzeń bez żadnego układu losowości.

Coldcard ma układ losowości. Po prostu przestano go pytać.

Powód jest prawie zbyt mały, aby w to uwierzyć. Strażnik budowy użył #ifndef, który sprawdza, czy ustawienie istnieje, a nie czy jest włączone. Coinkite zdefiniowało to ustawienie jako zero, co oznacza "wyłączone". Ponieważ zero nadal liczy się jako zdefiniowane, kontrola bezpieczeństwa przeszła i budowa została ukończona. Obie wersje funkcji miały identyczne sygnatury, więc nic nie wyglądało na nieprawidłowe.

"Większość losowości na COLDCARD pochodziła z PRNG, o którym nie wiedziałem, że faktycznie znajduje się w bazie kodu źródłowego", napisało Coinkite, odnosząc się do generatora liczb pseudolosowych — oprogramowania, które produkuje liczby wyglądające na losowe, ale postępujące według ustalonego przepisu od wartości początkowej.

Podaj przepisowi tę samą wartość początkową, a otrzymasz ten sam wynik. Za każdym razem.

Na urządzeniach Mk2 i Mk3 z oprogramowaniem układowym 4.0.1 do 4.1.9, ta wartość początkowa pochodziła z numeru seryjnego układu i jego zegara. Coinkite szacuje wynikową przestrzeń poszukiwań na około 40 bitów. Nowsze modele dodawały trochę entropii z elementu bezpiecznego, podnosząc je do około 72 bitów.

Żadna z nich nie osiąga 128, czyli celu.

Ta różnica ma większe znaczenie, niż się wydaje. Bity są wykładnikami. Przestrzeń poszukiwań 128-bitowa zawiera więcej kombinacji niż atomów w obserwowalnym wszechświecie i nikt jej nie przeszukuje. Czterdzieści bitów to około bilion — liczba, którą przyzwoity laptop może przetrawić. Każdy utracony bit zmniejsza pracę o połowę.

Zespół inżynierów Blocka, który opublikował własną analizę, określił efektywną przestrzeń poszukiwań elementu bezpiecznego nowszych urządzeń na 2^32 kandydatów, średnio około 2^31 prób. Ich ocena starszych płyt jest bardziej dosadna: dla znanego identyfikatora urządzenia, stanu timera i historii wywołań, generowanie portfela jest deterministyczne.

A deterministyczny jest przeciwieństwem losowego, co jest niezbędne w kryptografii.

Nie "słaby". Przewidywalny.

Coinkite podejrzewa, że został znaleziony przez maszynę. "Musimy założyć, że ktoś użył AI do przeglądu poprzednich wersji naszego oprogramowania układowego i natknął się na ten problem", napisała firma, dodając, że niedawno uruchomiła jeden z najlepszych dostępnych modeli AI na tym samym kodzie i nic nie znalazła. "Zarówno atakujący, jak i obrońcy mają te same narzędzia AI, ale dziś nam nie pomogło, a pomogło tylko złym ludziom."

Naprawione oprogramowanie układowe jest dostępne dla każdego dotkniętego modelu. Nie naprawia istniejących ziaren; te portfele muszą zostać wygenerowane ponownie, a środki przeniesione. Decrypt opisał, jak przechowywanie z izolacją powietrzną zmienia się po takim wykorzystaniu luki i śledził straty rosnące powyżej 114 milionów dolarów.

Czym właściwie jest entropia

Entropia to miara tego, czego atakujący nie wie.

Innymi słowy, to w zasadzie niepewność, liczona w bitach. Jeden bit to jeden rzut monetą: dwa możliwe wyniki, a zgadujący trafia w połowie przypadków. Dziesięć bitów to 1024 możliwe wyniki. Każdy bit podwaja pracę zgadującego.

Portfel Bitcoin to bardzo duża liczba trzymana w tajemnicy. Adres, na który ludzie wysyłają monety, jest z niej wyprowadzany matematycznie, a wyprowadzenie działa tylko w jedną stronę – można przejść od klucza do adresu, ale nigdy z powrotem.

Zatem bezpieczeństwo każdego portfela spoczywa na jednym pytaniu: Ile liczb musiałby spróbować atakujący?

Jeśli liczba została wybrana z 128 bitami entropii, odpowiedź brzmi: „więcej, niż pozwala fizyka”. Jeśli została wybrana z 40, odpowiedź brzmi: „dajcie mi trochę czasu”.

To ta sama właściwość, która sprawia, że zagrożenie ze strony komputerów kwantowych jest warte dyskusji – maszyna kwantowa zaatakowałaby matematykę łączącą klucz z adresem. Błąd Coldcard nigdy nie musiał tego robić. Sprawił, że klucze stały się zgadywalne, zanim ta matematyka w ogóle weszła w grę.

Tutaj słownictwo staje się śliskie. Generator pseudolosowy produkuje wyniki, które przechodzą testy statystyczne na losowość, więc w zasadzie nic, co arkusz kalkulacyjny by wychwycił. Ten wynik jest nadal w pełni zdeterminowany przez jego wartość początkową. Wygląda losowo, ale nie jest.

Losowość statystyczna i kryptograficzna nieprzewidywalność to różne właściwości, a wynik Coldcard przeszedłby pierwszy test, całkowicie oblewając drugi.

Prawdziwa losowość musi pochodzić z fizycznego szumu: elektrycznego dżittera w obwodzie, fluktuacji termicznych, rozpadu promieniotwórczego. Do tego służył układ sprzętowy w Coldcard. To ten układ został odłączony przez flagę kompilacji.

Potem Luke Dashjr wspomniał o kościach

Gdy użytkownicy gorączkowo regenerowali ziarna, wielu sięgało po oczywiste niskotechnologiczne rozwiązanie. Coldcard pozwala rzucić fizycznymi kośćmi i wprowadzić wyniki jako entropię. Własne wytyczne Coinkite traktują ziarna utworzone z co najmniej 50 niezależnych, prywatnych rzutów kośćmi jako niezagrożone tym błędem.

Może to brzmieć głupio, ale firma faktycznie sprzedaje woreczek ze „100 uroczymi, malutkimi kośćmi”, aby ułatwić ci cały proces.

31 lipca deweloper Bitcoin Core, Luke Dashjr, opublikował ostrzeżenie: „Całkiem sporo osób sugeruje/używa kości do złagodzenia podatności Coldcard. Należy pamiętać, że zwykłe kości nie są zaprojektowane jako kryptograficznie bezpieczne. Jeśli zamierzasz to zrobić, prawdopodobnie powinieneś kupić precyzyjne kości kasynowe. I nawet wtedy miej inne źródło entropii.”

Bitcoinowe Twitter nie przyjęło tego spokojnie.

„lol teraz nie możesz nawet rzucać kością”, napisał jeden z użytkowników. „Samodzielne przechowywanie jest skończone…” Inny zapytał, czy powinien zatrudnić kogoś z chorobą Parkinsona, aby nimi rzucał. (Nie miło.)

Prawdopodobnie najbardziej użyteczna odpowiedź przyszła z arytmetyką. Deweloper Justin Sharp przeliczył dokładnie, ile kosztuje cię zła kość:

„Przesada. Idealna kość k6 daje 2,585 bita na rzut. Wyraźnie obciążona kość, np. z jedną ścianą lądującą w 20% przypadków zamiast 16,7%, nadal daje około 2,55 bita. W przypadku 99 rzutów to różnica między ~256 bitami a ~252 bitami entropii.”

Cztery bity z 256. To cała kara za wyraźnie niesprawiedliwą kość.

Dashjr nie myli się, że tanie kości mają mierzalne obciążenie — wtryskiwane oczka usuwają nieco różne ilości plastiku z każdej ściany, co jest właśnie powodem, dla którego kasyna używają precyzyjnych kości z wypełnieniem. Ma rację co do fizyki, ale myli się co do stawki. Utrata czterech bitów z 256 pozostawia cię z 252. Błąd Coldcard pozostawił użytkowników z 40.

Jednak w jego radzie kryje się ostrzejszy argument, i nie chodzi o tolerancję produkcyjną. Chodzi o to, by nie ufać żadnemu pojedynczemu źródłu. Porażka Coldcard nie polegała na tym, że jego entropia była lekko obciążona — ale na tym, że jeden komponent po cichu przestał wnosić wkład i nic tego nie wychwyciło.

Co z tym zrobić

Jeśli wygenerowałeś seed na dotkniętym Coldcard bez rzutów kością (naprawdę) lub bez silnego hasła BIP-39, ten seed jest skompromitowany.

Zaktualizuj firmware, wygeneruj nowy seed, zweryfikuj odcisk palca, wyślij testową transakcję, a następnie przenieś wszystko. Zalecenie Coinkite przeprowadza cię przez to model po modelu. Wyeksportowane seedy niosą ze sobą wadę — przeniesienie złego seeda do innej aplikacji portfela niczego nie rozwiązuje.

Dla wszystkich innych, wniosek nie jest taki, że portfele sprzętowe są zepsute lub że kości to pułapka.

Chodzi o to, że "losowość" to twierdzenie, a twierdzenia wymagają sprawdzenia. Kod źródłowy Coldcard był publiczny przez cały czas. Zamierzony sprzętowy RNG znajdował się tuż w pliku binarnym. Recenzenci potwierdzili, że istniał, ale nigdy nie potwierdzili, że generator ziarna faktycznie go wywoływał.

Osiem lat audytów patrzyło na właściwy kod. Nikt nie sprawdził, czy został uruchomiony.