Back to Blog

Solanaネットワークの重大なバグ検知と迅速な修正方法

Code Auditing
June 7, 2022
6 min read

4月、当社の脆弱性検出システムはSolanaのrBPF(SolanaのdAppsがすべて動作する仮想マシンです。https://github.com/solana-labs/rbpf)に問題を発見しました。詳細な調査の結果、これはスマートコントラクトの不正な実行パスにつながる可能性のあるセキュリティ脆弱性であることが判明しました。このバグをSolanaのセキュリティチームに報告したところ、チームは直ちに脆弱性を確認し、修正しました。また、当社チームには80万米ドル相当のSoLトークンが付与されました。

この脆弱性は、rBPFの新しいバージョン(0.2.26から0.2.27)に存在します。当社が問題を報告した時点では、メインネットで使用されているバリデーターはこの影響を受けるバージョンにアップグレードされていませんでした。当社のシステムは、影響を受けるバージョンがマージされる前に問題を検出したため、メインネットのバリデーターはこの脆弱性の影響を受けずに済みました。

以下に、この脆弱性の詳細を説明します。

1. eBPFとrBPF

eBPF(Extended Berkeley Packet Filter)は、当初カーネルでのパケットフィルタリングのために開発されました。eBPFのセキュリティ、効率性、スケーラビリティにより、現在ではネットワーク、トレーシング、プロファイリングなど、さまざまな分野で使用されています(etc)。eBPFの豊富な機能性を考慮し、Solanaはそれをスマートコントラクトの実行エンジンとして使用しています。Solana上でdAppsを開発するために、開発者はRustでスマートコントラクトを開発し、コントラクトをeBPFバイトコードにコンパイルします。

Solanaは、Rustで書かれた仮想マシンであるrBPFを使用して、コンパイルされたBPFバイトコードを実行します。しかし、提案されている仮想マシン(つまりrBPF)が堅牢で安全かつ正確であるかは不明です。rBPFにセキュリティ上の問題が存在する場合、rBPFを含むすべてのバリデーターが影響を受け、Solanaネットワーク全体に多大な損失(例:資金の喪失)をもたらす可能性があります。

2. 原因

当社は、rBPFの実装バグを自動的に特定し、rBPFのコードを定期的にスキャンするツールを開発しました。スキャンプロセス中に、rBPF(バージョン0.2.26)で深刻な問題が特定されました。これは、コントラクトの不正な実行パスにつながる可能性があります。

具体的には、sdiv命令は符号付き除算命令として使用されており、rbpf 0.2.26でデフォルトで有効化された機能として導入されました。sdivは、32ビット(sdiv32)と64ビット(sdiv64)の両方のオペランドの除算をサポートしています。sdiv32命令の場合、計算結果は64ビットのbpfレジスタに格納されます。しかし、sdiv32命令の後の命令が計算結果を64ビットとして読み取った場合、結果が異なる可能性があります。これは、rBPFがJITコンパイル中にsdiv32の計算結果を64ビットの正しい値に拡張しないためです。

たとえば、正の数(12)を負の数(-4)でsdiv32で割った場合、正しい結果は32ビットと64ビットの両方で-3になるはずです。以下のコードはその例です。

JITモードとインタープリターモードの両方で実行およびトレースを行った後、両者の違いを観察することができました。

2.1 インタープリターモード

0 [0000000000000000, 0000000400000000, 0000000000000000, 0000000000000000, 0000000000000000, 0000000000000000, 0000000000000000, 0000000000000000, 0000000000000000, 0000000000000000, 0000000200014000]    29: lddw r5, 0x10000000c
 1 [0000000000000000, 0000000400000000, 0000000000000000, 0000000000000000, 0000000000000000, 000000010000000C, 0000000000000000, 0000000000000000, 0000000000000000, 0000000000000000, 0000000200014000]    31: sdiv32 r5, -4
 2 [0000000000000000, 0000000400000000, 0000000000000000, 0000000000000000, 0000000000000000, FFFFFFFFFFFFFFFD, 0000000000000000, 0000000000000000, 0000000000000000, 0000000000000000, 0000000200014000]    32: jslt r5, 0, lbb_7
 3 [0000000000000000, 0000000400000000, 0000000000000000, 0000000000000000, 0000000000000000, FFFFFFFFFFFFFFFD, 0000000000000000, 0000000000000000, 0000000000000000, 0000000000000000, 0000000200014000]    36: exit

2.2 JITモード

0 [0000000000000000, 0000000400000000, 0000000000000000, 0000000000000000, 0000000000000000, 0000000000000000, 0000000000000000, 0000000000000000, 0000000000000000, 0000000000000000, 0000000200014000]    29: lddw r5, 0x10000000c
 1 [0000000000000000, 0000000400000000, 0000000000000000, 0000000000000000, 0000000000000000, 000000010000000C, 0000000000000000, 0000000000000000, 0000000000000000, 0000000000000000, 0000000200014000]    31: sdiv32 r5, -4
 2 [0000000000000000, 0000000400000000, 0000000000000000, 0000000000000000, 0000000000000000, 00000000FFFFFFFD, 0000000000000000, 0000000000000000, 0000000000000000, 0000000000000000, 0000000200014000]    32: jslt r5, 0, lbb_7
 3 [0000000000000000, 0000000400000000, 0000000000000000, 0000000000000000, 0000000000000000, 00000000FFFFFFFD, 0000000000000000, 0000000000000000, 0000000000000000, 0000000000000000, 0000000200014000]    33: lddw r0, 0x1
 4 [0000000000000001, 0000000400000000, 0000000000000000, 0000000000000000, 0000000000000000, 00000000FFFFFFFD, 0000000000000000, 0000000000000000, 0000000000000000, 0000000000000000, 0000000200014000]    35: exit

インタープリターモードでは、レジスタr50xFFFFFFFFFFFFFFFD(32ビットおよび64ビットモードで-3)に設定されますが、JITモードではr50x00000000FFFFFFFDに設定されます。この場合、64ビット値を受け取るjslt命令にとっては、r5は正の数(0x00000000FFFFFFFD)として認識されます。その後、実行パスは完全に不正になります。

3. 影響

この不正な実装は、コントラクトの不正な実行パスにつながり、深刻な問題を引き起こす可能性があります。

例えば、スマートコントラクトにおける重要な操作がsdiv32命令の結果に依存している場合、不正な実行結果につながり、攻撃者によって悪用される可能性があります。

この問題はhttps://github.com/solana-labs/rbpf/pull/283で導入されたため、rBPFはバージョン0.2.26から脆弱性があります。当社はこの問題を特定し、2022年4月28日にSolanaのセキュリティチームに報告しました。チームは迅速に対応し、sdiv32命令に符号拡張処理を追加することで数時間で問題を修正しました。修正はhttps://github.com/solana-labs/rbpf/pull/310にあります。当社のチームによるタイムリーな検出と報告により、メインネットのバリデーターはこの脆弱性の影響を受けませんでした。

この問題はプロトコルのライブネスバグとして分類され、Solanaから80万米ドルのバグバウンティが付与されました。

タイムライン

  • 2022/04/28: Solanaセキュリティチームに問題を報告
  • 2022/04/29: 脆弱性が修正される
  • 2022/05/09: CVE-2022-23066が割り当てられる
  • 2022/06/01: バグバウンティが付与される

BlockSecについて

BlockSecチームは、ブロックチェーンエコシステムのセキュリティに注力し、主要なDeFiプロジェクトと協力して製品を保護しています。チームは、学界および産業界のトップクラスのセキュリティ研究者と経験豊富な専門家によって設立されました。著名なカンファレンスで複数のブロックチェーンセキュリティ論文を発表し、DeFiアプリケーションのゼロデイ攻撃を数件報告し、影響力の大きいセキュリティインシデントの詳細な分析レポートを公開しています。

Twitter: [BlockSecTeam]

Medium: https://blocksecteam.medium.com

Website: https://www.blocksec.com

Sign up for the latest updates
HarmonyのクロスシャードONEミント + 約4700万ドルの鍵漏洩による損失 | BlockSec
Security Insights

HarmonyのクロスシャードONEミント + 約4700万ドルの鍵漏洩による損失 | BlockSec

2026年8月10日〜16日の週、注目すべきセキュリティ事件5件を紹介、損失総額は約4700万ドル。詳細分析はHarmony Layer-1の連鎖実装欠陥に注目。Harmonyでは、クロスシャードのレシート再生により、未署名のMerkleProofのShardIDとBlockNumから支出マーカーを導出し、ONEが不正発行された。約3.01兆ONEが偽造されたが、名目価値は市場総額を大幅に超え、実現・確定損失ではないため総額から除外。約4700万ドルは秘密鍵漏洩(Unknown Whale Wallet約2500万ドル、Kite約1400万ドル、Coinsbuy約790万ドル)とFoxのロジック欠陥(約11.7万ドル)による。

約160万ドルの損失:MokeトークンとLpdFiへの攻撃 | BlockSec週次レポート
Security Insights

約160万ドルの損失:MokeトークンとLpdFiへの攻撃 | BlockSec週次レポート

2026年8月3〜9日の週、BNBチェーンで2件の重大なセキュリティインシデントが発生し、いずれも価格操作により総損失は約160万ドルに上った。LpdFi事件(約69.7万ドル)では、注文評価と利息償還の両方に同じ操作可能なPancakeSwapペアのリザーブが使用され、攻撃者がポジションの元本を水増しし過大な利息を請求した。Mokeトークン(約90.6万ドル)では、操作可能なスポット価格とLP配当の重複計上を組み合わせ、MOKEを水増し請求してBNB配当を複数回取得した。

COLDCARDの事件:ウォレットの「ランダム」シードがランダムではなかった時
Security Insights

COLDCARDの事件:ウォレットの「ランダム」シードがランダムではなかった時

COLDCARDファームウェアのビルド・統合バグにより、Bitcoin種生成がソフトウェアRNGフォールバックに誘導され、脆弱な乱数によりウォレットの秘密鍵がオフラインで復元可能となった。欠陥は種自体にあるためファームウェア更新では修正不可。2026年8月7日までに確認された被害は1,405 BTC(約91億円)、非公式推定では最大2,055 BTCに上る。

Best Security Auditor for Web3

Validate design, code, and business logic before launch. Aligned with the highest industry security standards.

BlockSec Audit
Solanaネットワークの重大なバグ検知と迅速な修正方法