2022年5月15日午後8時20分頃(UTC)、当社の監視システムは、FEGtokenプロジェクトのFEGexPROコントラクトがハッキングされたことを検知しました。 攻撃者はETHとBSCのメインネットの両方で一連の攻撃を実行し、関与した総額は約130万ドルに達しました(プロジェクトによって送信されたオンチェーンのメッセージによると)。
@FEGtoken Your FEGexPRO contract (0x818E2013dD7D9bf4547AaabF6B617c1262578bc7)における`path`パラメータは事前に確認されるべきです!当社の監視システムは、FEGexPROコントラクトに対する攻撃を報告したばかりであり、fBNBとFEGを失いました。 pic.twitter.com/A4obANAMhW
— BlockSec (@BlockSecTeam) May 16, 2022
このインシデントに関する詳細は、このプロジェクトの公式Twitterで確認できます。 本レポートでは、このインシデントの根本原因を明らかにするために詳細を掘り下げます。
0x1 脆弱性分析:一見して
脆弱なFEGexPROコントラクトは、ETHとBSCの両方にデプロイされており、コントラクトの脆弱な関数はswapToSwapです。

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

- ステップ1:資金と偽の
pathsの準備。攻撃者はDVMから約915 BNBのフラッシュローンを借り、その一部を116 fBNBにスワップします。その後、攻撃者は偽のpathsとして使用される一連のコントラクトを作成します。 - ステップ2:初期資金の預け入れ。FEGexPROコントラクトに115 fBNBを預け入れることで、攻撃者は被害者コントラクトの
balances2を増やします。 - ステップ3:任意の承認の実行。攻撃者は
swapToSwap関数を呼び出し、偽のpathを最初のパラメータとして渡します。これにより、FEGexPROコントラクトはpathに114 fBNBを使用する承認を与えます。 - ステップ4:
depositInternal関数とswapToSwap関数を呼び出して、別の承認を実行します。FEGexPROコントラクトは、別のpathに114 fBNBを使用する承認を与えます。
攻撃者はステップ4を繰り返し実行して、さらに多くの承認を行います。最終的に、攻撃者は承認された偽のpathsを使用して、FEGexPROからすべてのfBNBを引き出し、一部をBNBにスワップしてフラッシュローンを返済します。
明らかに、コントラクトはpathパラメータをチェックすべきであったことが容易にわかります。
しかし、この攻撃を完全に理解するためには、もう一つの問題に対処する必要があります。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)はオープンソースではありませんが、何か問題があるようです。
— BlockSec (@BlockSecTeam) May 17, 2022
次のトランザクションを見てください: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



