作者:啟明星辰ADLab
公眾號:區塊鏈智能合約控制流識別的大規模實驗研究
一、 背景介紹
啟明星辰ADLab聯合電子科技大學計算機學院(網絡空間安全學院)陳廳副教授首次對以太坊區塊鏈智能合約控制流的識別進行大規模研究,研究成果《A Large-Scale Empirical Study on Control Flow Identification of Smart Contracts》于2019年發表在中國計算機學會(CCF)推薦的B類學術會議International Symposium on Empirical Software Engineering and Measurement上。該研究分析了當前6個主流的智能合約靜態分析工具,通過對以太坊區塊鏈上已部署的全部合約(約500萬)實施執行跟蹤來評估他們的靜態控制流識別能力。實驗證明,一些典型的問題會導致上述流行工具都無法識別全部的控制流(如:不完備的代碼模式)。同時,實驗發現通過執行跟蹤可以有效增強這些工具對控制流的識別。我們通過在OYENTE中引入執行跟蹤,實現了把靜態控制流分析誤報率降低百分之三十。同時,該研究獲得了最佳論文提名獎。

二、 研究方法
2.1 智能合約收集
在以太坊區塊鏈中,每個智能合約都有唯一地址(下文中如無特殊說明,都默認為以太坊區塊鏈上的智能合約)。在已知該地址的條件下,可以通過錢包的編程接口web3.eth.getCode()來獲取該合約的字節碼。通過這種方式收集智能合約存在兩大問題:
1)無法獲得所有智能合約的地址,Etherscan等開放平臺也僅僅對外開放了部分合約的地址;
2)智能合約可動態刪除,在不知道智能合約的區塊編號時,該方法就無法獲得已刪除智能合約的字節碼。
為了獲得鏈上所有智能合約的字節碼,我們對客戶端進行了插樁擴展。具體來說,通過監控evm.Create()來獲得智能合約的地址,通過監控evm.StateDB.SetCode()來獲得智能合約的字節碼。最后通過監控鏈上智能合約的歷史部署活動,從而獲得了從2015年7月30日(以太坊啟動)到2018年2月10日期間部署的約500萬智能合約的字節碼。
2.2 主流智能合約分析工具
盡管有一些工具能識別智能合約的控制流,但它們大多不開源或者無法處理字節碼形態的智能合約,而實際智能合約絕大部分都不開放源碼。最大的etherscan平臺也僅僅收錄了很小的一部分智能合約的源碼。我們的研究選擇了如下六款主流面向字節碼智能合約的分析工具:
| 工具名稱 | 特性 | 異常合約數量 |
|---|---|---|
| OYENTE | 漏洞挖掘,符號執行,路徑敏感 | 27,131 (0.5%) |
| MAIAN | 漏洞挖掘,符號執行,路徑敏感 | 115,286 (2.3%) |
| Mythril | 漏洞挖掘,符號執行,路徑敏感 | 0 |
| evmdis | 反匯編器,路徑不敏感 | 0 |
| Miasm | 反匯編器,模式識別,路徑不敏感 | 0 |
| Porosity | 反匯編器,模式識別,路徑不敏感 | 0 |
上述六款工具中,路徑敏感的工具可能比路徑不敏感的工具發現更多的控制轉移路徑,因為它們不會檢查在實際條件下的路徑可達性。其中OYENTE和MAIAN在處理某些合約時會觸發異常,我們分析發現有三類原因:惡意無效字節碼、不支持的操作和求解器異常。為了深入比較,我們修復了這三類導致異常的軟件缺陷。
2.3 智能合約控制流分析
以太坊區塊鏈智能合約包含一系列虛擬機(EVM)操作,目前支持130+的EVM操作,其中8種操作可以導致控制流轉移,具體來說:
1) 2種合約內跳轉操作,EVM指令為JUMP/JUMPI,導致在同一個合約內的控制轉移;
2) 6種合約間跳轉操作,EVM指令為CREATE/CALL/CALLCODE/DELEGATECALL/ STATICCALL/SELFDESTRUCT,導致控制轉移到另外一個地址的智能合約內。
通過對約500萬智能合約的分析,我們發現其中絕大部分都是合約內控制轉移,因此本次研究集中分析合約內的控制流轉移,JUMP和JUMPI指令的含義如下:
| 指令 | 類型 | 解釋 |
|---|---|---|
| JUMP | 無條件跳轉 | 棧頂元素為轉移目標地址 |
| JUMPI | 條件跳轉 | 棧頂元素為轉移目標地址,棧頂下一元素不為0則轉移 |
同傳統x86二進制逆向分析相比,智能合約存在一些顯著的差異。
1)目標地址都存儲在堆棧上,增加了識別難度;
2)合約類函數調用沒有傳統的call指令,統一編譯為JUMP指令,增加了函數識別難度。
我們總結了如下的6種智能合約的控制轉移模式:

顯然,模式a可以快速靜態識別,模式b必須要模擬堆棧操作,模式c則必須模擬運算,模式d則必須模擬pc,模式e則必須模擬內存讀寫,模式f則更加復雜。為了統一分析當前流行工具的智能合約控制流識別分析能力,我們定義控制轉移記錄為
1)每個工具各自發現的控制轉移記錄
2)上述工具輸出控制轉移記錄都相同的合約,
3)上述工具都發現的控制轉移記錄
三、 研究結果
我們采用上述工具對全部智能合約進行實驗,對每個工具發現的控制轉移記錄數量進行了統計,如下圖所示。其中,MAIAN工具發現的數量最少。通過分析MAIAN的源碼發現根源是其一旦發現漏洞就會停止,導致很多路徑未被分析。進一步分析該工具發現,是因為其只針對三種類型智能合約漏洞的挖掘。OYENTE比Mythril能發現更多漏洞,分析工具源碼發現它們都是基于符號執行,但是前者支持更深層次的代碼路徑。Mythril/ evmdis發現的路徑數量都比Porosity少,因為前兩者都是遞歸式的反匯編處理。發現1:由于采用的技術或者配置不同,所以當前主流工具識別的智能合約控制流數量差別較大;線性反匯編比遞歸反匯編能識別更多控制流,因為遞歸分析在識別到非法轉移目標時就停止工作。

針對基于符號執行的三個分析工具(OYENTE/ MAIAN/ Mythril),我們采用這些工具統計每個智能合約的JUMP數量和發現的控制轉移記錄平均數量如下圖所示。實驗發現,JUMP數量200以下時,控制轉移記錄數量跟JUMP數量保持線性關系。JUMP數量能夠表示智能合約的復雜度,顯然隨著合約復雜度上升,合約的控制轉移數量也就更多。但是這個線性關系在JUMP數量超過200時就不再保持,進一步分析發現這是因為這些工具都設置了不同的符號執行結束條件。我們對另外三個反匯編器(evmdis/ Miasm/ Porosity)進行實驗,同樣發現了相似的結論,在JUMP數量300以下同樣保持良好的線性關系。進一步分析發現,這三個工具在分析結束條件上同樣也存在較大差異。發現2:不同分析工具在分析復雜智能合約控制流時能力差異較大,典型原因有路徑爆炸、提前結束條件和不完備的代碼模式。

為了分析智能合約的復雜性變化,我們跟蹤了從以太坊區塊鏈啟動以來每周新建合約的字節平均數量和JUMP操作平均數量如下圖所示,發現智能合約的體積和復雜度都在持續增長。這顯然對智能合約分析工具的能力提出了更高的要求。

為了研究上述工具的控制流分析差異,我們統計了在不同工具處理結果中都相同的合約的占比如下表所示。無論是符號執行工具還是反匯編工具,控制流分析輸出相同的合約都占比很小。進一步針對工具的相互比對分析如下圖所示,發現只有evmdis跟Porosity的分析能力比較接近,但也僅針對46%的智能合約才具備相似的控制流分析結果。發現3:上述的6款主流分析工具僅針對1.7%的智能合約才能識別出相同的控制流轉移。
| 類別 | 輸出相同的合約占總合約比率 | 詳情 |
|---|---|---|
| 基于符號執行的工具 | 7% | OYENTE/ MAIAN/ Mythril |
| 基于反匯編的工具 | 5% | evmdis/ Miasm/ Porosity |
| 全部工具 | 1.7% | 上述全部 |

針對上述路徑敏感性類型的三種合約分析工具(OYENTE/ MAIAN/ Mythril),我們通過實驗收集了控制流輸出相同的全部合約,然后對它們進行了復雜度分析,結果如下圖所示。顯然,隨著合約復雜度增加,三種工具分析結果相同的合約數量在減少。

針對路徑不敏感的三種工具(evmdis/ Miasm/ Porosity),我們分別計算每個合約中它們發現的控制轉移記錄并集和合集,同時計算每個合約的復雜度,然后得到如下圖的分析。顯然,針對任何一個合約,如果其復雜度越高,這三種工具發現的相同控制轉移記錄就越少。發現4:合約的復雜度越高,不同分析工具得到一致結果越困難。

為了提升合約分析工具的控制流分析能力,我們提出了基于執行trace的控制流識別增強。智能合約執行trace的一種獲取方式是通過標準編程接口 web3.debug.traceTransaction(),但該接口需要提供合約執行的交易哈希值。同時,該接口的運行效率很低,通過分析源碼發現其在獲取trace之前需要做:運行環境初始化、構建正確狀態和重放交易記錄,同時web3編程接口是RPC調用過程。因此,效率難以提升。最終,我們選擇了對以太坊區塊鏈終端進行插樁,因為該終端能執行全部的歷史合約操作。具體來說,我們對JUMP和JUMPI操作進行了插樁,最終得到了6300萬的執行trace。同時,我們也對這些trace進行了切割,因為合約的執行trace記錄會包括合約內的控制轉移和合約間的控制轉移。然后我們對上述工具識別的控制流和執行trace獲得的控制流進行了分析,發現執行trace可以提升上述工具的控制流識別能力,尤其是對于MAIAN和Miasm工具,提升能力皆超過百分之八十。即使是最優秀的控制流發現工具Porosity,提升能力也有百分之十。發現5:執行trace可以有效提升上述工具的智能合約控制流識別能力,能發現這些工具不能發現的控制轉移。

為了驗證基于執行trace的有效性,我們選擇了OYENTE工具進行增強實現和驗證,增強的具體算法如下圖所示。我們對OYENTE的源碼進行修改以嵌入該增強算法,然后對OYENTE能識別的四種合約漏洞進行了實驗,結論見下表。針對交易順序依賴、時間依賴和重入類型的漏洞,增強OYENTE能檢測更多的漏洞。針對未處理異常漏洞,增強OYENTE不能提升檢測能力。對OYENTE源碼分析發現,這是因為這類漏洞是直接用合約字節碼掃描來檢測的,與控制流分析無關。

| OYENTE | OYENTE(增強) | |
|---|---|---|
| Transaction-Ordering Dependence | 460,626 | 521,330 |
| Timestamp Dependence | 154,871 | 183,668 |
| Mishandled Exceptions | 115,731 | 115,731 |
| Reentrancy Vulnerability | 81,931 | 57,392 |
四、 研究總結
此次針對以太坊區塊鏈智能合約控制流識別的大規模深度研究,我們取得了多項新的發現。通過插樁以太坊客戶端,收集了全部的智能合約并還原了全部的執行trace。實驗證明,執行trace可以提升當前主流的智能合約分析工具的控制流識別能力,該發現將有助于以太坊用戶、開發者和研究分析人員開展更深入的智能合約研究。
本文由 Seebug Paper 發布,如需轉載請注明來源。本文地址:http://www.bjnorthway.com/1072/
暫無評論