GoPlus Security:Vyperコンパイラ0.2.15バージョンの脆弱性によるCurve攻撃分析

業界速報
2023-08-07 14:41:19
コレクション
未来のブロックチェーンのセキュリティは、コンパイラと開発者の共同努力だけでなく、静的分析や動的ファズなどの先進的なツールのサポートと推進にも依存する必要があります。

著者:GoPlus Security

背景

最近、Vyper 0.2.15 バージョンで書かれた安定プール(alETH/msETH/pETH)が再入攻撃を受けました。これは、このバージョンのコンパイラの実装エラーによる再入ロックの故障問題が原因です。この脆弱性により、約5000万ドルの損失が発生しました。本記事では、この脆弱性の根本原因と攻撃原理を分析します。また、同様の事件が再発しないようにするための最適化提案も提供します。

根因分析

脆弱性の根源は、コンパイラによる@nonreentrant(\<str>)修飾子の意味の誤った実装にあります。

正しい意味の説明

@nonreentrant(\<str>)は関数の再入を制限するためのもので、その意味はマルチスレッドにおけるミューテックスに似ています:

単一関数修飾:関数がこの修飾子で修飾されると、その複数の呼び出しは同時に実行できません。

複数関数修飾:複数の関数がこの修飾子を使用し、再入制限キーが同じ(文字列値が同じ)場合、それらの複数の呼び出しも同時に実行できません。

正しい実装は、各再入制限キーに対してブール値を設定することです。0は関数が実行中であることを示し、1は関数が実行されていないことを示します。複数の関数はこの変数に基づいて同期します(キーを取得する際は-1、解放する際は+1、キーを取得しようとする際は値が1であるかを確認する必要があります)。

実際の意味の実装

Vyperコンパイラ0.2.15バージョンおよびそれ以前では、この意味の実装が誤っていました。誤ったコードは以下の通りです。

分析 コード内のstorage_slotは、上記で言及した同期変数に対応しています。誤りはその値域にあります。この変数は最初は0で、インタプリタが関数宣言内の@nonreentrantに到達するたびに同期変数を+1します。これは重複しています。コードが上記の複数関数修飾の状況を満たすと、インタプリタが複数の関数を処理するため、同期変数の値域はもはやブール値を満たさず、正しい意味に合致しません(つまり、ロックが無効になることがあります)。実際、コード内のTODOコメントは開発者の懸念を反映しています。

修正 パッチでは、そのキーがすでに作成されているかどうかを確認し、そうであれば+1しないようにしました。

結果 これらのコントラクトは、この修飾子の実際の実装が期待と異なるために攻撃を受けました。これらのコントラクトは理論的には正しいものでした。例えば、次に紹介するケースがあります。

コントラクト攻撃ケース

上記で言及した複数関数修飾のコントラクトは、すべて攻撃を受ける可能性があります。例えば、攻撃を受けたコントラクトは、5つの関数が同じキー@nonreentrant("lock")で修飾されているため、相互に再入可能です。

  • add_liquidity
  • remove_liquidity
  • exchange
  • removeliquidityimbalance
  • removeliquidityone_coin

ハッカーの攻撃は最初の2つの関数を利用しました。これらはそれぞれ流動性プールに資産を追加および削除するために使用され、流動性提供者はそこから取引手数料やその他の報酬を得ることができます。攻撃のプロセスは一般的な再入攻撃に似ています:

  • 最初の呼び出しでadd_liquidityに資産を追加します。
  • remove_liquidityを呼び出してこれらの資産を削除します。

この時、removeliquidityは外部呼び出しを通じて、ハッカーにethを返します。この時、ハッカーはfallback関数内でaddliquidityを呼び出して再入を完了させます。

addliquidityに再入した後、removeliquidityはまだトークンの総量total_supplyを減少させていないため、ハッカーが鋳造したトークンの数量を計算する際に、本来の数量を超えてしまいます。

remove_liquidity()

add_liquidity()

解決策と今後の発展

この事故に対して、今後のWeb3セキュリティ開発ソリューションについていくつかの考えがあります:

1. プロトコル開発者の責任と敏感性

プロトコル開発者は、コアサプライチェーンの更新とセキュリティ問題に積極的に注意を払い、関連情報をタイムリーに取得し、基盤実装への理解を深める必要があります。

2. DevSecOpsの導入

コントラクト開発プロセスにおいて、静的分析や動的Fuzzなどのセキュリティテストと検証ツールをより良く導入し、SDLC(ソフトウェア開発ライフサイクル)に組み込むことで、問題をより早く露呈させ、解決できるようにします。

3. ソフトウェア構成分析(SCA)ツールの導入

Vyperの脆弱性が明らかになった後、実際に攻撃を受けたプロトコルチームには約半日から1日の時間があり、補救措置を講じることができましたが、残念ながら最終的には盗まれた資産を救うことができませんでした。このようなサプライチェーンの問題に対しては、完璧なサプライチェーン管理プラットフォームを導入すべきです。つまり、Web2でよく言われる製品リポジトリ管理のように、サプライチェーンに問題が発生した際に迅速に警告し、アップグレードプランを提供できるようにします。

4. 取引基盤の革新

インフラストラクチャのレベルで、実行時に自動防護を行うことを考慮します。例えば、動的なセキュリティチェックや、重要な操作を実行する際に自動的に防護措置を実行することです。このレベルでの多くのトレンドを見て嬉しく思います。例えば、Uniswap V4はHookを導入することで、取引機能の拡張性を大幅に向上させ、開発者が取引の複数の段階で防護を提供して安全性を高めることができます。類似のものとしてArtelaがあり、開発者がRuntimeレベルで複数の段階の拡張を実現できるため、再入という大きな問題を自然に解決できます。具体的にはhttps://medium.com/@artela_chinese/の記事を参照してください。

結論

スマートコントラクト開発の複雑さと困難さは、脆弱性の発生をほぼ避けられないものにしています。しかし、既存のツールをより良く理解し使用し、オープンソースコミュニティ活動に継続的に関与し、インフラストラクチャを最適化・改善することで、脆弱性のリスクを低減し、システム全体の安全性と堅牢性を向上させることができます。未来のブロックチェーンセキュリティは、コンパイラと開発者の共同努力だけでなく、静的分析や動的Fuzzなどの先進的なツールの支援と推進にも依存しています。同様に、束縛を打破し、より良い基盤取引モデルやソリューションを提案できる革新者が必要であり、Web3の世界全体をより安全にすることが求められています。

ChainCatcherは、広大な読者の皆様に対し、ブロックチェーンを理性的に見るよう呼びかけ、リスク意識を向上させ、各種仮想トークンの発行や投機に注意することを提唱します。当サイト内の全てのコンテンツは市場情報や関係者の見解であり、何らかの投資助言として扱われるものではありません。万が一不適切な内容が含まれていた場合は「通報」することができます。私たちは迅速に対処いたします。
banner
チェーンキャッチャー イノベーターとともにWeb3の世界を構築する