LNDの脆弱性の詳細
今月上旬、ライトニングノードの実装のうちの1つであるLndに大きな脆弱性が発見されたためユーザーがノードの更新を促されるという事件がありました。Lndはライトニングノードのシェアが9割ほどある、「ライトニング界のBitcoin Core」に近い存在なので、ちょうどライトニングに批判の矛先が向いていた時期だったため大きく取り上げられました。2週間ほど経って、今回アップデートが促される原因となった4月に報告された2つの脆弱性に関して、メーリングリストにて詳細が公開されました。1つ目はv0.10.0-betaにて修正された暗号の実装周りのバグで、悪用された事例は観測されませんでした。2つ目はv0.11.0-betaにて修正されたライトニングのルーティングとインボイスの管理に関するバグで、やはり悪用された事例は観測されていません。
本記事では両方について軽く解説します。
ライトニングノードをまだアップデートしていない方は、至急Lndを修正済みのバージョン0.11.0-beta以降にアップデートしましょう。最新版は0.11.1-betaです。
もしLndではなくc-lightningまたはEclairを使っている場合は、影響はありません。
① 暗号の実装周りのミス
2017年にSegwitの導入で解決方向に動いた1つの問題として、トランザクション展性の問題がありました。これは、ユーザーがビットコイントランザクションに署名して配信した後、悪意のある他のノードが(トランザクションの内容は変えずに)署名部分に細工することでトランザクションIDが変わる、という内容の攻撃を可能にする脆弱性です。(Segwit以降のトランザクション展性の対策に関してはBIP-146などを参照)
取引所などのサービスが送金を受け付ける場合にTXIDが変わってしまうことで着金の確認が難しくなったり、送金時に未承認のトランザクションに子トランザクションを連ねる場合に、親トランザクションのTXIDが変わることで子トランザクションたちも無効になってしまうなどの問題に繋がります。
トランザクション展性を引き起こす1つの問題は、楕円双曲線暗号による署名は(r, s)という値の組み合わせに対して有効なのですが、(r, -s(mod n))という組み合わせに対しても有効なことです。BIP-146では、低い方のs値 (LOW_S)の使用を強制することで対策しています。しかしLndでは、その対策が導入される前のビットコインの暗号学ライブラリを踏襲していたため、LOW_Sのチェックがされず、HIGH_Sで署名されたHTLCを無効としていませんでした。
このため、悪意ある相手がチャネルの非協力的クローズを引き起こすと、最新の状態ではない、1つ前のHTLCをTXIDを改変して配信することができてしまい、被害者がそれに対応する最新状態を一定時間内に生成できなければ、攻撃者がタイムアウトによるトランザクションを配信してチャネルの残高を全額受け取ることができました。協力的クローズはより包括的なチェックがあるため、この脆弱性の影響はありませんでした。
② インボイスのプリイメージの管理方法のミス
特定のインボイスに関してプリイメージを公開させられてしまう脆弱性ライトニングノードは送金の中継をする際にHTLCのバケツリレーをしますが、この際のHTLCにも受け取る側がプリイメージを生成し、支払いを受け取ったときに開示します。このため、インボイスを発行した場合のプリイメージと送金中継時のプリイメージを別々のデータベースで管理しています。
ライトニングの基本的な仕組みについては数度触れていますので、過去に私が書いたライトニング関連記事をご覧ください。
送金を中継する際、ライトニングノードは自身は中継点なのか、最終目的地なのかを判別できます。このとき、最終目的地であればインボイスのデータベースを参照してプリイメージを返送し、中継点であればプリイメージのデータベースを参照します。
その際、プリイメージのデータベースに該当するプリイメージがなかった場合に、自動的にインボイスのデータベースに切り替える処理があったことが今回の脆弱性です。インボイスを発行して支払いを待つ被害者のノードの手前に攻撃者のノードがある状況を考えます。攻撃者は被害者宛の送金の中継を一旦停止し、被害者を経由して自分自身に戻るようなルート(「偽のHTLC」)を差し込みます。「偽のHTLC」に関して、被害者宛ての送金のプリイメージハッシュと同じハッシュを含めて被害者ノードに送ることで、被害者ノードは意図せずインボイスのプリイメージを攻撃者に渡してしまいます。攻撃者は自分に「一周してきた」送金を再び停止します。
この時点で、攻撃者の手元には「被害者宛のトランザクションに関する本物のHTLC」と「被害者から返ってきた偽のHTLC」の2つのHTLCが停止しています。
ここで攻撃者は被害者に対して非協力的チャネルクローズを行います。脆弱性の結果、被害者のノードの視点ではプリイメージを返して決済したことになってしまっているので、チャネルは平和に最新状態でクローズします。
しかし、実際には「偽のHTLC」を通して受け取った金額は攻撃者に中継しており(中継手数料のみが被害者の手元に残る)、チャネルクローズ後にプリイメージを利用して本来受け取るはずだったトランザクションの金額を全て攻撃者に横取りされてしまうのです。この脆弱性も4月に報告されていたにも関わらず修正が遅くなった理由として、言語化することが非常に難しい脆弱性であることと、修正する対象の機能に安定性の問題が発生し、その対応にも追われたためだとされています。幸運にも、この脆弱性が悪用されたという報告はありません。Payment Secretsという、支払い者がパスワードのようなものを含めて送金する仕組みを使えば、攻撃者はプリイメージに加えて知り得ないパスワードが必要なためこの攻撃の手法を使って横取りすることはできませんが、現時点では任意で設定可能な機能なので、利用は広まっていません。
遠くない将来にリリース予定の0.12.0-betaからは少なくともLNDにおいてPayment Secretsの使用を必須にすることを検討しているそうです。
アップデート方法
BTCPayServerやRaspiBlitz、ノンカストディアルなライトニングウォレットなどはそれぞれがサイトやSNSで告知している方法でアップデートしましょう。アプリによっては既に0.11.0-beta以降を使用しているものもあるかもしれませんが、確認しましょう。最新版は0.11.1-betaです。コマンドラインから管理している方は自分で調べる力があると思いますが、GitHubのこのページのUpdate以下に書いてあります。
まとめ
Lightning Labsの暗号学エンジニアも言語化が難しいと言う脆弱性なだけあって、特に2つ目は難しかったかもしれません。両方とも比較的シンプルな凡ミスのようなバグですが、かなり大きな影響が考えられるものでした。ライトニングネットワークのプロトコル開発者が増えて、より多くの人がコードに目を通すまで、このような脆弱性の発覚は時々あるかもしれません。また、このような脆弱性の存在が複数種類の実装が存在することのメリットであり、またエンジニアが分散して監査力を弱める弱点でもあります。このあたりの教訓は実装がBitcoin Coreに偏りがちなビットコイン自体にも依然として通用するものでしょう。
次の記事
読者になる
一緒に新しい世界を探求していきましょう。
ディスカッション