Develop with pleasure!

福岡でCloudとかBlockchainとか。

Bitcoin Core v22.0未満に存在したブロック遅延バグの開示

Optechのニュースレターに掲載されていた、Delving Bitcoinフォーラムで開示されたBitcoin Core v22.0より前のバージョンに存在したブロック遅延攻撃を可能にする脆弱性

https://delvingbitcoin.org/t/block-stalling-issue-in-core-prior-to-v22-0/499

脆弱性自体は3年前に責任ある開示が行われv22で修正されているけど、まだv22未満のノードを実行しているユーザーがいることから開示されたみたい。

脆弱性を悪用するとLNなどのタイムロック系コントラクトを狙った攻撃を行えるが、↓の攻撃内容を見る限り攻撃を成功させるのもハードル高そう。

ブロック受信の遅延

まず攻撃をするためには、コンパクトブロックリレーを最初に無効化する必要がある。

Bitcoin Coreはマイニングされたブロックの受信にBIP-152で定義されているコンパクトブロックリレーを使用している。BIP-152については、↓

techmedia-think.hatenablog.com

BIP-152には実装に関して以下の記述がある:

充分なインバウンドの帯域幅は持つノードの場合、3つまでのピアに対して最初の引数に1をセットしたsendcmpctメッセージを送信する(=high-bandwidthモードで動作させる)ことを推奨する。可能であれば、ここで選択する3つのピアは過去の実績において素早くブロック情報を返すピアを選択することが推奨され、ノードはそれらのピアからほんの0.5*RTTでブロックを受信することが可能になる。

ノードは(アウトバウンドの帯域幅をムダに使用することになるため)3つ以上のピアにhigh-bandwidthモードのsendcmpctメッセージを送ってはならない。

この結果、Bitcoin Coredeha高帯域幅のコンパクトブロックリレーを行う対象として、ノードに迅速にブロックの情報を提供するピアを3つ選択するようになっていた。

つまり、攻撃者が誠実なノードよりも速くブロックを提供できれば、このコンパクトブロックリレーのスロットを占有できる。攻撃にあたっては、まずはこれを占有して、コンパクトブロックリレー経由のブロックの通知を実質無効にする。コンパクトブロックリレーが有効に機能しないと、他のピアから新しいブロックのアナウンスを受け取り、従来のBLOCKメッセージを使って新しいブロックを受け取るしかない。

攻撃手順

  1. 攻撃者は、被害者のノードに対して、他のピアよりも速く新しいブロックを提供することで、ノードのコンパクトブロックリレーの3つの接続スロットをすべて占有する。
  2. 被害ノードとの間に1とは別にN個の異なる接続を開く。LNを対象として攻撃する場合、LNノードのCLTV deltaが40の場合はN = 50。※ ただし、このN個の接続は被害者ノードのコネクションマネージャーのvNodesベクトル内で連続している必要がある。
  3. 新しいブロックがマイニングされたら、N個の接続の内、先頭の接続が、他の誠実なピアと競争して、新しいブロックを被害ノードにヘッダーファーストで通知する。成功したら、被害ノードのmapBlocksInFlightにエントリーが追加される。その後、BLOCKメッセージを使って新しいブロックを送信する必要があるが、ここでその送信を遅延させて対象ブロックを配信しない。この時、被害ノードがブロックを待つのは10分まで。
  4. その間、1で設定したコンパクトブロックリレーの接続は新しいブロックについて何もアナウンスしない。
  5. 10分経過する手前で、先頭の接続は、無効なブロックをBLOCK`メッセージで送信する or 接続を単に切断する。
  6. そうなると、被害ノードはvNodes内の次の接続を選択して、遅延しているブロックを要求する。
  7. この次の接続でも攻撃者は同様の振る舞いを行い、ブロックの送信を遅延させる。
  8. これを繰り返すことで、N×10分間(N = 50の場合は約500分)被害ノードには新しいブロックがリレーされなくなる。

LNでの影響

↑の攻撃では、攻撃者によりコンパクトブロックリレーが実質無効化され、さらにN個の接続が連続して被害ノードのvNodesに挿入される必要がある。

もしそういう状況になると、LNで支払いを転送している場合に、そのHTLCの金額を盗む攻撃が可能になる可能性がある。具体的には、被害者BのLNノードに対して、攻撃者のノードM1とM2がそれぞれチャネルを開いている状態で、以下の経路で支払いが転送されるケースが対象になる。

M1 -> 被害者B -> M2

各LNノードのHTLC deltaの設定値を40と仮定した場合、攻撃のシナリオは以下のようになる:

  1. M1が上記の経路でM2に支払いを送信する。現在のブロック高をTとした場合、B→M2のHTLCはT + 40でタイムアウトし、M1→BのHTLCはT + 80でタイムアウトする。
  2. T + 38くらいで(もっと前でもいい)M1とM2が上記のブロック遅延攻撃を開始する。
  3. まずM2がBとのチャネルを強制クローズするTxをブロードキャストし、それがT + 39で承認される。
  4. 続いて、M2はプリイメージを使ってHTLCを請求するTxをブロードキャストし、それがT + 40で承認される。
  5. 今度はM1はT + 40でBとのチャネルを強制クローズし、それがT + 41で承認される。
  6. M1はT + 80まで待って、HTLCのタイムアウトTxをブロードキャストし、それがT + 81で承認される。
  7. M1とM2がそれぞれHTLCの金額を入手したので攻撃を止める。

この攻撃でも、Bのノードがmempoolを監視していれば、4の後でプリイメージをmempoolから抽出してM1のHTLCを回収できる。ただ、攻撃者がマイナーと協力して4のトランザクションP2Pネットワークにブロードキャストせずに直接ブロックに格納してもらって配信すると、Bにはブロックが届かないためプリイメージを知ることができず攻撃の影響を受ける。

修正内容

この問題に対する修正のPRは以下の2つ。

ということで、攻撃が成功する可能性は低いと思うけど、まだアップデートしていない場合は要アップデート。