2022年5月15日午後8時20分頃(UTC)、当社の監視システムは、FEGtokenプロジェクトのFEGexPROコントラクトがハッキングされたことを検出しました。 攻撃者はETHおよびBSCメインネットの両方で一連の攻撃を仕掛け、関与した総額は約130万ドルに達しました(プロジェクトが送信したオンチェーンメッセージによる)。
@FEGtoken The paramter `path` in your FEGexPRO contract (0x818E2013dD7D9bf4547AaabF6B617c1262578bc7) should be checked in advance ! Our monitor system just reports an attack against the FEGexPRO contract, which lost its fBNB and FEG. pic.twitter.com/A4obANAMhW
— BlockSec (@BlockSecTeam) May 16, 2022
このインシデントに関する詳細情報は、このプロジェクトの公式Twitterで確認できます。 本レポートでは、このインシデントの根本原因を明らかにするために詳細を掘り下げていきます。
0x1 脆弱性分析:第一印象
脆弱なFEGexPROコントラクトは、ETHとBSCの両方にデプロイされており、コントラクトの脆弱な関数はswapToSwapです。以下の通りです。

ソーシャルメディアで指摘されているように、swapToSwap関数の最初のパラメータである***pathは、関数呼び出し元が指定できます。したがって、攻撃者はそれを悪用して任意の承認*を行うことができました(swapToSwap関数の682行目を参照)。
現時点では目新しいことは何もありません。検証されていないパラメータのもう一つのケースに過ぎません。しかし、攻撃トレースは、この攻撃が単に任意の承認に帰することはできないことを示唆しています。実際、微妙なトリックが存在し、これが興味深い点です。
0x2 攻撃分析
0x2.1 事前攻撃分析
例として、BSCでの攻撃トランザクションを取り上げ、資産fBNBを標的とした攻撃手順を以下に簡潔にまとめます。

- ステップ1:資金と偽の
pathsの準備。攻撃者はDVMから約915 BNBのフラッシュローンを借入れ、その一部を116 fBNBにスワップします。次に、攻撃者は偽のpathsとして使用される一連のコントラクトを作成します。 - ステップ2:初期資金の預け入れ。FEGexPROコントラクトに115 fBNBを預け入れることで、攻撃者は被害者コントラクトの
balances2を増やします。 - ステップ3:任意の承認の実行。攻撃者は次に
swapToSwap関数を呼び出し、最初のパラメータとして偽のpathを渡します。これにより、FEGexPROコントラクトは114 fBNBを使用するためにpathを承認します。 - ステップ4:
depositInternal関数とswapToSwap関数を呼び出して、別の承認を実行します。FEGexPROコントラクトは、114 fBNBを使用するために別のpathを承認します。
攻撃者はステップ4を繰り返し実行して、より多くの承認を行います。最終的に、攻撃者は承認された偽のpathsを使用してFEGexPROからすべてのfBNBを引き出し、一部をBNBにスワップしてフラッシュローンを返済します。
明らかに、コントラクトはpathパラメータをチェックするはずだと容易に判断できます。
しかし、この攻撃を完全に理解するには、もう1つの問題に対処する必要があります。FEGexPROコントラクトが偽のpathを承認したとしても、approve操作はユーザーのbalances2が直ちに減少するという事実に基づいています(swapToSwap関数の684行目)。つまり、承認された資金はステップ3で預け入れられた金額と正確に一致します。言い換えれば、攻撃者は自分の預け入れた資金を偽のpathに承認するだけです。その後、balances2の減少により、攻撃者は他の偽のpathsの承認を行うべきではありません。
したがって、ここに疑問が生じます。攻撃者が追加の利益を得るために他の承認を行うために、どのようなトリックが使われているのでしょうか?
0x2.2 高度な攻撃分析
この質問に答えるために、swapToSwap関数に戻りましょう。
コードを注意深く調べた結果、ここで使われているトリックは、偽のpathだけでなく、偽のswapでもあり、被害者コントラクトの残高の実際の値と記録された値との間に不整合が生じます。その結果、この不整合を利用して、depositInternal関数を呼び出すことで攻撃者の預け入れ額を回復し、承認を繰り返し行うことができます。
具体的には、depositInternal関数は、主にコントラクトのMain.balanceOfと_totalSupply2の差に基づいて、ユーザーのbalances2を変更します(depositInternal関数の651行目)。

swapToSwapに渡されるpathアドレスは攻撃者が制御する偽のpathであるため、実際には何も転送されません。その結果、Main.balanceOfの戻り値はステップ3と同じままです。_totalSupply2はswapToSwap関数で減少していることに注意してください。攻撃者が預け入れる限り、増加したbalance2は必然的に実際に預け入れられた金額よりも大きくなります。
したがって、ステップ4では、攻撃者はまずdepositInternal関数を呼び出して預け入れ額を回復し、次にswapToSwap関数を呼び出して承認と偽のswapを実行します。
攻撃者が使用する預け入れ額はほぼ0(つまり、1 / 1e18)fBNBにすぎないことに注意してください。そのため、depositInternal関数は、前述のように(次の承認のトレースで実証されているように)、攻撃者のbalances2をステップ3とほぼ同じ額に回復させます。

攻撃者はステップ4を繰り返し実行することで、収穫を拡大できます。
最後に、上記で説明した攻撃は、攻撃者が悪用した攻撃経路の1つにすぎないことに注意する価値があります。同じ攻撃トランザクションで、攻撃者は資産FEGも標的にしています。

0x3 根本原因
ここで、この攻撃の根本原因をまとめます。
- 第一に、
swapToSwap関数における検証されていないパラメータによって引き起こされた任意の承認。 - 第二に、
swapToSwap関数における偽のswapにより、被害者コントラクトの残高の実際の値と記録された値との間に不整合が生じます。これは、攻撃者の預け入れ額を回復することで、承認を繰り返し行うために使用されました。
これらを組み合わせることで、攻撃者は被害者コントラクトからすべての資金を首尾よく引き出しました。
0x4 その他の関連攻撃
本稿執筆時点では、別の攻撃者によるさらなる関連攻撃も観測されています。
ROX(https://t.co/NWvSy5faY3) is not open-sourced, but something is wrong.
— BlockSec (@BlockSecTeam) May 17, 2022
Take a look at the following transaction:https://t.co/chPxcDoFOD@Mudit__Gupta
再び、イーサリアムとBSCの両方にデプロイされたコントラクトが攻撃されました。 興味深いことに、攻撃トレースは今回議論したトレースとは異なります。被害者コントラクトはオープンソースではありませんが、攻撃者は同様の攻撃手法で同じ脆弱性を悪用したと強く疑われます。
0x5 まとめ
DeFiプロジェクトのセキュリティを確保することは容易ではありません。コード監査に加えて、コミュニティはプロジェクトのステータスを積極的に監視し、攻撃が発生する前にブロックするべきだと考えます。
BlockSecについて
BlockSecは、世界的に著名なセキュリティ専門家チームによって2021年に設立された、先駆的なブロックチェーンセキュリティ企業です。同社は、新興のWeb3世界におけるセキュリティとユーザビリティの向上に専念し、その普及を促進することを目指しています。この目的のため、BlockSecはスマートコントラクトおよびEVMチェーンのセキュリティ監査サービス、セキュリティ開発および脅威のプロアクティブなブロックのためのPhalconプラットフォーム、資金追跡および調査のためのMetaSleuthプラットフォーム、そしてWeb3ビルダーが効率的に暗号世界をサーフィンするためのMetaDock拡張機能を提供しています。
現在までに、同社はMetaMask、Uniswap Foundation、Compound、Forta、PancakeSwapなど300社を超える著名なクライアントにサービスを提供し、Matrix Partners、Vitalbridge Capital、Fenbushi Capitalなどの著名な投資家から2回の資金調達ラウンドで数千万米ドルを獲得しています。
公式ウェブサイト:https://blocksec.com/ 公式Twitterアカウント:https://twitter.com/BlockSecTeam



