您的智能合約中的“幻影”

本文為機器翻譯
展示原文

Solidity 編碼的智能合約是一個封裝了包括確定的功能和邏輯的方法的類。調用智能合約中不存在的函數通常會導致交易被還原。然而,Solidity 有一個稱為“後備”的功能,這意味著對合約的任何函數調用如果與匹配的函數名稱不匹配,都會被後備捕獲。雖然這提供了有用的目的,但它也帶來了危險。讓我們看看為什麼在下一節中使用後備時要小心很重要。

“後退”的歷史

在版本0.6.0發佈之前,Solidity 有以下後備語法:

 function() public payable{}

上述方法處理任何向合約發送本機代幣(ETH、 BNBETC)的傳入“調用”。它還充當合約中未指定的函數調用的接收者。也許以太坊/Solidity 團隊發現了一個問題,導致在0.6.0版本中引入了重大更改。這需要更改語法以及分離具有以下功能的兩個函數:

  • receive() external payable :當調用數據為空時觸發。其目的是處理發送到智能合約的本機代幣的接收。

  • fallback() external payable :每當沒有找到匹配的函數時就會觸發。它可以替代舊的後備方案,並且如果無意接收原生代幣,則可以將其設為免付費。

“後退”風險與案例研究

回退功能是代理模式中經常使用的強大功能。然而,在某些情況下,合約內部存在的回退可能會帶來重大風險,可能導致用戶直接經濟損失。

為了說明這一點,考慮這樣一種情況:合約 A 包含回退,而另一方的不相關合約 B 與合約 A 進行交互。當合約 B 調用合約 A 未知的函數時,會觸發回退,交易不會恢復。這會創建一個場景,如果合約 B 使用不存在的函數調用 A,則調用者以某種方式“繞過”邏輯。

雖然這種情況的發生似乎必須滿足多個條件,但此類攻擊的現實例子已經導致了嚴重的影響。探索下面兩個案例研究的具體細節,瞭解為什麼回退可能很危險以及它對安全意味著什麼。

Multiswap (anyswap) — 訪問控制漏洞

Multiswap Router 合約(V6 之前)有一些稱為“ permit ”的功能,它們在利用委託權限代表其他人橋接或交換代幣方面發揮作用。例如:

 function anySwapOutUnderlyingWithPermit(address from,address token,address to,uint amount,uint deadline,uint8 v,bytes32 r,bytes32 s,uint toChainID) external {address _underlying = AnyswapV1ERC20(token).underlying();IERC20(_underlying).permit(from, address(this), amount, deadline, v, r, s);TransferHelper.safeTransferFrom(_underlying, from, token, amount);AnyswapV1ERC20(token).depositVault(amount, from);_anySwapOut(from, token, to, amount, toChainID);}

anySwapOutUnderlyingWithPermit函數調用底層代幣的permit函數,將轉賬權限委託給合約。接下來,合約調用transferFrom來轉移資金,橋接過程將資金轉移到另一個區塊鏈。

雖然上面的代碼看起來很正常,但如果基礎代幣的合約包含回退,它就會呈現異常性質。總是有後備的代幣的一個典型例子是包裝原生代幣(WETH、WBNB、WAVAXETC)。這是一個潛在的攻擊場景:

  • 受害者 Alice已向路由器批准了 10 WETH。

  • 攻擊者 Bob使用 10 WETH 和任意vrs值執行anySwapOutUnderlyingWithPermit函數。

  • 合約執行permit功能,目的是委託授權。然而,此時的代幣是 WETH,它包含一個後備。沒有邏輯來檢查正在發生哪個授權,並且調用不會被恢復。結果,合約將 10 WETH 從 Alice 轉移到 Bob

最終,Bob 成功從 Alice 那裡竊取了 10 WETH,因為 Router 合約在調用另一個合約中的函數時缺乏強大的限制。

這次攻擊造成了巨大的經濟損失,總損失達 144 萬美元。這是一筆鉅款,對許多項目開發人員、程序員和安全審計人員來說都是一個重要的教訓。

通過閃貸任意造成另一份合約的代幣損失

該漏洞是由Code4rena的審計人員發現的。我將以簡化的方式重現易受攻擊的合約以及腳本,以演示它如何導致其他合約的財務損失。

 interface IFlashBorrower {function onFlashLoan(uint256, bytes) external;}contract VulnerableContract {IERC20 tokenX = 0x001234;function flashloan(IFlashBorrower receiver, uint256 amount, bytes calldata data) public payable {uint256 fee = amnount * 50 / 1_000;tokenX.mint(address(receiver), amount);receiver.onFlashLoan(shareAmount, data);tokenX.burn(address(receiver), amount + fee);emit Flashloaned(receiver, eusdAmount, burnShare);}}

flashloan函數的調用者可以完全控制receiver是誰。該函數內沒有驗證邏輯,它會繼續mintburn tokenX ,同時計算接收者的費用。如果接收方是具有後備功能且無法恢復的合約,則合約內的tokenX將被燒燬,造成與費用等額的損失。攻擊場景:

  • 受害者是通過GnosisSafeProxy部署的合約 A ,其中包含一個後備函數,該函數在調用不存在的函數時不會恢復。用戶在合約中存儲 100 tokenX

  • 攻擊者調用flashloan函數,並將接收者設置為合約 A

  • 在此階段,邏輯運行時不會遇到任何可能導致其恢復的約束。交易成功後,合約A被燒燬5個代幣,這是攻擊者閃電貸期間的費用。這是對用戶使用該產品時的保護的重大侵犯。

結論

通過上面的兩個案例研究,合約中的後備功能類似於一個隱藏的幽靈,可能會對合約的用戶造成影響。用戶損失的直接來源不是合約本身,而是使用該合約的第三方合約。但是,作為開發者,您必須始終承擔所有場景下用戶安全的責任。

對於包含後備功能的合約,始終檢查邏輯並在數據中存在任何無效行為時立即恢復至關重要。

當使用第三方合約時,你永遠無法預測其整個內部邏輯。始終驗證返回值,並且絕不允許用戶控制傳遞給它的關鍵數據。

Verichains團隊不斷更新他們已審核的項目和當前正在審核的項目中發現的最新漏洞,以及來自區塊鏈安全社區的信息。

感謝您閱讀 Verichains!免費訂閱以接收新帖子並支持我的工作。

關於維瑞鏈

Verichains是一家領先的區塊鏈安全公司,專門從事代碼審計、密碼分析、周邊安全和事件調查。該公司由世界一流的安全研究人員於 2017 年創立,利用安全、密碼學和核心區塊鏈技術方面的豐富專業知識,幫助調查和修復了BNB Bridge 和Ronin Bridge 等最大的加密黑客攻擊中的安全問題。如有任何疑問或疑問,請通過info@verichains.io聯繫我們

來源
免責聲明:以上內容僅為作者觀點,不代表Followin的任何立場,不構成與Followin相關的任何投資建議。
喜歡
收藏
評論