Develop with pleasure!

福岡でCloudとかBlockchainとか。

CLN v23.02〜v23.05.2に影響したDoS脆弱性

Core Lightnig v23.02〜v23.05.2に影響した脆弱性について、最近内容が開示された↓

DoS disclosure: Channel open race in CLN - Implementation - Delving Bitcoin

ので、内容を確認してみる。詳細は報告者のブログ記事で説明されている↓

morehouse.github.io

発見された脆弱性は、元々別のフェイクチャネルの脆弱性の修正についてテストをしていたところ新たに発見されたものらしい。折角なのでまずフェイクチャネルの脆弱性についても調べてみた↓

フェイクチャネルによるDoS

こちらも同じ報告者のブログ記事が詳しい↓

morehouse.github.io

この脆弱性は、偽のチャネル開設リクエストを多数発行する攻撃により発生する。

新しくチャネルを開く際、↑の記事にあるように二者間で以下のメッセージがやりとりされる。

https://morehouse.github.io/images/channel_funding.png

1〜4のステップで、FunderとFundeeはチャネル開設用のコミットメントトランザクションを構築し、その署名を交換する。そしてステップ5でFunderがファンディングトランザクションBitcoinネットワークにブロードキャストして、そのトランザクションが指定数承認されたらチャネルが開設される。

このとき、Funderがファンディングトランザクションをブロードキャストしなければ、Fundeeは2016ブロック(約2週間)の間その保留中のチャネルがオンチェーンで承認されないかオンチェーンを監視する必要がある。そのため、ストレージやRAM、CPUリソースが消費される。

これを悪用して、攻撃者は大量の偽のチャネルの開設要求を被害ノードに送信し、被害ノードのマシンリソースを消費させるというのがフェイクチャネルのDoS攻撃。この攻撃では、攻撃者はランダムに生成したIDをトランザクションIDとして偽のファンディングアウトポイントを作成すれば良いので、攻撃者が資金をオンチェーンに保持している必要もない。

脆弱性の影響

主要なライトニングノード実装の影響は以下のとおり:

実装 影響
LND 数日でパフォーマンスが大幅に低下し、ピアやCLIからのリクエストに応答しなくなる。DoS攻撃が終わっても、パフォーマンスの低下は継続する。
CLN 攻撃から1日後、CLNのconnectdデーモンがブロックされ他のノードからの接続要求に応答できなくなる。ただ、他の機能は引き続き動作し(別のデーモンで動作してるので)、タイムロックなどの反応で資金が危険にさらされることはなかった。
Eclair OOMによりクラッシュ。DoS攻撃が終わった後も再起動しても30分以内にOOMでクラッシュする。
LDK ルノード実装ではないため、ldk-sampleノードで実験。DoS攻撃から数時間後にパフォーマンスが大幅に低下し、ブロックチェーンが同期できなくなる。

いずれのノードも攻撃の影響を受け、CLN以外は、資金が危険にされされる可能性があった模様。対応としては、チャネル開設がペンディング中の場合、その上限を設けるようにしたみたい。

競合状態の発生によるDoS

上記のフェイクチャネルの修正のフォローアップのテスト中に発見された新たな脆弱性が今回開示された内容。

この脆弱性は、CLNのチャネル開設フローとピア接続フローの2つの異なるフローが重なった場合に競合状態が発生し、その結果CLNがchanneldデーモンを2回起動しようとしてクラッシュを引き起こすというものみたい。

チャネル開設フロー

通常、CLNに対して新たなチャネル開設をリクエストするとCLNの各デーモンでは以下のフローが実行される(CLNは各機能がそれぞれ別のプロセスで実行されるように構成されている。このような構成のため、フェイクチャネルのDoS攻撃の場合、一部のデーモンのみがダウンして他は機能し続けた模様)。

https://morehouse.github.io/images/cln_channel_open_no_race1.png

  • connectdは、ピアとの接続を管理するデーモン
  • lightningdは、サブデーモンを制御するマスターデーモン
  • opendは、1つのピアとのチャネル開設をネゴシエーションするデーモン
  • channeldは、1つのピアとの開設したチャネルを管理するデーモン

ピア接続フロー

ピアがチャネルをセットアップした後、接続が切断して再接続が発生すると、以下のフローが実行される。

https://morehouse.github.io/images/cln_channel_open_no_race2.png

いずれのフローも最終的に、lightnigdchanneldデーモンを起動する構成になっている。

競合を発生させる攻撃

問題となるは、上記の2つのフローが重なるような実行が発生した場合↓

https://morehouse.github.io/images/cln_channel_open_race.png

chanbackupプラグインの処理に時間がかかるとこのような競合状態が発生する。その結果、ピアに対して2回channeldの起動が行われ、アサーションに失敗し、CLNがクラッシュする。

この攻撃を成功させれるためには、多くのピア接続やチャネルステートの変更などによってchanbackupプラグインの処理を遅くする必要がある。上記のフェイクチャネル攻撃もそういった攻撃の方法の1つ。

↑の記事では、インターネット上で約30秒の作業でCLNをクラッシュさせることができたらい。

フェイクチャネルの脆弱性の修正中にこの競合が発見されなかったのは、単に、chanbackupプラグインが導入されたのがそれより後だったからということみたい。

その後、ピア接続時のフックによるプラグインの処理が終わった後、すでにそのピアとのchanneldが実行されている場合は、再度channeldを起動しようとしないという修正が行われたCLN 23.08がリリースされている。