特筆すべきは、攻撃者が物理的に一台のColdcard端末にも触れていない点です。すべての攻撃は、脆弱なファームウェアで生成されたウォレットのシード(復元フレーズ)をリモートで再現することで行われました。
Galaxy Research、Chainalysis、そしてBlock(旧Square)のエンジニアリングチームは独立に調査を行い、いずれもこの流出が同じColdcardの脆弱性に起因するものと結論づけています。
Blockのビットコインエンジニアリング・セキュリティチームを率いるエンジニア、Clay Garrett氏の調査により、攻撃者の手口が明らかになりました。攻撃者は有名ブロックチェーンサービスプロバイダの有料アカウントを使用し、脆弱なアドレスを効率的に特定・照会していたのです。
Garrett氏はこの証拠を「異常なほどの具体性で、アカウントレベルにまで特定できた」と述べています。この分析サービスは事実上の偵察ツールとして機能し、攻撃者はどのアドレスが脆弱なファームウェアで生成されたかを素早く割り出し、最も資産のあるウォレットを優先的に標的にすることが可能でした。
Chainalysisの分析によれば、攻撃者は事前に犠牲者をプロファイリングしていたとされ、これにより最初の10分間で大規模な流出が実現しました。
この脆弱性は、2021年3月にリリースされたMk3ファームウェアバージョン4.0.1のコミットで混入しました。この時、同社はビットコインコアのlibsecp256k1ライブラリへの移行作業を行っていました。
問題はビルド設定のマクロエラーにありました。本来、Coldcardは専用の**STM32ハードウェア乱数生成器(TRNG)**を使用する設計でしたが、このミスにより、そのTRNGがバイパスされ、**MicroPythonの決定論的ソフトウェア乱数生成器「Yasmarang」**にフォールバックしてしまう状態になっていたのです。
具体的には、本番ボード設定でMICROPY_HW_ENABLE_RNGというマクロがゼロに定義されていました(Coldcardは独自のハードウェアRNGラッパーを持っていたため)。しかし、暗号ライブラリlibngu側のガード条件が#ifndef MICROPY_HW_ENABLE_RNGとなっており、これはマクロが定義されているかどうかだけをチェックし、その値が非ゼロかどうかは確認していませんでした。
その結果、値がゼロであってもマクロが定義されているという理由で、libnguは「ハードウェアパスが利用可能」と誤認し、ソフトウェアベースのrng_get()関数にバインド。実効的なエントロピーは本来の128ビット以上からわずか32~40ビットに低下し、可能なシードの組み合わせは約40億通りと、現代のハードウェアでは容易に総当たり(ブルートフォース)可能な範囲にまで減少していました。
CoinkiteのCEO、Rodolfo Novak(NVK)氏は後にこのエラーを認め、「私はMICROPY_HW_ENABLE_RNGをゼロに設定し、どちらのバージョンも必要ないと考えたが、それが正しい動作ではなかった」と説明しています。
| 影響あり | 影響なし(当初) |
|---|---|
| Coldcard Mk3, ファームウェアバージョン4.0.1~5.0.3 | Mk4, Q, Mk5(Coinkiteの初回分析による) |
| ユーザーによるサイコロロールやBIP 39パスフレーズなしで生成されたシード | ユーザーがサイコロロールやパスフレーズを追加したシード |
その後、Coinkiteは調査を拡大し、特定のMk4、Mk5、およびQモデルのファームウェアバージョンも影響を受ける可能性があると警告を更新。全対象モデル向けの緊急ファームウェアアップデートをリリースしました。
今回の事件は、**「ハードウェアウォレットのセキュアエレメントがあれば、ソフトウェアのバグに関係なく暗号学的な安全性が保証される」**という自己保管の根幹をなす信頼を大きく揺るがしました。
詳細な技術的分析については、BlockのエンジニアリングレポートおよびCoinkiteのテクニカルバックグラウンダーを参照してください。