?

區塊鏈智能合約漏洞檢測與自動化修復綜述

2023-03-24 13:25童俊成趙波
計算機應用 2023年3期
關鍵詞:以太調用字節

童俊成,趙波

(武漢大學 國家網絡安全學院,武漢 430072)

0 引言

在信任危機困境中,涉及第三方的交易存在安全風險或成本較高的問題。區塊鏈作為一種分散的分布式賬本,幫助人們在不可信的環境中進行安全可靠的交易,得到了迅速發展和廣泛應用。區塊鏈在市場上的潛力隨著比特幣的流行而被重視[1-2],但現在的區塊鏈已不再局限于數字貨幣,而是由于智能合約這一應用于區塊鏈2.0 上的技術而引起了廣泛關注[3]。

密碼學者Szabo[4]首次提出智能合約的概念,將它定義為一套以數字形式指定的承諾,合約參與者可以在上面執行這些承諾的協議。即智能合約是一段可以在計算機上自動執行的代碼。由于缺乏可信的執行環境,這一概念在當時并未得到廣泛地應用。如今區塊鏈技術為智能合約提供了一個可以達成共識從而整體可信的網絡環境,使智能合約真正流行起來。因此可以認為智能合約與區塊鏈平臺相互促進,將受到學術界與工業界越來越多的重視。

隨著智能合約的快速發展,近年來針對它的漏洞的攻擊層出不窮。2016 年,去中心化自治組織(Decentralized Autonomous Organization,DAO)這一部署在以太網上的全球最大眾籌項目遭到黑客攻擊,導致超過300 萬以太幣脫離DAO 資源池,直接造成以太坊采取硬分叉策略,損害了以太坊的公平性[5]。2017 年,以太坊多重簽名錢包Parity 出現安全漏洞,導致超過15 萬以太幣被侵吞。2021 年,幣安智能鏈上的自動做市商(Automated Market Maker,AMM)合約在遷移過程中出現漏洞并遭到黑客攻擊利用,導致5 000 萬美元的資金被盜。

智能合約與傳統程序區別很大。首先,它通過交易方式發布,一旦被部署成功,將分布式地存儲到鏈上的每一個區塊內,由礦工節點運行,而在現有的區塊鏈系統中這些礦工節點無需具有可信的基礎計算環境;其次,智能合約常常通過相互調用以實現更加復雜的功能,但如果調用了不受信任的外部合約可能會引發風險和錯誤,甚至當它所依賴的其他合約內存在惡意代碼時,會導致每個外部調用都存在潛在的安全威脅;再者,在區塊鏈上智能合約可以由任意用戶發布或協同編制,而在這一過程中用戶知識和使用工具參差不齊、選擇使用的智能合約源碼的安全建議也并不齊全,還有可能存在不受控制的惡意用戶操作規程,無法保證智能合約部署上鏈后沒有安全漏洞或缺陷;最后,智能合約還具有一些傳統代碼沒有的機制,如以太坊智能合約的燃料(Gas)機制等。這些都導致區塊鏈智能合約漏洞挖掘具有難度和挑戰性。另外,區塊鏈系統具有的兩大特性也給智能合約的修復升級帶來挑戰:1)區塊鏈系統具有的不可篡改性使智能合約一經部署就難以更新升級;2)區塊鏈系統具有的透明性使普通用戶獲取區塊鏈上運行的智能合約字節碼更加容易,這就對智能合約修復工作提出了及時、快速的需求,因為僅挖掘、發現漏洞而不升級合約則攻擊者更有可能利用漏洞對區塊鏈平臺產生威脅。

綜上所述,智能合約的漏洞檢測與自動化修復技術的研究在區塊鏈安全領域十分必要也非常熱門,本文從智能合約漏洞基礎知識出發,重點調研了智能合約漏洞挖掘的關鍵技術方法以及自動化修復與升級方法,并探討了前沿技術與未來可能的發展方向。

1 背景知識

智能合約是一種旨在提供、驗證與執行合約的特殊應用程序,整個存儲、讀取、執行過程由區塊鏈技術保障。首先,智能合約通過交易方式發布,一旦被部署成功,與區塊鏈融為一體,分布存儲到鏈上的每一個區塊內,且區塊鏈的不可篡改性使它難以更新升級,而且存儲于區塊鏈上的智能合約字節碼公開透明,這會導致智能合約不可信。由于智能合約最常見的部署平臺是以太坊[6],當前最廣泛的智能合約漏洞挖掘工作也集中在以太坊,因此本章將重新審視它們的基本概念和執行上下文,對三個關鍵概念進行描述:賬戶、交易和以太坊虛擬機(Ethereum Virtual Machine,EVM)。

1)賬戶。

以太坊采用類似傳統銀行系統中的賬戶管理機制的賬戶模式,有兩種賬戶類型:外部賬戶(Externally Owned Account,EOA)和合約賬戶(Contract Account,CA)。它們都由一個20 Byte 的地址唯一標識,由隨機數(Nonce)、賬戶余額(Balance)、合約代碼(Bytecode)、存儲(Stored Data)組成。

EOA 由公鑰/私鑰對控制,主要用于管理以太(ETHereum,ETH),并通過發送交易與合約進行交互。而CA則由智能合約中的代碼邏輯控制,主要用于實現各種功能需求,記錄已執行的交易、余額修改等合約狀態變化,但不能發送交易。CA 不能主動與外部賬戶交互。這兩類賬戶將共同維護以太坊中包含變量狀態信息的狀態對象實體,并通過區塊鏈的共識機制實現各節點之間的一致性。

2)交易。

以太坊中的交易指由外部賬戶發送的消息簽名數據,其中包含了發送者簽名、接收者地址、賬戶余額、發送幣的數量、最大消耗的Gas 限制以及合約每步執行支付給礦工的費用。在以太坊中,CA 在智能合約被第一次發布時創建,它的創建過程通過合約創建交易形式完成。交易將廣播到區塊鏈上的每個礦機執行,并在達成一致共識后改變存儲狀態。在交易包含的信息中,Gas 機制維持以太坊生態系統正常運行的動力來源,合約中函數的計算都以Gas 進行衡量,無論是轉賬交易還是合約的創建與執行,都需要消耗Gas。在激勵與安全上,Gas 機制也發揮著關鍵作用:對礦工執行和存儲交易進行補償和激勵;防范惡意用戶發送復雜計算等拒絕服務攻擊(Denial of Service,DoS)攻擊。

3)執行環境。

以太坊智能合約由EVM 執行。EVM 由一個具有自定義指令格式的虛擬機組成,該虛擬機基于棧結構實現。在EVM 中,智能合約調用的每條指令都表示為一個字節操作碼,參數在數據堆棧上傳遞。唯一的例外是Push 指令,它將常量推送到堆棧上,這些常量被直接編碼到指令字節中。EVM 的存儲結構有堆棧、內存和存儲。堆??梢源鎯植孔兞?;內存用于存儲參數和返回值,被函數調用后釋放。堆棧和內存具有易失性,將在完成事務后清除,存儲將持久地存儲狀態變量。

2 智能合約漏洞

以太坊智能合約漏洞按照引入原因可分為Solidity、EVM 和區塊鏈三個層級,其中:Solidity 為智能合約編程語言,因此可以將DASP 10(Decentralized Application Security Project 10)列舉的除了未知類型漏洞外的主要智能合約漏洞按表1[7]進行歸類。

表1 智能合約漏洞類型與引入層級Tab.1 Smart contract vulnerability types and introduction levels

1)重入漏洞。

重入漏洞是最臭名昭著的以太坊漏洞,第一次被發現時直接導致了以太坊的硬分叉。當允許外部合約調用時,在初始執行完成之前對調用合約進行新調用時就會發生重入。對于函數而言,這意味著合約狀態可能會在執行過程中由于調用不受信任的合約或使用具有外部地址的低級函數而發生變化。DAO 項目遭到重入漏洞的攻擊過程如圖1 所示。

圖1 利用重入漏洞攻擊DAO合約Fig.1 Attacking DAO contract by exploiting reentrancy vulnerability

攻擊者調用DAO 合約中的splitDAO(),而SplitDAO()調用withdrawRewardFor(),這個函數調用由DAO 創建的子合約中的payOut();然后,payOu(t)調用call.value()向攻擊者的智能合約發送ETH;由于call.value()將調用被調用合約中的回退函數fallback(),因此攻擊合約可以再次調用splitDAO(),從而被攻擊的DAO 合約可被重復執行如圖1 所示的步驟2)~6),直到耗盡Gas,導致超過合理數量的ETH 被取走。

2)訪問控制漏洞。

攻擊者利用不安全的可見性設置訪問合約私有值或邏輯。當合約使用已棄用的tx.origin 驗證調用者,并在代理庫或代理合約中魯莽使用處理冗長的大型授權邏輯require 以及delegatecall 時,就會出現這類漏洞。如圖2 所示,在用戶A調用合約B 的內部函數并通過該內部函數再次調用合約C的過程中,會出現tx.origin 返回原始發送交易的地址,而msg.sender 返回當前交易的發送者的情況。因此當利用tx.origin 驗證權限時,攻擊者會利用上述差異進行攻擊。

圖2 tx.origin與msg.sender調用結果差異Fig.2 Differences between calling results of tx.origin and msg.sender

3)算術漏洞。

算術漏洞也被稱為整數上溢和下溢,這并不是一類新的漏洞,但它們在智能合約中尤其危險,其中無符號整數導致的漏洞最常見,大多數開發人員習慣使用簡單的Int 類型(通常只是有符號整數)。如果發生溢出,許多看似良性的合約代碼將成為盜竊以太幣或拒絕服務的源頭。如圖3 所示:由于高位為符號位置,若合約不檢查整數上溢的函數,將導致127 加上1 得到有符號整數-128 的錯誤。

圖3 整數上溢示例圖Fig.3 Schematic diagram of integer overflow

4)拒絕服務漏洞。

與大多數分布式系統一樣,拒絕服務在以太坊中是致命的攻擊。導致拒絕服務的方式有很多,包括交易接收者的惡意行為、人為增加計算函數所需的Gas、濫用控制訪問智能合約的私有組件、利用混淆和疏忽等。在如圖4 所示的鎖倉合約調用示例中,用戶A、B、C 都可以通過發布在以太坊上的Lockdrop 合約進行鎖倉操作,成功后會生成一份屬于自己權限控制下的Lock 合約。但在Lock 合約生成中函數會進行強制判斷:屬于參與者的Lock 合約的金額必須等于參與者鎖倉時發送的金額,如果不相等,意味著Lock 失敗,此時會導致參與者的Lock 合約“癱瘓”而形成“拒絕服務”,如果攻擊持續,那么鎖倉機制將不再可用。

圖4 鎖倉合約的拒絕服務漏洞Fig.4 Denial of service vulnerability in lock contract

5)低級調用中未檢查返回值。

cal(l)、callcode()、delegatecal(l)和send()為Solidity 中的低級函數。它們在計算錯誤方面的行為與其他Solidity 函數完全不同,因為它們不會傳播并且導致當前執行的完全恢復。相反,它們將返回一個設置false 的布爾值,并且代碼將繼續運行。如果不檢查此類低級調用的返回值,可能會導致打開失敗和其他不需要的結果。在如下所示的由于調用send()而產生的該類型的漏洞合約代碼2)~4)行中:如果漏洞合約提高send()函數調用將以太發送到不接受它的智能合約,EVM 將用false 替換返回值;如果漏洞合約未檢查返回值,函數對合約狀態的更改將不會被還原,并且etherLeft 變量最終將記錄不正確的值。

6)短地址攻擊。

短地址攻擊是EVM 自身接受錯誤填充參數的副作用。攻擊者通過使用特制地址,使編碼不佳的客戶端在將參數包含在事務中之前錯誤地對它進行編碼。大量的以太幣可能會直接受到這個問題的影響。以以太坊協議ERC-20(Ethereum Request for Comments 20)為標準的代幣為例,如果調用transfer()函數給地址“0x12345678901234567890123456 7890123456700”發送2 個ETH,交易的input 數據可以分為如圖5 所示的3 個部分,但如果傳入的地址最后兩位是“00”,合約在解析參數時,會從下一個參數的高位拿到“00”來補充,導致后面的參數不足32 Byte,從而自動在尾部補上“00”,這樣則會出現只取2 個ETH,卻拿到512 個ETH 的漏洞。

圖5 短地址自動補齊機制Fig.5 Short address auto-completion mechanism

7)交易順序依賴漏洞。

交易順序依賴漏洞指一種依賴于交易執行順序而造成執行結果差異的安全漏洞。交易打包發送出去后會先存入交易池中,區塊鏈礦工節點按照規則從交易池中選取一批交易放入新生成的區塊。此時該新生成的區塊還沒有被確認為最終塊,不同節點選取的交易和交易放入的順序都不固定,因此合約執行的函數順序也不可預測。一般礦工會選擇交易費高的交易放入新區塊中,因此攻擊者可以通過提高交易費使交易在其他交易之前被寫入,進而影響合約的最終執行結果。如圖6 所示是MarketPlace 合約的兩種不同的被調用順序。MarketPlace 合約是一個股票買賣合約,聲明了price 和stock 兩個變量,以及兩個功能函數updatePrice 和buy。其中:updatePrice 用于更新price 值,只有合約所有者才能修改;buy 是用戶從合約中購買股票。按照順序1 確認交易會出現用戶使用舊的價格購買股票,而順序2 確認交易會出現用戶用新的價格購買。利用這一漏洞可能導致合約所有者將用戶賬戶余額清零的攻擊行為。

圖6 MarketPlace合約的兩種交易確認順序Fig.6 Two transaction confirmation orders for MarketPlace contract

8)時間戳依賴漏洞。

從鎖定代幣銷售到在游戲的特定時間解鎖資金,合約有時需要依賴當前時間,通常通過block.timestamp 實現事件約束。在如圖7 所示的輪盤賭游戲合約中,如果參與用戶在區塊時間戳正好能被5 整除的區塊中第一個向智能合約轉10以太,那么他將獲得之前轉入合約的所有賭注。但由于區塊由礦工生成,礦工可以預先知道下一個區塊的時間戳是否能被5 整除,從而作惡贏得所有以太。

圖7 具有時間戳依賴漏洞的輪盤賭合約Fig.7 Roulette contract with timestamp dependence vulnerability

9)錯誤隨機漏洞。

由于以太坊是一種確定性的圖靈機,因此通過區塊鏈環境中的變量生成的隨機數并不是真隨機數。在如圖8 所示的示例中,判斷獲勝合約的發布者定義了pointer 指針作為私有變量,希望通過隱藏該私有變量,讓用戶參與者無法獲取私有種子的數值。但攻擊者實際上可以通過Web3 等方法在區塊鏈上查看到這一變量值,從而利用這一漏洞贏得游戲。

圖8 具有錯誤隨機漏洞的游戲合約Fig.8 Game contract with error random vulnerability

3 智能合約漏洞檢測關鍵技術

3.1 符號執行

符號執行是一種重要的程序分析技術,它通過用抽象符號值替換程序本身未指定的信息來表示任何值從而偽執行程序,同時也發展出了靜態符號執行與動態符號執行[8]。

在靜態執行方面,Oyente[9]是第一個被提出的工具,它將智能合約的字節碼和以太坊區塊鏈的狀態作為輸入,通過符號執行可以檢測出事務排序依賴、重入、時間戳依賴和未處理的異常四個類型的漏洞。文獻[10]中針對整數漏洞提出名為Osiris 的工具。該工具通過符號執行方法,針對導致整數上溢或者整數下溢錯誤的算術指令,檢查當前的路徑條件下指令是否有可能違反邊界檢查要求;針對由Solidity 使用AND 和SIGNEXTEND 指令截斷有符號整數和無符號整數導致的錯誤,檢查這兩條指令的輸入是否大于指令的輸出;針對符號錯誤,檢查特定指令的符號限制。文獻[11]中提出了一種基于符號執行的工具DefectChecker,該工具使用堆事件和特征檢測器代替了SMT 求解器的使用,相較于基于符號執行方法的Oyente、Mythril[12]和Securify[13]這三種智能合約漏洞檢測先驅工具,速度和準確性更優。

動態符號執行也稱為混合符號執行,通過對路徑謂詞的識別生成有約束的程序輸入,從而提高準確度。文獻[14]中提出名為Manticore 的開源動態符號執行框架,該框架實現了與平臺無關的通用符號執行引擎,該引擎對底層執行模型幾乎沒有任何假設,根據狀態生命周期來操作和管理程序狀態。文獻[15]中提出名為MAIAN 的工具,該工具通過分析智能合約在以太坊中的多次調用(合約的每次運行被稱為一次調用),給定輸入的上下文,在合約代碼中執行一條執行路徑,系統地描述并檢測出三種漏洞合約:1)貪婪合約,通過無法發送ETH 來鎖定資金;2)洪泛合約,可以將ETH 泄露給從未互動過的用戶;3)自殺性合約,可以殺死合約或強制合約執行自殺指令。

盡管符號執行在智能合約漏洞檢測方法中被廣泛使用,但是將符號執行用于智能合約仍面臨著無法識別不可行路徑、無法驗證交互的合約等局限性[16],因此存在許多優化的符號執行漏洞檢測方法。例如,文獻[10]中的Osiris 工具采用污點分析方法篩選掉不能被實際利用的整數錯誤,以降低誤報率。文獻[17]中提出一種新的增量符號執行方法,該方法基于路徑探索和路徑后綴摘要之間的迭代循環。一方面,匯總探索的路徑,以更精確地識別受影響的路徑;另一方面,路徑后綴摘要將路徑探索引導到沒有增量行為的修剪路徑。文獻[18]中提出名為Annotary 的混合符號執行工具,該工具在Mythril 工具的基礎上,通過構建合約間以及交易間的控制流執行語義模型消除傳統符號在執行無法處理的不可達狀態時存在誤報的問題,并且,通過支持合約開發者聲明屬性的可驗證來實現Solidity 語言的向后兼容擴展。

3.2 形式化驗證

結合靜態分析的程序驗證方法在智能合約安全審計中也是研究的熱點。該方法基于形式化方法(Formal Method)的相關理論,通過形式化語言把合約中的概念、判斷、推理轉化成智能合約模型,可以消除自然語言的歧義性、不通用性,進而采用形式化工具對智能合約建模、分析和驗證。智能合約形式化驗證方法包括演繹驗證和模型檢測等方法。

演繹驗證主要基于定理證明(Theorem Proving)的基本思想,采用邏輯公式描述系統及它的性質,通過一些公理或推理規則來證明系統具有某些性質。

定理證明可以驗證無限狀態系統與有限狀態系統。雖然定理證明技術通常是半自動化的,需要人的參與和專業知識,但是學術界與工業界依舊開發了許多由定理證明支持的智能合約安全審計方法與工具,可按照定理證明方法所基于的語言級別分為以下三類。

1)對EVM 字節碼這一低級語言層面進行定理證明的研究工作受到了廣泛的關注:文獻[19]中將智能合約字節碼序列組織成直線型程序,然后在Isabelle/HOL 定理證明器中用一個字節碼級別的程序邏輯對EVM 形式化進行了擴展;文獻[20]中提出一種以Gas 消耗量為重點的EVM 執行抽象模型,該模型通過對EVM 調用堆棧進行度量,提供了對智能合約終止條件的通用形式化證明。

2)文獻[21]中認為中間語言(Intermediate Language,IL)有助于在驗證的直觀性和減少底層理解所需的能力之間取得平衡,因此通過Isabelle/HOL 證明器對Yul 這一以太坊的IL 進行形式化證明,并在證明過程中利用Yul 的良好可理解性來設計合約函數的初始前置/后置條件以達到精確識別合約函數的所有假設和影響的目的?;贗L 的另一項更具代表性的工作是由文獻[22]中提出的ZEUS 工具,它構建了第一個從Solidity 語言到低級虛擬機中間表示(Low Level Virtual Machine Intermediate Representation,LLVM-IR)的轉換器,并進行給定策略下的形式化證明。

3)由于并不需要程序員理解Solidity 源碼的編譯過程,并且等價性檢查對基于IL 進行形式化驗證的有效性至關重要(例如ZEUS 的大多數誤報正是由Solidity 與轉換為LLVMIR 后的語義不一致造成的),因此對Solidity 以及生成的領域特定語言(Domain Specific Language,DSL)這樣的高級語言進行形式化驗證也是研究的熱點。文獻[23]中基于形式記憶框架完成了第一個Solidity 子集的語義形式化工作。

模型檢測(Model Checking)可以根據系統的規格自動驗證具有有限狀態的系統模型。該方法的基本思想是通過狀態空間搜索來確認合約是否具有某些性質。即給定一個智能合約P和規約ψ,生成對應的合約模型M,然后證明規約公式ψ在智能合約模型M中成立,這樣就證明了智能合約P滿足規約ψ。在基于模型檢測方法的智能合約安全審計研究工作中,模型檢測方法的流行得益于傳統代碼分析領域大量成熟的框架與工具的存在,比如NuSMV 和nuXmv 等模型檢查器以及WebGME 等開源Web 框架。

文獻[24]中提出FSolidM 工具,該工具建立在WebGME之上,能夠將智能合約轉為有限狀態機,并通過鎖定、交易計數器等插件完成對重入漏洞與交易排序依賴漏洞的檢測;在此基礎上,文獻[25]中進一步設計并實現集成了nuXmv 驗證器的VeriSolid 工具,以滿足并發系統死鎖和活鎖等機制的驗證需求;文獻[26]中則基于多個智能合約交互的視角,通過引入部署圖來擴展VeriSolid 系統的操作語義;文獻[27]中提出一種由不同實體開發和控制的交互智能合約組成的系統的驗證方法,該方法使用NuSMV 模型檢測器和行為-交互-優先級(Behavior Interaction Priority,BIP)工具建模智能合約的行為及交互,從而驗證它們是否符合系統的功能要求。

上述模型檢測方法雖然已經從對單個智能合約的驗證擴展到了對智能合約交互進行驗證,但由于NuSMV 等模型檢測器輸入語言的限制,模型檢查方法很少考慮區塊鏈上智能合約執行的細節,比如Gas 機制或內存模型,這意味著對區塊鏈環境進行精確建模成為了難點。文獻[28]中考慮智能合約在執行環境中的執行行為因素,如合約的注冊、外部交易的接收等并對此進行建模;文獻[29]中通過將著色Petri網(Colored Petri Net,CPN)與EVM 字節碼的程序邏輯相結合,實現了一個更現實的智能合約執行模型。

3.3 模糊測試

模糊測試(Fuzzing)是一種流行且有效的軟件測試技術,通過向被測智能合約輸入大量意外數據,檢測異常發生情況,從而發現潛在漏洞。相較于符號執行與形式化驗證等方法的復雜設計,模糊測試具有簡單高效的特點,而且是在運行過程中測試,有助于挖掘出更深層的智能合約漏洞。

文獻[30]中設計并實現了第一個基于模糊測試的以太坊智能合約漏洞檢測工具ContractFuzzer,通過分析智能合約的應用程序二進制接口(Application Binary Interface,ABI)生成符合被測智能合約調用語法的輸入。在輸入用例生成過程中,該工具針對重入等7 個類型的智能合約漏洞按照固定大小輸入與非固定大小輸入兩類將用戶提供的輸入種子生成輸入。

后續學者在智能合約模糊測試領域的研究工作熱衷于提高模糊測試中測試用例的覆蓋率以提高漏洞檢測的精度。文獻[31]中提出一種基于屬性的智能合約測試工具Echidna,它利用了基于語法的模糊測試。Echidna 首先通過智能合約靜態分析框架編譯合約并進行分析,確定直接處理ETH 的常量和函數;然后基于得到的常量、事務與函數生成的隨機交易進行模糊測試。文獻[32]中提出名為sFuzz 的方法,該方法基于傳統工具AFL,采用反饋自適應模糊策略并考慮將區塊編號和時間戳建模為環境信息,以提高路徑覆蓋率。文獻[33]中結合深度學習在學習階段通過神經網絡對運行符號執行所獲得的交易序列進行訓練,但也增加了學習階段的開銷。文獻[34]中提出了一個用于智能合約的混合模糊測試器ConFuzzius,結合了進化模糊測試和約束求解,能執行更多的智能合約代碼并找出更多的bug。進化模糊測試用于測試智能合約的淺層邏輯,約束求解用于生成可以滿足復雜條件的輸入,從而得到更深入的測試路徑,而且ConFuzzius 使用數據依賴分析高效地生成交易序列,以找出可能存在bug 的特定的合約狀態。

另外,也有越來越多的學者致力于研究效率和覆蓋率平衡的智能合約模糊測試方法。文獻[35]中通過污點分析指導交易序列的生成,排除候選測試對象,從而實現最小化搜索空間并提高模糊測試過程效率的目的。文獻[36]中提出一種用于智能合約漏洞挖掘的灰盒模糊測試方法Harvey,它在兼顧灰盒模糊測試方法輕量級特點的同時通過基于預測輸入和基于需求驅動的模糊序列的方式以提高覆蓋率。

4 智能合約漏洞修復與升級部署方法

雖然已經有如第3 章所示的各類方法致力于檢測出智能合約的錯誤,以太坊社區也已經發布了許多安全編程建議與指南[37-39],但一旦智能合約部署在區塊鏈上,區塊鏈系統就認為它的代碼不可改變,因此需要漏洞自動修復技術以升級部署無錯誤的指南合約,否則,智能合約安全審計方法反而會增加攻擊者利用合約漏洞的可能性。

對于智能合約升級部署問題,以太坊社區已經探索了幾種設計模式來支持可升級的智能合約[40-43]。其中,最簡單的方法是將修補后的合約部署在新地址,并將原始合約的狀態遷移到該地址。但這一過程要求合約開發者訪問舊合約的所有內部狀態以及新合約中接受狀態轉移的程序,增加了開發者的工作量。為避免狀態遷移,合約修復與升級還可以由開發者使用新的合約作為數據存儲合約(也稱為永恒存儲模式)來實現,但是這會增加外部調用帶來的額外的Gas 開銷問題。一種更實用的策略是使用委托調用代理模式編寫合約。在該模式下,一個智能合約被拆分為兩個不同的合約:1)代理合約,持有所有資金和所有內部狀態,但不實現任何業務邏輯,它是所有用戶交易的接入點,具有不可變的代碼與合約地址。2)邏輯合約,包含管理合約動作的實際代碼。代理合約使用DELEGATECALL 指令將所有函數調用轉發到注冊的邏輯合約。該指令用于授予邏輯合約訪問代理合約中存儲的所有內部狀態和資金的權限。當智能合約升級時,首先需要部署一個新的邏輯合約,并在代理合約中更新相應地址;然后,代理合約將所有未來的交易轉發給修補后的邏輯合約。在這一部署升級合約的過程中不需要任何數據遷移,因為所有數據都存儲在不可變代理合約中,并且,由于合約地址保持不變,用戶對升級過程也是可見的。

由于區塊鏈系統的分布式特性,智能合約數量始終在線增長,合約升級模式又要求確保版本兼容,因此修補智能合約錯誤是一個耗時、繁瑣的過程,對自動化的智能合約字節碼重寫技術研究成為了一項重要且具有實際意義的工作。

文獻[44]中提出了智能合約字節碼修復系統SMARTSHIELD,該系統的工作流程如圖9 所示。該系統的工作流程主要包含以下2 部分:1)語義提取。首先分析每個智能合約的抽象語法樹(Abstract Syntax Tree,AST)和未修正的EVM 字節碼,以提取字節碼級語義信息。2)合約修正?;谔崛〉淖止澊a級語義信息通過控制流轉換和DataGuard插入來修正不安全的控制流和數據操作,最后,生成修正后的EVM 字節碼并向開發人員發送一份修正報告。

圖9 SMARTSHIELD工作流程Fig.9 Workflow of SMARTSHIELD

SMARTSHIELD 主要分析與修正了3 種典型的不安全代碼模式:1)狀態變量(存儲在存儲器中的變量)在外部函數調用之后被更新,該系統將所有狀態更改移至外部函數調用的前面來對它進行修正。2)在不事先檢測數據有效性的情況下,執行算術語句。該系統通過將邊界檢查插入到算術運算中對它進行修正。3)在調用外部合約中的函數或發送以太幣后不檢查返回值,該系統在外部函數調用后,插入有效性檢查來確保調用函數的返回值并進行修正。

由于SMARTSHIELD 在語義提取階段需要完整的控制流圖(Control Flow Graph,CFG)來更新跳轉目標和數據引用,使這一修復策略不能很好地擴展到更大更復雜的合約中。相較之下,文獻[45]中提出的EVMPatch 框架基于跳板(Trampoline)的重寫策略不需要精確的CFG,在重寫復雜合約時具有更好的可擴展性。EVMPatch 框架如圖10 所示,主要由以下組件組成:1)由自動分析工具和公開漏洞披露組成的漏洞檢測引擎;2)將補丁應用到合約的字節碼重寫器;3)驗證先前交易補丁的補丁測試機制;4)上傳合約補丁版本的合約部署組件。

圖10 EVMPatch框架Fig.10 Framework of EVMPatch

在字節碼重寫器中,基于Trampoline 的方法將新的EVM指令添加到空白代碼區域,從而在新合約代碼插入合約地址時,可以保留或更新智能合約的代碼地址空間中對任何代碼或數據的所有基于地址的引用空間。并且該方法考慮了EVM 在代碼地址空間中強制對代碼和數據進行分隔,突出了EVM 字節碼重寫器的特殊性,以達到更適用于智能合約字節碼生成的目的。

5 挑戰與展望

智能合約的安全問題研究吸引了學術界和產業界的共同關注。隨著區塊鏈技術與平臺的快速發展,智能合約的應用越來越廣泛,其中的漏洞挖掘與自動修復技術面臨著在線、多平臺、自動化與智能化的挑戰。

挑戰1:多區塊鏈平臺智能合約漏洞挖掘與安全增強。

隨著支持智能合約功能的區塊鏈平臺的迅速發展,智能合約在這些平臺上也暴露出一些令人矚目的漏洞,越來越多的研究開始關注這些非以太坊智能合約的漏洞挖掘工作。文獻[46]中關注最具代表性的采用委托權益證明(Delegated Proof of Stake,DPoS)共識機制的區塊鏈項目Enterprise Operation System(EOSIO),基于符號執行技術識別出EOSIO 智能合約中4 個最流行的漏洞的存在,并確定了48次擴展中的攻擊(其中27 次已被開發人員確認),這些攻擊已導致至少170 萬美元的經濟損失。文獻[47]中則通過模糊測試技術對Hyperledger Fabric 這一聯盟鏈的合約漏洞進行檢測。

上述工作的挑戰在于不同平臺的智能合約從虛擬機、合約字節碼到漏洞類型都不相同,因此現有的對以太坊智能合約的安全審計技術并不能直接應用于這些平臺,例如EOSIO虛擬機支持的浮點運算、類型轉換等指令在EVM 上不支持,并且EOSIO 智能合約還具有不開源的特點與挑戰。因此未來的研究工作中在對這些非以太坊智能合約漏洞進行檢測時需要更多地考慮這些區塊鏈平臺具有的特點。另外,由于在聯盟鏈等許可鏈場景下,區別于以太坊區塊鏈節點可以隨意加入,智能合約往往運行在“授權”的區塊鏈節點上,因此對這類智能合約進行安全增強時,一種可行的方案是采用可信計算技術來保障智能合約運行環境以及在上鏈過程中數據傳輸的安全可靠??紤]到可信計算環境的構建會損害區塊鏈的去中心化特性,現有研究僅利用可信執行環境技術以保障以太坊智能合約運行過程中的數據隱私性[48-51],但針對聯盟鏈等去中心化程度相對較低的許可鏈場景,對其智能合約的運行節點進行可信防護則很有意義與價值。

挑戰2:在線智能合約安全審計。

智能合約具有一經部署不可變的特點,區塊鏈平臺上的智能合約數量持續增加,如何高效、實時地檢測在線的智能合約近年來也吸引了學者們的關注。文獻[52]中提出了Sereum 技術,利用污點分析保護現有的、已經部署的具有可重入漏洞的智能合約以向后兼容的方式免受攻擊;而對于區塊鏈上易受攻擊的智能合約,特別是蜜罐類智能合約,文獻[53]中基于模式匹配實時恢復交易,但是并沒有透露具體的設計、實現和評估;文獻[54]中則提出了一種名為SODA 的更加兼具功能與效率的在線智能檢測框架,通過按需信息檢索以減少信息收集的開銷,并采用動態鏈接來消除進程間通信的開銷。在這些研究中,在線智能合約安全審計技術的挑戰在于對區塊鏈運行時行為的要素建模與檢測效率的平衡,并且隨著智能合約漏洞類型的增多,需要考慮方法的可擴展性。

挑戰3:智能化合約漏洞挖掘、利用與修復技術。

隨著深度學習的快速發展,越來越多的研究開始利用人工智能技術結合智能合約靜態代碼分析技術以完成合約代碼注釋[55-56]、安全審計[57-59]等工作,尤其是文獻[59]中提出基于圖神經網絡的漏洞挖掘工作,明顯提升了檢測精度。這些方法通?;谥悄芎霞s抽象語法樹以及控制流圖來進行語義知識的學習與訓練,但存在一個較為普遍的問題:有標簽的樣本數量較少?,F有的解決方法主要利用成熟的開源靜態代碼檢測器標記是否存在漏洞;但這樣的方法仍存在檢測漏洞種類有限、難以發現新類型惡意智能合約、目標泄露導致預測偏移等諸多問題。

針對這些問題與挑戰,提出如圖11 所示的在線合約智能化安全檢測與自動化修復升級框架,由虛擬機/Docker 層、異構區塊鏈架構層、可信計算層組成,結合合約代碼分析與區塊鏈情景分析兩個維度,并采用可信計算技術進行異構智能合約運行環境的安全增強,從而實現智能合約在線安全檢測與合約漏洞自動化修復升級兩大功能,達到智能合約全生命周期的安全審計與可信防護的目的。

圖11 在線合約智能化安全檢測與自動化修復升級框架Fig.11 Architecture of online contract intelligent security detection and automatic repair

該框架針對上述挑戰,解決思路具體如下:

針對挑戰1,框架的整體架構在可信計算層之上??尚庞嬎銓踊赥rustZone、SGX(Software Guard eXtension)、Keystone 等異構安全機制,可分別為許可鏈上的智能合約構建可信的運行環境,并且保障智能合約在修復升級中上鏈過程的傳輸安全;而對非許可區塊鏈上的智能合約,可為它的數據提供隱私保護。同時,框架提取異構區塊鏈下的智能合約的特征,考慮到在存儲機制、驗證機制、共識機制等區塊鏈情景上的不同,框架提取共識驗證特征、合約執行流特征、交易輸入特征與存儲結構特征,并針對不同智能合約以字節碼的形式讀取合約數據,為接下來的數據分析作準備。

針對挑戰2,框架從合約字節碼分析與區塊鏈情景分析兩個角度出發:1)對于單個智能合約,采用輕量級符號執行工具基于合約字節碼構造控制流圖,得到合約內函數調用關系等結構信息,并利用自然語言處理(Natural Language Processing,NLP)方法中表示學習技術生成字節碼指令的語義信息。2)考慮智能合約構建、存儲、執行的全生命周期,分析智能合約安全威脅機理,借助機器學習算法對區塊鏈的異常結構進行分類,再利用知識圖譜方法進一步分析智能合約之間在運行時的交互關系與方式,從而得到智能合約行為信息?;谏鲜龇治鼋Y果,進一步基于圖神經網絡進行訓練與預測,從而實現區塊鏈智能合約在線安全檢測自動化。

針對挑戰3,框架在現有基于圖神經網絡檢測工作取得的良好精度的基礎上,從智能合約字節碼、交易歷史、執行流及其他多元信息出發,分析了合約操作碼和賬戶交易特征等區塊鏈情景,有助于提升神經網絡模型泛化能力以及現有方案對未知類型漏洞智能合約的檢測能力。另外,在安全檢測功能模塊中,框架采用小樣本學習等更先進的深度學習技術進行數據增強從而解決數據不平衡的問題。

6 結語

本文介紹了智能合約漏洞挖掘與自動修復技術的研究現狀,重點介紹與分析了三類智能合約漏洞挖掘方法的研究趨勢,并調研介紹了主流的智能合約升級方案以及較前沿的自動修復技術實現框架與思路。在總結這些關鍵技術的基礎上分析了未來的三個重要的發展方向及所需解決的問題,并進一步提出一種在線智能合約智能化安全檢測與自動化修復升級框架,有助于未來研究工作應對這些挑戰。

猜你喜歡
以太調用字節
No.8 字節跳動將推出獨立出口電商APP
核電項目物項調用管理的應用研究
No.10 “字節跳動手機”要來了?
LabWindows/CVI下基于ActiveX技術的Excel調用
車易鏈:做汽車業的“以太坊”
簡談MC7字節碼
基于系統調用的惡意軟件檢測技術研究
A Study on the Contract Research Organization
百通推出入門級快速工業以太網絡交換器系列
以太互聯 高效便捷 經濟、可靠、易用的小型可編程控制器
91香蕉高清国产线观看免费-97夜夜澡人人爽人人喊a-99久久久无码国产精品9-国产亚洲日韩欧美综合