著者: Chengdu Lian’an 原文:「クロスチェーンブリッジセキュリティに関する研究(3)」 | Polygon Warrior Safe 透析、「パンドラの箱」の開封を防ぐには?
前回の記事(Cross-Chain Bridge Security Research (2) | Nomad ブリッジの最初の分散型強盗は私たちに何をもたらしますか?)、Nomad ブリッジプロトコルの専門的なテクニカル分析を詳細に実施します。
本日、成都チェーンセキュリティ研究チームは、ポリゴン戦士であるポリゴンの安全な透析を行いますので、読み続けてください。
Polygonは、イーサリアムのレイヤー2スケーリングソリューションであり、イーサリアムのブロックチェーンインターネットを構築するというビジョンを持っています。 Polygonは、開発者がイーサリアムのセキュリティを活用して、カスタマイズされたアプリケーションに焦点を当てたチェーンを作成し、zk-rollup、PoSなどのさまざまなスケーリングスキームを組み合わせた相互運用可能なネットワークを提供できる共通のフレームワークを提供します。 その中で、Polygon PoSは現在、Polygonで最も成熟した有名なスケーリングソリューションです。 トランザクション処理にサイドチェーンを使用して、トランザクション速度の向上とガス消費の節約という目的を達成し、ネットワーク構造には主に次の3つのレイヤーが含まれます。
イーサリアムメインネット上の一連の契約は、主にステーキング、チェックポイント、報酬契約など、PoSステークに関連するステーキング管理機能を担当しており、トークンをステーキングする人は誰でもバリデーターとしてシステムに参加できるように、MATICネイティブトークンのステーキング機能を提供し、ステーキング報酬を得るためのPolygonネットワークの変換の検証、二重署名、バリデーターのダウンタイム、その他の違法行為に対するバリデーターの罰則、チェックポイントの保存などを担当しています。
PoS Heimdallノードのセットで構成されるプルーフ・オブ・ステーク・バリデーター・レイヤーは、イーサリアムにデプロイされた一連のステーキングコントラクトをリッスンしながら、Polygonネットワークのチェックポイントをイーサリアムのメインネットに送信する役割を担います。 主な流れは、まず、Bor レイヤーでブロックを作成してブロードキャストするブロックプロデューサーとして、バリデータプール内のアクティブなバリデータのサブセットを選択し、次に Bor が提出したチェックポイントに基づいて Merkle ルートハッシュと署名を付加し、最後に提案者が責任を持って指定されたチェックポイントのすべてのバリデータ署名を収集し、署名の数が 2/3 以上に達した場合、チェックポイントをイーサリアムに提出するというものです。
ブロックプロデューサーレイヤーは、Heimdallレイヤーのバリデーター委員会によって定期的に選ばれるブロックプロデューサーのグループで構成され、Polygonサイドチェーン上のトランザクションの集約とブロックの生成を担当するバリデータのサブセットです。 この層は、以下の図に示すように、チェックポイントを Heimdall 層に定期的に公開し、チェックポイントは Bor チェーンのスナップショットを表します。
チェックポイント機構とは、Bor レイヤーのデータをイーサリアムに同期させる仕組みで、同期されたデータはチェックポイント、つまりチェックポイント間隔に含まれる Bor レイヤーのブロックデータのスナップショットであり、ソースコードは以下のようになります。
プロポーザー:プロポーザーはバリデーターによっても選ばれ、ブロックプロデューサーとプロポーザーはバリデータのサブセットであり、その責任はプール全体におけるステークによって決定されます
RootHash: StartBlock と EndBlock の間の Bor ブロックから生成されたマークル ハッシュです。
以下は、RootHash 値を生成するための 1 から n の番号が付けられた Bor ブロックの擬似コードです。
要約すると、この値はメルケルツリーのルートハッシュ値であり、Borブロックヘッダーのブロック番号、ブロックタイムスタンプ、トランザクションツリーのルートハッシュ値txハッシュ、およびレシートツリーのルートハッシュから計算されたkeccak256ハッシュ値で構成されます。
AccountRootHash:イーサリアム上の各チェックポイントに送信する必要があるバリデーター関連のアカウント情報のマークルハッシュで、個々のアカウント情報のハッシュ値は次のように計算されます。
AccountRootHash は、RootHash 値と同じ方法で、アカウントマークルツリーのルートハッシュから生成されます。
StateSyncは、イーサリアムのデータをPolygon Maticチェーンに同期することを指し、主に以下のステップに分かれています。
1)まず、イーサリアム上のコントラクトがStateSender.solのsyncState()関数をトリガーし、状態を同期します
2)syncState()関数は、次のようにイベントイベントを発行します。
4)borレイヤーのノードは、APIを介して同期される上記のリストを取得し、それをborレイヤーのコントラクトに渡して、さらにビジネスロジックを処理します。
Polygon Bridgeは、PolygonとEthereum間の双方向のクロスチェーンチャネルを可能にし、ユーザーがサードパーティの脅威や市場の流動性の制約なしに、2つの異なるチェーンプラットフォーム間でトークンを簡単に転送できるようにします。 Polygon BridgeにはPoSとPlasmaの2種類があり、どちらもPolygonとEthereum間の資産の転送に以下のような類似点があります。
1)まず、下の画像に示すように、イーサリアム上のトークンをPolygonにマッピングする必要があります。
2)双方向アンカーリング技術(双方向ペグ)も使用されています。
a:イーサリアムから転送されたすべてのトークン資産は、最初にイーサリアムにロックされ、同じ数のマッピングされたトークンがポリゴンで鋳造されます。
b:トークン資産をイーサリアムに引き出すには、まずこれらのマッピングされたトークンをPolygonで燃やし、次にイーサリアムにロックされている資産のロックを解除する必要があります。
次の図は、PoS Bridge と Plasma Bridge の比較を示しています。
上の図からわかるように、セキュリティの面では、PoS Bridgeは外部バリデータセットのセキュリティに依存しているのに対し、PlasmaはEthereumメインチェーンのセキュリティに依存しています。 同時に、ユーザーがクロスチェーン資産の転送(PolygonからEthereumへのトークンの転送など)を行う場合、PoSは約20分から3時間のチェックポイント間隔のみを必要としますが、Plasmaは7日間の異議申し立て期間を必要とします。 同時に、PoSはより標準的なトークンをサポートしていますが、PlasmaはETH、ERC20、ERC721の3つのタイプしかサポートしていません。
PoSブリッジは、主に2つの機能で構成されています:DepositはEthereum上のユーザーの資産をPolygonに転送することを指し、WithdrawalsはPolygonからEthereumに資産を引き出すことを指します。
以下は、AliceがPoS Bridgeを使用して、EthereumアカウントからPolygonアカウントにトークン資産を送信する例です。
approtect 関数には、次の 2 つのパラメーターがあります。
Spender:ユーザーがトークンの使用を承認する宛先アドレス
amount:使用できるトークンの数
depositFor 関数には 3 つのパラメーターがあります。
user:Polygonで入金トークンを受け取ったユーザーのアドレス
rootToken:メインイーサリアムチェーン上のトークンアドレス
depositData:ABIによってエンコードされたトークンの数
以下は、RootChainManagerコントラクトのdepositFor関数の特定のコードです。
ソースコードを分析すると、この関数は最初にトークンに対応する述語コントラクトアドレスを取得し、次にそのlockTokens()関数を呼び出してコントラクト内のトークンをロックしていることがわかります。 最後に、syncState() は _stateSender によって状態同期のために呼び出されますが、これは admin によって設定された状態送信者によってのみ呼び出すことができます。
最初のパラメータはログのシーケンス番号インデックスで、2 番目のパラメータは呼び出し元が登録済みの正当なコントラクト アドレスであるかどうかを確認するために使用され、3 番目のパラメータは状態と同期する必要があるデータです。 トランザクションは Heimdall ブロックに追加され、保留状態の同期リストに追加されます。
data: bytes32 syncType と bytes syncData。 syncType がマッピングの場合、syncData はエンコードされた rootToken アドレス、childToken アドレス、および bytes32 tokenType であり、syncType が deposit の場合、syncData はエンコードされたユーザーアドレスです。 bytes 型の rootToken アドレスと depositData。 depositDataはREC20の数量とERC721のtokenIdです。
この関数には 2 つのパラメーターがあります。
user: 入金しているユーザーのアドレス
depositData:ABIでエンコードされた金額
以下は、ユーザーAliceがPoS Bridgeを使用して、Polygonアカウントに入金された資金をEthereumアカウントに引き出す例です。
Withdraw には、バーンされるトークンの数という 1 つのパラメーターのみが含まれています。 対応するトークンコントラクトのwithdraw()関数は次のとおりです。
上記のトランザクションは、約20分から3時間後にチェックポイントに含まれ、バリデーターはそれをイーサリアムに提出します。
トランザクションがチェックポイントに追加され、イーサリアムに送信されると、イーサリアム上のRootChainManagerコントラクトのexit()関数が呼び出され、送信されたチェックポイントの内容を検証することでPolygonでの引き出しトランザクションの有効性が確認され、対応するPredicateコントラクトがトリガーされて、ユーザーの預け入れトークンのロックが解除されます。
関数に渡されるプルーフ証明 inputData には、次のデータが含まれます。
headerNumber: 出金トランザクションのチェックポイントブロックヘッダーが含まれます。
blockProof: 子チェーンのブロックヘッダーが、コミットしたマークルルートのリーフノードであることを証明します。
blockNumber: 出金トランザクションを含む子チェーンのブロック番号
blockTime:出金トランザクションのブロックタイムスタンプ
txRoot: ブロックトランザクションツリーのルート値
receiptRoot:ブロックレシートツリーのルート値
レシート:出金取引のレシート
receiptProof:出金取引の領収書のメルクプルーフ
branchMask: レシート ツリーの 32 ビットで表されるレシートへのパス
以下は、主に3つの部分からなる関数のコアロジックです:最初の部分は引き出しトランザクションのレシートの有効性を検証すること、2番目の部分はチェックポイントにトランザクションブロックが含まれているかどうかを検証すること、3番目の部分は述語コントラクトのexitTokens()関数を呼び出してロックされたトークンをユーザーに送信することです。
PoS Bridgeクロスチェーンメッセージングプロセスのソースコード分析によると、プロセス全体の関数呼び出しはバリデーターによって指定されたロールによってのみ呼び出すことができるため、クロスチェーンのセキュリティはPoS(公証人)によってのみ保証されます。
Plasma Bridge には、次の図に示すように、入金と出金の 2 つの機能も含まれています。
ポリゴンプラズマは、主にアカウントベースのプラズマモアVPモデルを使用するクロスチェーンブリッジシリーズの最初の記事で紹介したビットコインプラズマMVPの実装とは少し異なります。 Plasmaと比較して、アルゴリズムは撤退部分で部分的に改善されています。
ERC20とERC721のトークン転送は、ビットコインUTXOと同様のイベントログを介して実現されるため、最初にイベントを紹介しましょう。
input1:送金前の送金者の口座残高
input2:送金前の受取人の口座残高
output1:送金後の送金者の口座の残高
output2:送金後の受取人の口座残高
第二に、オリジナルのPlasma MVPは1人のオペレーターまたは少数のブロックプロデューサーによって生成されるため、Polygonには2つの攻撃シナリオがあります。
オペレーターの悪:
前の記事(クロスチェーンブリッジセキュリティに関する研究(2) | Nomad cross-chain bridge)は、ユーザーのトランザクションがオペレーターによってPlasmaブロックにパッケージ化されると、オフチェーンデータが利用できなくなると述べています。 したがって、ユーザーがエグジットトランザクションを行う際に、古いトランザクションから引き出しを開始すると、オペレーターは最新のトランザクションの1つでチャレンジすることができ、チャレンジは成功します。 同時に、Plasmaで使用されているPoSチェックポイントメカニズムにより、オペレーターがバリデーターと共謀して悪事を働いた場合、バリデーターは状態遷移を偽造してイーサリアムに提出することさえできます。
ユーザーの悪:
ユーザーは、クロスチェーンの二重支払いと同様に、出口トランザクションを開始した後もPolygonでトークンを使い続けます。
要約すると、PolygonのPlasma MoreVpアルゴリズムは、最新のトランザクションから終了するための出口優先順位を計算するために別のアルゴリズムを使用します。 このメソッドはUTXOに似たLogTransferイベントを使用するため、ユーザーの正当なトランザクションが正しいinput1とinput2を使用している限り、ユーザーのトランザクションの前に悪意のあるトランザクションがパッケージ化されていたとしても、ユーザーのトランザクションは有効な入力からのみ発生するため、ユーザーのトランザクションを正しく処理できます。 関連する擬似コードは次のとおりです。
ユーザーAliceがPlasma Bridgeを使用して、EthereumアカウントからPolygonアカウントにトークン資産を送信する例を考えてみましょう。
1.まず、ユーザーは、メインチェーン(イーサリアム)上のPolygonコントラクトのdepositManagerに転送する必要があるトークン資産をapprotect関数を通じて承認する必要があります。
2.承認されたトランザクションが確認された後、ユーザーはerc20token.deposit()関数を呼び出して、depositManager契約のdepositERC20ForUser()関数をトリガーし、ユーザーのERC20トークン資産を入金します。
注:childChainコントラクトのソースコードの分析によると、PlasmaはETH、ERC20、ERC721の3つのタイプのみをサポートしています。
ユーザーがPlasmaブリッジを使用してPolygonからEthereumに資産を引き出す場合、次の手順に従います。
また、Polygon 上の Plasma Client の withdrawStart() インターフェース実装を呼び出すこともできます。
検証に合格すると、WithdrawManager.addExitToQueue()が呼び出され、優先度の高い順にメッセージキューに挿入されます。
最後に、addExitToQueue()は_addExitToQueue()を呼び出して、NFTを返金バウチャーとして発行します。
ユーザーは 7 日間のチャレンジ期間を待機します
チャレンジ期間が終了したら、WithdrawManager.processExits() 関数を呼び出して、ユーザーにトークンを送信できます。
この関数は 2 つのステップに分かれており、まず、メッセージキュー内の引き出しトランザクションが 7 日間のチャレンジ期間を過ぎたかどうかを確認し、チャレンジ期間が過ぎた場合は、キューからトランザクションを削除します。
次に、チャレンジ期間中に返金バウチャーNFTが削除されているかどうかを判断し、削除されていない場合はNFTが破棄され、対応するアセットがユーザーに返却されます。
2021年10月5日、ホワイトハットのGerhard Wagner氏は、8億5,000万ドルの二重支払い攻撃につながる可能性のあるPolygonの脆弱性を報告し、ホワイトハットはPolygonから公式に2,000,000ドルのバグバウンティを受け取りました。
上記のPlasma Bridgeの紹介では、完全なWithdrawトランザクションプロセスは次のとおりです。
- ユーザーがPolygonでDrawトランザクションを開始し、Polygonでユーザーのトークンをバーンします。
- チェックポイント間隔 (約 30 分) の後、引き出しトランザクションがチェックポイントに含まれるのを待ちます。
- バリデーターの2/3以上が署名してイーサリアムに送信し、その時点でユーザーはERC20PredicateBurnOnlyコントラクトのstartExitWithBurntTokens()を呼び出して、チェックポイントにバーントランザクションが含まれているかどうかを確認します。
- 検証に合格すると、NFT返金バウチャーが発行され、ユーザーに送信されます
- ユーザーは 7 日間のチャレンジ期間を待機します
- WithdrawManager.processExits()を呼び出してNFTを破棄し、ユーザーに返金します
注:トランザクションのリプレイ(二重支払い攻撃)を防ぐために、PolygonはNFTを払い戻しの証拠として使用し、引き出しトランザクションを一意に識別します。 しかし、NFTのID生成の欠陥により、攻撃者は、同じ有効な出金取引を用いてIDの異なる複数のNFTを生成するパラメータを構築し、これらのNFTを返金取引に利用することで、「二重支払い攻撃」を実現することができます。
ここでは、NFTの生成方法を詳しくご紹介します。
パラメータ分析によると、exitid = priorityの場合、NFTのIDはPlasma Bridgeの年齢優先度の左シフトによって生成されます。
この値は、年齢を生成するときにも使用されます。
攻撃者が最初の 16 進ビットが 1 と 3 に等しくならないように branchMaskBytes パラメーターを作成した場合、同じトランスコードされた値を取得する方法は 14*16 = 224 通りあります。
具体的な攻撃プロセスは次のとおりです。
- Polygon Plasma経由でPolygonに大量のETH/トークンを入金する
- Polygonで出金取引を開始し、7日間のチャレンジ期間を待ちます
- 出金トランザクションのbranchMaskBytesパラメータの最初のバイトを変更し(同じ有効なトランザクションを最大223回再送信できます)、出金トランザクションを繰り返し開始します
要約すると、この脆弱性は主に、リプレイを防ぐために払い戻しバウチャーを生成するNFTのIDアルゴリズム設計の問題が原因であり、その結果、同じ払い戻しトランザクションが異なるNFTを生成し、二重支払い攻撃につながる可能性があります。 エンコードされたブランチマスクの最初のバイトは常に0x00である必要があることがわかります。 修正は、エンコードされたブランチマスクの最初のバイトが0x00かどうかを確認し、それを誤ったマスクとして扱わないことです。
さて、今日の共有は終わりました、次号では、成都チェーンセキュリティセキュリティ研究チームが別のクロスチェーンプロジェクトのセキュリティ研究を紹介しますので、楽しみにしていてください。
20.15K 人気度
5.88K 人気度
4.67K 人気度
2.96K 人気度
88.58K 人気度
Polygon Warrior Polygon Security Dialysis:クロスチェーンのセキュリティと安定性を確保する方法は?
著者: Chengdu Lian’an
原文:「クロスチェーンブリッジセキュリティに関する研究(3)」 | Polygon Warrior Safe 透析、「パンドラの箱」の開封を防ぐには?
前回の記事(Cross-Chain Bridge Security Research (2) | Nomad ブリッジの最初の分散型強盗は私たちに何をもたらしますか?)、Nomad ブリッジプロトコルの専門的なテクニカル分析を詳細に実施します。
本日、成都チェーンセキュリティ研究チームは、ポリゴン戦士であるポリゴンの安全な透析を行いますので、読み続けてください。
1_Polygonは誰ですか?
Polygonは、イーサリアムのレイヤー2スケーリングソリューションであり、イーサリアムのブロックチェーンインターネットを構築するというビジョンを持っています。 Polygonは、開発者がイーサリアムのセキュリティを活用して、カスタマイズされたアプリケーションに焦点を当てたチェーンを作成し、zk-rollup、PoSなどのさまざまなスケーリングスキームを組み合わせた相互運用可能なネットワークを提供できる共通のフレームワークを提供します。 その中で、Polygon PoSは現在、Polygonで最も成熟した有名なスケーリングソリューションです。 トランザクション処理にサイドチェーンを使用して、トランザクション速度の向上とガス消費の節約という目的を達成し、ネットワーク構造には主に次の3つのレイヤーが含まれます。
イーサリアムレイヤー:
イーサリアムメインネット上の一連の契約は、主にステーキング、チェックポイント、報酬契約など、PoSステークに関連するステーキング管理機能を担当しており、トークンをステーキングする人は誰でもバリデーターとしてシステムに参加できるように、MATICネイティブトークンのステーキング機能を提供し、ステーキング報酬を得るためのPolygonネットワークの変換の検証、二重署名、バリデーターのダウンタイム、その他の違法行為に対するバリデーターの罰則、チェックポイントの保存などを担当しています。
ヘイムダルレイヤー:
PoS Heimdallノードのセットで構成されるプルーフ・オブ・ステーク・バリデーター・レイヤーは、イーサリアムにデプロイされた一連のステーキングコントラクトをリッスンしながら、Polygonネットワークのチェックポイントをイーサリアムのメインネットに送信する役割を担います。 主な流れは、まず、Bor レイヤーでブロックを作成してブロードキャストするブロックプロデューサーとして、バリデータプール内のアクティブなバリデータのサブセットを選択し、次に Bor が提出したチェックポイントに基づいて Merkle ルートハッシュと署名を付加し、最後に提案者が責任を持って指定されたチェックポイントのすべてのバリデータ署名を収集し、署名の数が 2/3 以上に達した場合、チェックポイントをイーサリアムに提出するというものです。
Bor レイヤー:
ブロックプロデューサーレイヤーは、Heimdallレイヤーのバリデーター委員会によって定期的に選ばれるブロックプロデューサーのグループで構成され、Polygonサイドチェーン上のトランザクションの集約とブロックの生成を担当するバリデータのサブセットです。 この層は、以下の図に示すように、チェックポイントを Heimdall 層に定期的に公開し、チェックポイントは Bor チェーンのスナップショットを表します。
2_Polygon 相互運用性
2.1 チェックポイント
チェックポイント機構とは、Bor レイヤーのデータをイーサリアムに同期させる仕組みで、同期されたデータはチェックポイント、つまりチェックポイント間隔に含まれる Bor レイヤーのブロックデータのスナップショットであり、ソースコードは以下のようになります。
プロポーザー:プロポーザーはバリデーターによっても選ばれ、ブロックプロデューサーとプロポーザーはバリデータのサブセットであり、その責任はプール全体におけるステークによって決定されます
RootHash: StartBlock と EndBlock の間の Bor ブロックから生成されたマークル ハッシュです。
以下は、RootHash 値を生成するための 1 から n の番号が付けられた Bor ブロックの擬似コードです。
要約すると、この値はメルケルツリーのルートハッシュ値であり、Borブロックヘッダーのブロック番号、ブロックタイムスタンプ、トランザクションツリーのルートハッシュ値txハッシュ、およびレシートツリーのルートハッシュから計算されたkeccak256ハッシュ値で構成されます。
AccountRootHash:イーサリアム上の各チェックポイントに送信する必要があるバリデーター関連のアカウント情報のマークルハッシュで、個々のアカウント情報のハッシュ値は次のように計算されます。
AccountRootHash は、RootHash 値と同じ方法で、アカウントマークルツリーのルートハッシュから生成されます。
2.2 StateSync
StateSyncは、イーサリアムのデータをPolygon Maticチェーンに同期することを指し、主に以下のステップに分かれています。
1)まず、イーサリアム上のコントラクトがStateSender.solのsyncState()関数をトリガーし、状態を同期します
2)syncState()関数は、次のようにイベントイベントを発行します。
4)borレイヤーのノードは、APIを介して同期される上記のリストを取得し、それをborレイヤーのコントラクトに渡して、さらにビジネスロジックを処理します。
2.3 ポリゴンブリッジ
Polygon Bridgeは、PolygonとEthereum間の双方向のクロスチェーンチャネルを可能にし、ユーザーがサードパーティの脅威や市場の流動性の制約なしに、2つの異なるチェーンプラットフォーム間でトークンを簡単に転送できるようにします。 Polygon BridgeにはPoSとPlasmaの2種類があり、どちらもPolygonとEthereum間の資産の転送に以下のような類似点があります。
1)まず、下の画像に示すように、イーサリアム上のトークンをPolygonにマッピングする必要があります。
2)双方向アンカーリング技術(双方向ペグ)も使用されています。
a:イーサリアムから転送されたすべてのトークン資産は、最初にイーサリアムにロックされ、同じ数のマッピングされたトークンがポリゴンで鋳造されます。
b:トークン資産をイーサリアムに引き出すには、まずこれらのマッピングされたトークンをPolygonで燃やし、次にイーサリアムにロックされている資産のロックを解除する必要があります。
次の図は、PoS Bridge と Plasma Bridge の比較を示しています。
上の図からわかるように、セキュリティの面では、PoS Bridgeは外部バリデータセットのセキュリティに依存しているのに対し、PlasmaはEthereumメインチェーンのセキュリティに依存しています。 同時に、ユーザーがクロスチェーン資産の転送(PolygonからEthereumへのトークンの転送など)を行う場合、PoSは約20分から3時間のチェックポイント間隔のみを必要としますが、Plasmaは7日間の異議申し立て期間を必要とします。 同時に、PoSはより標準的なトークンをサポートしていますが、PlasmaはETH、ERC20、ERC721の3つのタイプしかサポートしていません。
3_Crossチェーン メッセージング - PoS ブリッジ
PoSブリッジは、主に2つの機能で構成されています:DepositはEthereum上のユーザーの資産をPolygonに転送することを指し、WithdrawalsはPolygonからEthereumに資産を引き出すことを指します。
入金
以下は、AliceがPoS Bridgeを使用して、EthereumアカウントからPolygonアカウントにトークン資産を送信する例です。
approtect 関数には、次の 2 つのパラメーターがあります。
Spender:ユーザーがトークンの使用を承認する宛先アドレス
amount:使用できるトークンの数
depositFor 関数には 3 つのパラメーターがあります。
user:Polygonで入金トークンを受け取ったユーザーのアドレス
rootToken:メインイーサリアムチェーン上のトークンアドレス
depositData:ABIによってエンコードされたトークンの数
以下は、RootChainManagerコントラクトのdepositFor関数の特定のコードです。
ソースコードを分析すると、この関数は最初にトークンに対応する述語コントラクトアドレスを取得し、次にそのlockTokens()関数を呼び出してコントラクト内のトークンをロックしていることがわかります。 最後に、syncState() は _stateSender によって状態同期のために呼び出されますが、これは admin によって設定された状態送信者によってのみ呼び出すことができます。
最初のパラメータはログのシーケンス番号インデックスで、2 番目のパラメータは呼び出し元が登録済みの正当なコントラクト アドレスであるかどうかを確認するために使用され、3 番目のパラメータは状態と同期する必要があるデータです。 トランザクションは Heimdall ブロックに追加され、保留状態の同期リストに追加されます。
data: bytes32 syncType と bytes syncData。 syncType がマッピングの場合、syncData はエンコードされた rootToken アドレス、childToken アドレス、および bytes32 tokenType であり、syncType が deposit の場合、syncData はエンコードされたユーザーアドレスです。 bytes 型の rootToken アドレスと depositData。 depositDataはREC20の数量とERC721のtokenIdです。
この関数には 2 つのパラメーターがあります。
user: 入金しているユーザーのアドレス
depositData:ABIでエンコードされた金額
出金
以下は、ユーザーAliceがPoS Bridgeを使用して、Polygonアカウントに入金された資金をEthereumアカウントに引き出す例です。
Withdraw には、バーンされるトークンの数という 1 つのパラメーターのみが含まれています。 対応するトークンコントラクトのwithdraw()関数は次のとおりです。
上記のトランザクションは、約20分から3時間後にチェックポイントに含まれ、バリデーターはそれをイーサリアムに提出します。
トランザクションがチェックポイントに追加され、イーサリアムに送信されると、イーサリアム上のRootChainManagerコントラクトのexit()関数が呼び出され、送信されたチェックポイントの内容を検証することでPolygonでの引き出しトランザクションの有効性が確認され、対応するPredicateコントラクトがトリガーされて、ユーザーの預け入れトークンのロックが解除されます。
関数に渡されるプルーフ証明 inputData には、次のデータが含まれます。
headerNumber: 出金トランザクションのチェックポイントブロックヘッダーが含まれます。
blockProof: 子チェーンのブロックヘッダーが、コミットしたマークルルートのリーフノードであることを証明します。
blockNumber: 出金トランザクションを含む子チェーンのブロック番号
blockTime:出金トランザクションのブロックタイムスタンプ
txRoot: ブロックトランザクションツリーのルート値
receiptRoot:ブロックレシートツリーのルート値
レシート:出金取引のレシート
receiptProof:出金取引の領収書のメルクプルーフ
branchMask: レシート ツリーの 32 ビットで表されるレシートへのパス
以下は、主に3つの部分からなる関数のコアロジックです:最初の部分は引き出しトランザクションのレシートの有効性を検証すること、2番目の部分はチェックポイントにトランザクションブロックが含まれているかどうかを検証すること、3番目の部分は述語コントラクトのexitTokens()関数を呼び出してロックされたトークンをユーザーに送信することです。
PoS Bridgeクロスチェーンメッセージングプロセスのソースコード分析によると、プロセス全体の関数呼び出しはバリデーターによって指定されたロールによってのみ呼び出すことができるため、クロスチェーンのセキュリティはPoS(公証人)によってのみ保証されます。
4_Crossチェーンメッセージング - プラズマブリッジ
Plasma Bridge には、次の図に示すように、入金と出金の 2 つの機能も含まれています。
ポリゴンプラズマは、主にアカウントベースのプラズマモアVPモデルを使用するクロスチェーンブリッジシリーズの最初の記事で紹介したビットコインプラズマMVPの実装とは少し異なります。 Plasmaと比較して、アルゴリズムは撤退部分で部分的に改善されています。
ERC20とERC721のトークン転送は、ビットコインUTXOと同様のイベントログを介して実現されるため、最初にイベントを紹介しましょう。
input1:送金前の送金者の口座残高
input2:送金前の受取人の口座残高
output1:送金後の送金者の口座の残高
output2:送金後の受取人の口座残高
第二に、オリジナルのPlasma MVPは1人のオペレーターまたは少数のブロックプロデューサーによって生成されるため、Polygonには2つの攻撃シナリオがあります。
オペレーターの悪:
前の記事(クロスチェーンブリッジセキュリティに関する研究(2) | Nomad cross-chain bridge)は、ユーザーのトランザクションがオペレーターによってPlasmaブロックにパッケージ化されると、オフチェーンデータが利用できなくなると述べています。 したがって、ユーザーがエグジットトランザクションを行う際に、古いトランザクションから引き出しを開始すると、オペレーターは最新のトランザクションの1つでチャレンジすることができ、チャレンジは成功します。 同時に、Plasmaで使用されているPoSチェックポイントメカニズムにより、オペレーターがバリデーターと共謀して悪事を働いた場合、バリデーターは状態遷移を偽造してイーサリアムに提出することさえできます。
ユーザーの悪:
ユーザーは、クロスチェーンの二重支払いと同様に、出口トランザクションを開始した後もPolygonでトークンを使い続けます。
要約すると、PolygonのPlasma MoreVpアルゴリズムは、最新のトランザクションから終了するための出口優先順位を計算するために別のアルゴリズムを使用します。 このメソッドはUTXOに似たLogTransferイベントを使用するため、ユーザーの正当なトランザクションが正しいinput1とinput2を使用している限り、ユーザーのトランザクションの前に悪意のあるトランザクションがパッケージ化されていたとしても、ユーザーのトランザクションは有効な入力からのみ発生するため、ユーザーのトランザクションを正しく処理できます。 関連する擬似コードは次のとおりです。
入金
ユーザーAliceがPlasma Bridgeを使用して、EthereumアカウントからPolygonアカウントにトークン資産を送信する例を考えてみましょう。
1.まず、ユーザーは、メインチェーン(イーサリアム)上のPolygonコントラクトのdepositManagerに転送する必要があるトークン資産をapprotect関数を通じて承認する必要があります。
2.承認されたトランザクションが確認された後、ユーザーはerc20token.deposit()関数を呼び出して、depositManager契約のdepositERC20ForUser()関数をトリガーし、ユーザーのERC20トークン資産を入金します。
注:childChainコントラクトのソースコードの分析によると、PlasmaはETH、ERC20、ERC721の3つのタイプのみをサポートしています。
撤退
ユーザーがPlasmaブリッジを使用してPolygonからEthereumに資産を引き出す場合、次の手順に従います。
また、Polygon 上の Plasma Client の withdrawStart() インターフェース実装を呼び出すこともできます。
検証に合格すると、WithdrawManager.addExitToQueue()が呼び出され、優先度の高い順にメッセージキューに挿入されます。
最後に、addExitToQueue()は_addExitToQueue()を呼び出して、NFTを返金バウチャーとして発行します。
ユーザーは 7 日間のチャレンジ期間を待機します
チャレンジ期間が終了したら、WithdrawManager.processExits() 関数を呼び出して、ユーザーにトークンを送信できます。
この関数は 2 つのステップに分かれており、まず、メッセージキュー内の引き出しトランザクションが 7 日間のチャレンジ期間を過ぎたかどうかを確認し、チャレンジ期間が過ぎた場合は、キューからトランザクションを削除します。
次に、チャレンジ期間中に返金バウチャーNFTが削除されているかどうかを判断し、削除されていない場合はNFTが破棄され、対応するアセットがユーザーに返却されます。
5_Polygon Plasma Bridge の二重支払いの脆弱性
2021年10月5日、ホワイトハットのGerhard Wagner氏は、8億5,000万ドルの二重支払い攻撃につながる可能性のあるPolygonの脆弱性を報告し、ホワイトハットはPolygonから公式に2,000,000ドルのバグバウンティを受け取りました。
上記のPlasma Bridgeの紹介では、完全なWithdrawトランザクションプロセスは次のとおりです。
- ユーザーがPolygonでDrawトランザクションを開始し、Polygonでユーザーのトークンをバーンします。
- チェックポイント間隔 (約 30 分) の後、引き出しトランザクションがチェックポイントに含まれるのを待ちます。
- バリデーターの2/3以上が署名してイーサリアムに送信し、その時点でユーザーはERC20PredicateBurnOnlyコントラクトのstartExitWithBurntTokens()を呼び出して、チェックポイントにバーントランザクションが含まれているかどうかを確認します。
- 検証に合格すると、NFT返金バウチャーが発行され、ユーザーに送信されます
- ユーザーは 7 日間のチャレンジ期間を待機します
- WithdrawManager.processExits()を呼び出してNFTを破棄し、ユーザーに返金します
注:トランザクションのリプレイ(二重支払い攻撃)を防ぐために、PolygonはNFTを払い戻しの証拠として使用し、引き出しトランザクションを一意に識別します。 しかし、NFTのID生成の欠陥により、攻撃者は、同じ有効な出金取引を用いてIDの異なる複数のNFTを生成するパラメータを構築し、これらのNFTを返金取引に利用することで、「二重支払い攻撃」を実現することができます。
ここでは、NFTの生成方法を詳しくご紹介します。
パラメータ分析によると、exitid = priorityの場合、NFTのIDはPlasma Bridgeの年齢優先度の左シフトによって生成されます。
この値は、年齢を生成するときにも使用されます。
攻撃者が最初の 16 進ビットが 1 と 3 に等しくならないように branchMaskBytes パラメーターを作成した場合、同じトランスコードされた値を取得する方法は 14*16 = 224 通りあります。
具体的な攻撃プロセスは次のとおりです。
- Polygon Plasma経由でPolygonに大量のETH/トークンを入金する
- Polygonで出金取引を開始し、7日間のチャレンジ期間を待ちます
- 出金トランザクションのbranchMaskBytesパラメータの最初のバイトを変更し(同じ有効なトランザクションを最大223回再送信できます)、出金トランザクションを繰り返し開始します
要約すると、この脆弱性は主に、リプレイを防ぐために払い戻しバウチャーを生成するNFTのIDアルゴリズム設計の問題が原因であり、その結果、同じ払い戻しトランザクションが異なるNFTを生成し、二重支払い攻撃につながる可能性があります。 エンコードされたブランチマスクの最初のバイトは常に0x00である必要があることがわかります。 修正は、エンコードされたブランチマスクの最初のバイトが0x00かどうかを確認し、それを誤ったマスクとして扱わないことです。
さて、今日の共有は終わりました、次号では、成都チェーンセキュリティセキュリティ研究チームが別のクロスチェーンプロジェクトのセキュリティ研究を紹介しますので、楽しみにしていてください。