SharkTeam:ERC2771 & Multicall任意地址欺騙漏洞原理分析
2023 年 12 月 8 日,OpenZeppelin 官方向社區發布了一則重要的安全警報。警報指出,在項目集成中使用 ERC-2771 標准與類 Multicall 方式時,可能存在任意地址欺騙攻擊的風險。
SharkTeam 對此事件第一時間進行了技術分析,並總結了安全防範手段,希望後續項目可以引以為戒,共築區塊鏈行業的安全防线。
一、攻擊交易分析
由於存在一系列與該漏洞相關的攻擊交易,我們選擇其中一筆攻擊交易進行分析。
攻擊者地址:
0xFDe0d1575Ed8E06FBf36256bcdfA1F359281455A
攻擊交易:
0xecdd111a60debfadc6533de30fb7f55dc5ceed01dfadd30e4a7ebdb416d2f6b6
攻擊流程:
1.首先。攻擊者(
0xFDe0d157
)先利用 5 枚 WETH 兌換了約 3, 455, 399, 346 枚 TIME。
2.隨後,攻擊者( 0xFDe0d157 )構建了惡意的 calldata 參數並調用了[Forwarder].execute 函數。
3.在調用[Forwarder].execute 函數時,惡意的 calldata 觸發了 TIME 合約的 multicall 函數。隨後,使用剩余的 calldata 觸發執行 TIME 合約的 burn 函數,銷毀池中的 TIME 代幣。
二、漏洞分析
首先,此次攻擊事件主要涉及幾個方面:ERC 2771、Multicall、經過精心構造的 calldata。我們可以從 TIME 代幣合約中找到相關的繼承:
1.ERC 2771 提供了擁有虛擬的 msg.sender 的能力,允許用戶委托第三方[Forwarder]執行交易,用來降低 gas 成本。提交交易時,msg.sender 地址會被添加到 calldata 中。
2.TIME 代幣合約繼承了
ERC2771Context
。當[Forwarder]調用合約時,_msgSender() 會檢查 calldata 數據,並將其右移,截斷最後的 20 個字節作為預期的 msg.sender。
3.Multicall 是一種將單個函數調用轉變為在同一個合約中按順序調用多個函數的方法。它接受一個用戶編碼調用的數組並對其自身合約執行。這個函數遍歷調用數組,並對每一個操作執行 delegatecall()。這允許用戶組合自己的一系列操作,並在同一筆交易中順序執行,而無需在協議中預先定義好某些操作組合。它主要目的也是為了節省 gas。
4.對於經過精心構造的 calldata,攻擊者調用了 [Forwarder].execute 函數,並傳入相關參數。
我們對 data 值進行相應的可讀格式化後得出:
攻擊者(0x FDe 0 d 157)通過對當前 calldata 的偏移操作獲得新的 data 值,並將該值傳遞給 multicall(bytes[]) 函數。新 data 的前 4 個字節是 burn(uint 256) 函數的選擇器,amount 參數為 62227259510000000000000000000。
5.在 multicall(bytes[])函數中,通過 delegatecall 調用 burn(uint 256)函數。在0x 20 這一行,
0x760dc1e043d99394a10605b2fa08f123d60faf84
地址是在構造 calldata 時一开始添加在末尾的。該地址對應
Uniswap
v2上的 TIME-ETH 流動性池,即前文提到的預期的 msg.sender。
6.剛才提到的 msg.sender 為何變成 TIME-ETH 流動性池地址?原因是一开始 msg.sender 是[Forwarder]合約地址。為了判斷是否是可信的[Forwarder],如果是可信的[Forwarder],則將 msg.sender 設置為 calldata 的最後 20 個字節。
三、安全建議
此次攻擊事件的根本原因:在 ERC-2771 中,[Forwarder]並不是專為 multicall 設計。攻擊者將_msgSender()函數中的相關參數添加到 multicall 的外部調用中,即本次事件的[Forwarder].execute 函數。在 multicall 函數中,一些函數也會附加_msgSender()中的相關參數,從而允許攻擊者欺騙_msgSender()。因此,攻擊者通過使用 multicall 調用相關函數,可以模仿任意地址的調用。最終,通過授權銷毀池子裏的 TIME 代幣。
針對此事件,可採取以下緩解和防範措施:
1.使用修復 bug 後的新版本,OpenZeppelin 新版本的 Multicall 帶有 ERC 277 1co ntext 數據的 context 後綴長度,用於標識 ERC-2771 預期的 context 後綴長度。因此,來自可信任[Forwarder]的任何 call 都將被識別並適應每個子函數 call。
以下是 bug 版本和已更新版本的對比圖:
2.禁止任何合約調用 multicall 來防止[Forwarder]使用它,以 ThirdWeb 為例,該方法與 OpenZeppelin 的解決方案相比,OpenZeppelin 仍然允許通過合約進行 multicall。以下是 ThirdWeb 的相關 bug 版本和已更新版本的對比圖。
About Us
SharkTeam 的愿景是保護Web3世界的安全。團隊由來自世界各地的經驗豐富的安全專業人士和高級研究人員組成,精通區塊鏈和智能合約底層理論。提供包括鏈上大數據分析、鏈上風險預警、智能合約審計、加密資產追討等服務,並打造了鏈上大數據分析和風險預警平臺 ChainAegis,平臺支持無限層級的深度圖分析,能有效對抗Web3世界的高級持續性威脅(Advanced Persistent Threat,APT)。已與Web3生態各領域的關鍵參與者,如 Polkadot 、Moonbeam、polygon、 Sui 、 OKX 、 imToken 、 ChainIDE 等建立長期合作關系。
官網: https://www.sharkteam.org
Twitter : https://twitter.com/sharkteamorg
鄭重聲明:本文版權歸原作者所有,轉載文章僅為傳播信息之目的,不構成任何投資建議,如有侵權行為,請第一時間聯絡我們修改或刪除,多謝。
星球日報
文章數量
7745粉絲數
0