作者:老雅痞

來源鏈接

a16z:檢測變形智能合約的工具

以太坊安全性的前提就是假設智能合約是不可變的。智能合約的代碼一旦部署在區塊鏈上就無法更改。但是在實踐中,一些智能合約可能會發生變化——即使它們已經部署。通過一些巧妙的技巧,你可以創建“變形”的變形智能合約,通過了解這種變形的原理,則可以反向檢測出它們。

變形智能合約是可變的,這意味著開發人員可以更改其中的代碼。 web3 用戶他們信任代碼,希望代碼可以保持絕對一致性的運行,所以這些可變形的智能合約給web3 用戶帶來了嚴重的風險,特別是當不良行為者擁有了編寫變形智能合約的能力時。想像一下,攻擊者使用該技術“欺騙”那些在智能合約中質押代幣的人,他們沒有意識到這是變形的。這種破壞力是巨大的,可變形的只能合約使詐騙者有能力捕食他人,並且通常會破壞對去中心化系統的全部承諾的信任。

為了分析智能合約是否包含變形屬性,我構建了一個簡單的變形合約檢測器(受Jason Carver、0age和其朋友的原創作品啟發和構建)。任何人都可以使用該工具來檢查給定的合約是否顯示出可能表明可能發生變形的危險信號。該方法並非萬無一失:僅僅因為智能合約顯示了一個標誌,並不意味著它一定是變形的;僅僅因為它沒有,並不意味著它是安全的。檢查器僅提供一個快速的初步評估:根據可能的指標,合約可能會變形。

Web3 用戶應該熟悉變形合約帶來的威脅,以便能夠留意並避免可能的攻擊。錢包和區塊鏈索引器可以通過在用戶與可能包含變形屬性的智能合約交互之前警告用戶來提供幫助。該工具旨在幫助教育人們了解這種潛在威脅……並防禦它。

檢測變形智能合約

我構建的Metamorphic Contract Detector分析了六個屬性,這些屬性可能表明智能合約是否是變形的。

是否用於部署合約的已知變形代碼?如果已知的變形字節碼——通常用Solidity 編寫的以太坊智能合約在編譯後變成的較低級別的虛擬機可讀代碼——出現在給定智能合約部署的交易中,這是一個主要的危險信號。在接下來的部分中,我們將討論一個由0age 開發的變形字節碼示例。一個重要的警告:變形字節碼可能存在無數種變體,檢測所有變體是非常困難的。但是,通過掃描眾所周知的實例,檢測器消除了那些攻擊者容易得到的僅僅複製和粘貼現有示例的結果。

智能合約代碼可以自毀嗎?要替換合約中的代碼(創建變形合約的關鍵步驟),開發人員首先需要刪除預先存在的代碼。做到這一點的唯一方法是使用SELFDESTRUCT 操作碼,該命令的作用與聽起來完全一樣——它會擦除給定合約地址的所有代碼和存儲。合約中存在自毀代碼並不能證明它是變形的;但是,它提供了一個線索,即合約有可能是變形的,無論如何,了解你所依賴的合約是不是有自我毀滅代碼是很重要的。

智能合約是否從其他地方調用代碼?如果有問題的智能合約不能直接自毀,它仍然可以通過使用DELEGATECALL 操作碼來擦除自己。此操作碼允許智能合約動態加載和執行存在於另一個智能合約中的代碼。即使智能合約不包含SELFDESTRUCT 操作碼,它也可以使用DELEGATECALL 從其他地方加載自毀代碼。雖然DELEGATECALL 功能並不能直接指示智能合約是否是變形的,但這是一個可能的線索——一個潛在的安全問題——值得注意。請注意,該指標有可能引發許多誤報。

是否有另一個合約部署了這個合約?變形合約只能由其他智能合約部署。這是因為變形合約由另一個操作碼啟用,只能由其他智能合約使用,稱為CREATE2。 (我們將在後面的部分中討論CREATE2是如何工作的以及為什麼它很重。)這個特徵是可能變形的最不顯眼的指標之一。這是一個必要但不充分的先決條件。掃描此特徵可能會引發許多誤報——但這是有價值的信息,因為它可能會引起懷疑並提供進一步審查合約的理由,特別是如果智能合約包含下面描述的操作碼。

部署者合約是否包含CREATE2 操作碼?如上所述,通過CREATE2 部署是變形的必要前提。如果部署者合約包含CREATE2 操作碼,這可能表明它使用CREATE2 來部署相關合約。如果部署者確實使用CREATE2 來部署所述合約,雖然這並不意味著合約一定是變形的,但這確實意味著它可能是變形的,謹慎行事並進一步調查可能是明智的。再次提醒您注意誤報:CREATE2有很多合法用途,包括支持“第2 層”擴展解決方案,以及更容易創建可以改進web3 的智能合約錢包用戶加入和密鑰恢復選項。

代碼變了嗎?這是最明顯的說法,但只有在變形合約已經變形後才會出現。如果智能合約的代碼哈希(一個唯一的加密標識符)與合約最初部署時的不同,那麼很可能代碼已被刪除、替換或更改。如果哈希不再匹配,則代碼的某些內容髮生了變化,並且合約可能會變形。該標誌是變形最可靠的指標,但這一條檢測對預測或先發製人沒有任何幫助,只能檢查變形是否已經發生。

除了為Metamorphic Contract Detector 構建一個簡單的命令行工具外,我還構建了一些示例智能合約來演示一個騙局的變形合約抵押場景,我將在下一節中對此進行描述。所有代碼都可以在這個GitHub 存儲庫中找到。

惡意行為者如何使用變形合約竊取人們的資金

以下是有人可能如何使用變形智能合約作為騙局的一部分。

首先是設置階段。攻擊者使用兩種工具在區塊鏈上的特定地址部署智能合約:變形字節碼和CREATE2 操作碼。 (稍後我們將擴展這兩個概念。)變形字節碼然後按照其名稱的含義進行“變形”。在這裡,它變成了一個質押合約,用戶可以在其中質押ERC-20 代幣。 (同樣,我們稍後會討論這個變形技巧的細節。)

接下來是誘餌和開關。毫無戒心的用戶將他們的代幣押在這份合約中,被賺取收益或其他一些好處的可能性所吸引。然後,攻擊者使用上一節中討論的SELFDESTRUCT 操作碼刪除此智能合約地址上的所有質押代碼和“狀態”——區塊鏈存儲或內存。 (應該注意的是,作為單獨的ERC-20 合約的一部分存在的代幣會持續存在,不受自毀合約的影響。)

最後,Rug Pull 就是一個卷包跑路的大動作。攻擊者重用在設置階段使用的相同變形字節碼來“重新部署”一個新合約。這個新合約部署到最近被自毀合約騰出的同一個地址。然而,這一次,字節碼“變形”(同樣,我們將在稍後解釋)變成一個惡意合約,可以竊取合約地址上的所有代幣。騙局完畢。

變形智能合約帶來的風險現在顯而易見。但是你可能仍然想知道,這種變形技巧實際上是如何工作的?要理解這一點,必須更深入字節碼級別地探索。

CREATE2如何開啟變形的可能性

CREATE2是2019 年2 月引入以太坊的操作碼升級,它提供了一種部署智能合約的新方法。

CREATE2 讓開發人員能夠比以前更好地控制智能合約的部署。原始的CREATE 操作碼使開發人員難以控制要部署的智能合約的目標地址。使用CREATE2,人們可以在將特定智能合約實際部署到區塊鏈之前,提前控制和了解特定智能合約的地址。這種預知——加上一些巧妙的技巧——使人們能夠創建變形的智能合約。

CREATE2如何預測未來?操作碼的計算是確定性的:只要輸入不改變,CREATE2 確定的地址就不會改變。 (即使是最小的更改也會導致部署發生在其他地方。)

更詳細地說,CREATE2 是一個將幾個元素組合併散列在一起的函數。首先,它包含部署者(或發送者)的地址:啟動智能合約,充當要創建的合約的父合約。接下來,它添加發送者提供的任意數字(或“salt”),這允許開發人員將相同的代碼部署到不同的地址(通過更改salt)並防止覆蓋現有的相同合約。最後,它使用一些智能合約初始化(“init”)字節碼的keccak256 哈希,這是變成新智能合約的種子。這種哈希組合確定了一個以太坊地址,然後將給定的字節碼部署到該地址。只要字節碼保持完全相同,CREATE2 將始終將給定的字節碼部署到區塊鏈上的相同地址。

下面是CREATE2 公式的樣子。 (注意:在下面的示例中,你會注意到另一個元素,“0xFF”。這只是CREATE2 用於防止與前面的CREATE 操作碼發生衝突的常量。)

a16z:檢測變形智能合約的工具