過去1週間(2026/07/27 - 2026/08/02)において、注目すべきセキュリティインシデントは以下の2件で、合計損失額は約$88Mに達しています。
| 日付 | インシデント | タイプ | 推定損失額 |
|---|---|---|---|
| 2026/07/29 | LULA | ビジネスロジックの欠陥 | ~$578K |
| 2026/07/30 | COLDCARD | 不完全なエントロピー生成 | ~1,370 BTC (~$88M)* |
* COLDCARDの損失額は確認方法によって異なります。表示されている~1,370 BTC(~$88M)は、公開検証可能なオンチェーン上の最小値です(coldcardwatch.com)。プライベートチャネルでの照合(Galaxy Research、73名の被害者との連絡に基づく)ではより高い数値、約1,596 BTCとされており、疑わしいが未確認のドレインを含めると最大で約2,055 BTC(~$130M)に達します。
選定理由
- LULA: AMMペアの残高を移動させ、リザーブの再同期を強制できる特権的なトークン関数が、価格操作によって繰り返し利用可能な流動性引き抜きのプリミティブとなりました。
- COLDCARD: ウォレットファームウェアにおけるビルドおよび統合エラーが、シード生成を決定論的なソフトウェアフォールバックへと密かに経由させ、エントロピーの保証を損ない、シードの復元をオフライン検索に変え、大規模な資金損失へとエスカレートしました。
Best Security Auditor for Web3
Validate design, code, and business logic before launch
今週のハイライト: COLDCARD
今週のハイライトとしてCOLDCARDを選んだ理由は、ウォレットのエントロピーに関するバグが今期最大の損失を生んだことです。根本原因は、設定マクロが有効化されているかどうかではなく、存在するかどうかだけをチェックするビルドガードであり、これは機能テストでは捉えられない類の静かな統合エラーです。この教訓は、オンチェーンのセキュリティがオフチェーンのランダム性に依存しているすべてのシステムに当てはまります。
BitcoinハードウェアウォレットであるCOLDCARDは、2021年に出荷されたファームウェアにおいて、意図されたハードウェア乱数生成器(RNG)ではなく決定論的なソフトウェアソースを使用してウォレットシードを生成していました [1][2]。この欠陥は2026年7月末まで大規模には悪用されませんでしたが、7月30日から始まったオンチェーン上の波状の掃き出しにより、影響を受けたウォレットが標的となりました。公開確認済みの損失は合計で少なくとも1,370 BTC(8月5日時点の$64,099の価格で約$88M)に達し [3]、プライベートに確認された報告では最大で約1,596 BTCに達するとされています [4]。根本原因は、シード生成を意図されたハードウェアRNGではなくソフトウェアフォールバックへと誤って経路付けたビルドおよび設定エラーでした。影響を受けたデバイスにおいて、これによりシードの復元は暗号学的に不可能な問題からオフライン検索へと変化しました。
背景
COLDCARDはBitcoinハードウェアウォレットです。ウォレットの秘密鍵とアドレスはすべて単一の秘密値、すなわちシードから導出されるため、いかなる自己管理型ウォレットのセキュリティも、そのシードの2つの特性、すなわち秘密が保たれること、そして生成時に予測不可能であることに依拠します。ハードウェアウォレットは主に最初の特性を保護するために存在しますが、このインシデントは2番目の特性の失敗です。BIP-39シードフレーズは人間が読める形式ですが、予測不可能性の要件の根底にあるセキュリティ特性は、それを作成するために使用されるランダムバイトのエントロピーです。それらのバイトが再現可能であれば、シードも再現可能です。直感的には、コンビネーションがサイコロを振って決められる金庫を考えてみてください。サイコロに仕掛けがあれば、その偏りを知る誰にでも金庫は開いてしまいます。鍵がいかに強力であっても関係ありません。
ウォレットにとって「仕掛けられたサイコロ」とは、弱い乱数生成器を意味します。ハードウェアウォレットは、セキュアなマイクロコントローラ上のハードウェア真性乱数生成器(TRNG)からシードのエントロピーを取得することが期待されています。なぜなら、ソフトウェアの疑似乱数生成器(PRNG)は決定論的であり、その内部状態と呼び出し履歴が分かれば、出力を正確に再現できてしまうためです。生成器の出力が予測可能な場合、その候補範囲を列挙し、アドレス、xpub、公開鍵などの公開ウォレットデータと照合することができ、これによりシードの復元は暗号学的に不可能な問題からオフライン検索へと崩れ落ちます。
COLDCARDのファームウェアは、2つの別々のRNGサーフェスを公開していました。MicroPythonは、ウォレットの暗号ライブラリが期待するグローバルなrng_get()シンボルを公開するSTM32プラットフォームレイヤーを出荷しており、COLDCARDもまた独自のボード固有のハードウェアRNGラッパーを維持していました。両方のサーフェスはハードウェアのエントロピーを提供することを意図されており、ウォレットの暗号ライブラリは、ファームウェアのビルド時に解決される単一のグローバルRNGシンボルを通じてそのいずれかにアクセスします。
脆弱性の分析
根本原因は、MICROPY_HW_ENABLE_RNG設定マクロを取り巻くビルドおよび統合エラーでした。COLDCARDのプロダクションボード設定は、このマクロを0に設定していました。これは、ファームウェアがMicroPythonのハードウェアRNG実装ではなく、独自のボード固有ハードウェアRNGラッパーを使用することを意図していたためです。しかし、ウォレット生成のパスはngu.random.bytes(32)へと移行されており、暗号ライブラリのSTM32パスは、最終的にMicroPythonによって解決されるグローバルなrng_get()シンボルに依存していました。
問題のチェーンは以下の通りです:
generate_seed()
-> ngu.random.bytes(32)
-> libngu CHIP_TRNG_32()
-> rng_get()
-> MicroPython STM32 RNG module
-> Yasmarang software fallback because MICROPY_HW_ENABLE_RNG == 0
ボード設定はMicroPythonのハードウェアRNGブランチを無効化していました:
// We have our own version of this code.
#define MICROPY_HW_ENABLE_RNG (0)
暗号ライブラリはそれでも、このマクロをハードウェアRNGの十分な証拠として扱っていました [5]。なぜなら、rng_get()を呼び出す前に、マクロが存在するかどうかだけをチェックしていたためです:
extern uint32_t rng_get(void);
#define CHIP_TRNG_32() rng_get()
#ifndef MICROPY_HW_ENABLE_RNG
#error "get a HW TRNG plz"
#endif
このガードは危険なケースを見逃しています。すなわち、0として定義されたマクロもやはり「定義されている」ため、#ifndefチェックは通過し、ビルドは成功してしまいます。MicroPythonはマクロの存在ではなく値によってRNG実装を選択するため、MICROPY_HW_ENABLE_RNG == 0は、rng_get()をCOLDCARDのボード固有ラッパーではなくソフトウェアフォールバックブランチへと経路付けてしまいました [6]:
#if MICROPY_HW_ENABLE_RNG
// STM32 hardware RNG
#else
// Yasmarang software fallback
#endif
結果はデバイスの世代によって異なります。Mk2/Mk3ファームウェアv4.0.0-v4.1.9については、Blockの分析 [7] によれば、ngu.randomには暗号学的エントロピーが一切追加されておらず、フォールバック状態と呼び出し履歴が分かれば、ウォレット生成は決定論的になり得ます(Coinkiteのアドバイザリ [2] では、Mk2/Mk3の範囲をもう少し狭く、v4.0.1-v4.1.9として規定しています)。Mk4/Q/Mk5については、セキュアエレメントの材料がハッシュ化されていましたが、ngu.random.reseed()には4バイトのみが渡されており、セキュアなリシードが単一の32ビット状態ワードに限定され、ユーザーが期待するウォレットのエントロピーよりもはるかに効果の低い探索空間となっていました。最終的な32バイトのランダムバイトをハッシュ化しても結果のエントロピーを増やすことはできず、すでに限定された候補集合を変換するだけです。
攻撃の分析
スマートコントラクトのエクスプロイトとは異なり、このインシデントには追跡すべき単一のオンチェーン攻撃トランザクションがありません。これはオフラインのシード復元問題であり、その後にオンチェーン上の掃き出しが続いたものでした。前提条件は、影響を受けたユーザーが脆弱なngu.random.bytes(32)パスを通じてウォレットシードを生成していたことであり、そのシード素材が完全なハードウェアエントロピーではなく再現可能なソフトウェアフォールバック状態に依存していたことです。2番目の、推測される前提条件は、影響を受けたウォレットがシードのみから導出可能であったことです。強力でユニークなBIP-39パスフレーズは、PBKDF2を通じてRNGの欠陥が全く影響を与えなかった、独立したユーザー提供のエントロピーを混入させるため、そのようなウォレットは純粋なシード列挙の対象外となります。そして、掃き出しの規模から、影響を受けたユーザーの大半はそのようなパスフレーズを設定していなかったことが示唆されます。そこから、復元は以下の3つのステップで進行したと考えられます:
- 攻撃者は、デバイスのメタデータ、起動タイミング、RTC/SysTickの前提、そしてもっともらしいRNG呼び出し履歴を用いて、RNG状態の候補を絞り込むか列挙しました。
- 候補となる各状態について、攻撃者は候補のウォレットシードを導出し、アドレス、xpub、生成された公開鍵などの公開ウォレットデータに対してオフラインで照合しました。
- 候補が実際のウォレットと一致した時点で、攻撃者はシードを復元し、秘密鍵を再構築し、関連するBTCを掃き出しました。
オンチェーン上では、この窃取は7月30日から始まったアドレス掃き出しの波として現れました。独立したオンチェーン上のヒューリスティック追跡 [3] は、4,580件の検証済みアドレスから合計少なくとも1,370 BTC(8月5日のBTC価格$64,099で評価すると約$88M)が掃き出された、複数のドレイン波を確認していますが、これは検証済みの最小値であり総額ではありません。一方、73名の被害者との連絡を通じて確認されたプライベートチャネル [4] では、この数字は約1,596 BTCにまで達するとされており、疑わしいが未確認のドレインを加えると2,055 BTC(~$130M)に近づくとしています。
結論
COLDCARDのインシデントは、エントロピー生成の失敗でした。セキュリティ上重要なシード生成APIが、意図されたハードウェアRNGではなく決定論的なソフトウェアPRNGフォールバックへと静かに解決されていたのです。これは、ビルドガードが設定マクロが有効化されているかどうかではなく存在するかどうかだけをチェックしていたためです。影響を受けたデバイスにおいて、これによりシードの復元は暗号学的に不可能な問題からオフライン検索へと変化し、その結果、複数の波にわたって1,370 BTC以上 [3] が掃き出されました(プライベートチャネルの集計では約1,596から2,055 BTCとされています [4])。
核心となるエンジニアリングの失敗は、出荷されたファームウェアが、そのセキュリティ上最も重要なAPIが実際に意図されたハードウェアRNGに到達していることを一度も証明していなかったことです。3つの実践がこれを捕捉できたはずです。暗号学的エントロピーのビルドガードはマクロの存在と値の両方をチェックすべきであること、エントロピーのフォールバックはソフトウェアPRNGを静かに代替するのではなくフェイルクローズすべきであること、そして最終的なファームウェアイメージの検証は、コードがコンパイルされることだけでなく、シンボルの出自とエンドツーエンドのエントロピーフローをカバーすべきであることです。影響を受けたシードはその場で修正することはできません。その資金は修正されたファームウェアで作成されたウォレットに移動すべきであり、強力でユニークなパスフレーズはシード自体を修復することなく即時のリスクを軽減します [2]。
この失敗のモードは強調しておく価値があります。この種のランダム性のバグは、生成されたすべてのシードが個別には有効であるため、機能テストには見えません。欠陥はいずれかの単一の出力にあるのではなく、それらを生成したソース自体にあります。そのソースが予測可能かつ再現可能であるため、シード全体として小さく列挙可能な範囲に収まってしまうのです。オフチェーンの鍵生成コンポーネントは、第一級のセキュリティ精査に値します。
参考文献
- [1] COLDCARDウォレットの掃き出しを弱いシード生成のランダム性に結び付けたBlockSec Phalconのアラート
- [2] Coinkite、エントロピー問題の技術的な詳細解説
- [3] coldcardwatch.com、Coldcard Sweep Watch: オンチェーン上の掃き出されたアドレスの追跡と方法論
- [4] Galaxy Research、COLDCARDハックの損失推定額(被害者の報告により約1,596 BTCが確認済み)
- [5] libngu、STM32のRNGパスはグローバルな
rng_get()を参照し、#ifndef MICROPY_HW_ENABLE_RNGのみでガードしている - [6] Coldcard MicroPython、ハードウェアRNGが無効な場合、
rng_get()はYasmarangにフォールバックする - [7] Block Engineering、COLDCARDファームウェアにおける予測可能なRNGフォールバックと32ビットリシード
今週のその他のインシデント
LULA
BNB Chain上のBEP-20トークンであるLULAは、2026年7月29日、トークンコントラクトのビジネスロジックの欠陥により約$578Kを失いました。攻撃者が到達可能なパスが、その特権的なrecycle()関数をトリガーできてしまい、RentalコントラクトがそれによってPancakeSwap V2ペアからLULAを直接送出させ、さらにsync()を呼び出すことで、ペアのリザーブを操作された残高へと更新させることができました。攻撃者はrecycle()を繰り返しトリガーし、ペアのLULAリザーブをほぼゼロまで縮小させ、その後わずかな量のLULAをそのUSDTのほぼ全量に交換しました [1]。
背景
LULAは、レンタルベースのチーム報酬メカニズムを持つ、BNB Chain上のBEP-20トークンです。対象となるアドレスは、Rentalコントラクトにチーム報酬を保留額として蓄積し、claimTeamReward()を通じてそれを請求します。請求フローの中で、Rentalコントラクトはトークンのrecycle()関数を呼び出して、報酬配布用のLULAを取得します。recycle()は任意のユーザーから呼び出すことはできず、Rentalコントラクトのみがそれを実行する権限を持っています。
claimTeamReward()のエントリポイントには「EOAのみ」というチェックが含まれています。これは、msg.sender == tx.originとなる外部所有アカウントからの直接呼び出しをサポートしており、また、委任されたコードのプレフィックスを検査することで、EIP-7702委任呼び出しもサポートしています。

自動マーケットメーカー(AMM)において、ペアはそのスワップの価格を、保存されているリザーブから算出します。そして、これらのリザーブは、ペアのsync()関数を通じて更新されます。この関数は、リザーブをペアの現在のトークン残高に設定します。リザーブは通常、スワップおよび流動性イベントに伴って変動するため、本物の取引を反映しますが、ペアのトークン残高は直接的な送金によっても変更され得ます。そしてsync()は、その残高が操作されたものであるかどうかに関わらず、そのときに存在する残高を保存されたリザーブへとそのままコピーします。
脆弱性の分析
根本原因は、LULA.recycle()がRentalコントラクトにPancakeSwap V2ペアからLULAを直接送出させ、その後sync()を呼び出すことを許可していたことであり、これによってペアのリザーブが操作された残高へと更新されてしまいました [1]。

sync()は、ペアに残っているLULA残高がどれであれ、それをそのままリザーブに設定するため、この特権的なパスは、USDT側を全く変更しないまま、ペアのLULAリザーブを任意に低く抑えることができます。LULAリザーブがほぼゼロに近づくと、ペアはわずかな量のLULAをそのUSDTのほぼ全量に相当する価格として算出してしまいます。
攻撃の分析
以下の分析は、トランザクション0xa219ab9...411d7cに基づいています。
- ステップ1: 攻撃者は約197.05M USDTを蓄積することで、操作の資金を調達しました。この資金は、Moolah/Lista、Aave V3、Venus、PancakeSwap V3、PancakeSwap Vault、Uniswap V4 PoolManager、Uniswap V3を含む複数のフラッシュローンおよび借入元から得られました。
- ステップ2: 攻撃者は約197.05M USDTを使用して、PancakeSwap V2ルーターを通じて大規模な
USDT -> LULAスワップを実行しました。これにより、ペアのLULAリザーブは約8M LULAから24,022 LULAへと急激に減少し、一方でUSDT側は約197.64M USDTへと増加しました。 - ステップ3: 攻撃者は複数のEIP-7702ウォレットを通じて報酬パスを起動しました。各ウォレットがRentalコントラクトの
claimTeamReward()を呼び出し、それがLULA.recycle()をトリガーし、ペアのLULAリザーブを24,022 LULAから0.004 LULAへと縮小させました。この時点でも、ペアは依然として非常に大きなUSDT側を保持していました。 - ステップ4: 攻撃者はルーターを通じて最後のPancakeSwap V2スワップを実行し、わずか約4,749 LULAをペアに送り込むことで、約197.64M USDTを受け取りました。
- ステップ5: 攻撃者はすべてのフラッシュローンを返済し、約$578Kの利益を得ました。
結論
BNB Chain上のLULAトークンは、そのトークンコントラクトのビジネスロジックの欠陥を通じて約$578Kを悪用されました。攻撃者が到達可能なパスが、その特権的なrecycle()関数をトリガーできてしまい、RentalコントラクトがそれによってPancakeSwap V2ペアからLULAを直接送出させ、さらにsync()を呼び出すことで、ペアのリザーブを操作された残高へと再同期させることができました。攻撃者はこれを繰り返しトリガーしてペアの価格を歪め、わずかな量のLULAをそのUSDTのほぼ全量に交換しました。
トークンコントラクトは、AMMペアの残高を移動させ、リザーブの再同期を強制できる特権的なパスを絶対に公開してはなりません。そうしてしまうと、そのパスに到達できる者に価格の制御権を渡してしまうことになるためです。AMMペアと統合するトークンは、ペアのリザーブを本物の、市場に基づく残高の変動に厳密に紐付けておく必要があり、価格算出のためにプールのリザーブを読み取るロジックは、それを権威あるものとしてではなく、操作可能なものとして扱うべきです。
参考文献
BlockSecについて
BlockSecは、フルスタックのブロックチェーンセキュリティおよび暗号資産コンプライアンスのプロバイダーです。私たちは、プロトコルやプラットフォームのライフサイクル全体にわたって、顧客がコード監査(スマートコントラクト、ブロックチェーン、ウォレットを含む)を実施し、攻撃をリアルタイムで阻止し、インシデントを分析し、不正資金を追跡し、AML/CFTの義務を果たすことを支援する製品およびサービスを構築しています。
BlockSecは、権威あるカンファレンスにおいて複数のブロックチェーンセキュリティ論文を発表し、DeFiアプリケーションにおけるいくつかのゼロデイ攻撃を報告し、複数のハッキングをブロックして2,000万ドル以上を救出し、数十億ドル規模の暗号資産を保護してきました。
-
公式ウェブサイト: https://blocksec.com/
-
公式Twitterアカウント: https://twitter.com/BlockSecTeam



