智能合約漏洞檢測(cè)

漏洞介紹

1. 可重入漏洞(Reentrancy attack)
案例:The DAO 事件,最終損失360萬(wàn)枚ETH并導(dǎo)致以太坊硬分叉
本質(zhì):在調(diào)用取錢函數(shù)的時(shí)候會(huì)執(zhí)行fallback
回調(diào)函數(shù)(一般用于輸入日志),攻擊者利用該性質(zhì)在fallback
函數(shù)中修改邏輯,導(dǎo)致函數(shù)遞歸調(diào)用取錢函數(shù),因此造成賬戶的所有ETH被轉(zhuǎn)走
利用兩點(diǎn):程序的健壯性、fallback
函數(shù)
注:合約在以下兩種情況下會(huì)執(zhí)行
fallback
函數(shù)
當(dāng)外部賬戶或其他合約向該合約地址發(fā)送 ether 時(shí);
當(dāng)外部賬戶或其他合約調(diào)用了該合約一個(gè)不存在的函數(shù)時(shí);

4種解決方法:
聲明一個(gè)全局的控制變量,使程序的運(yùn)行受到控制(互斥鎖)

up主RuiChao_web3視頻中的代碼截圖2
完備程序的健壯性,通過(guò)調(diào)整代碼的順序防范攻擊

up主RuiChao_web3視頻中的代碼截圖3
更換
call
為transfer
,因?yàn)楹笳叩膅as費(fèi)有限制為2300,這點(diǎn)gas只能用來(lái)打印日志,而不支持多次回調(diào);call
的gas費(fèi)無(wú)限制,所以應(yīng)該根據(jù)具體需求來(lái)選擇調(diào)用call
還是transfer
實(shí)現(xiàn)轉(zhuǎn)幣

up主RuiChao_web3視頻中的代碼截圖4

使用 OpenZeppelin 官方提供的
ReentrancyGuard
修飾器來(lái)防止重入攻擊的發(fā)生

2. 數(shù)值溢出漏洞(Over and under flows)
案例:美鏈BEC代幣

在 Solidity 中 uint
默認(rèn)為 256 位無(wú)符整型,可表示范圍 [0, 2^256-1]
,在下面的示例代碼中通過(guò)做差的方式來(lái)判斷余額,如果傳入的 _amount
大于賬戶余額,則 balances[msg.sender] - _amount
會(huì)由于整數(shù)下溢而大于 0 繞過(guò)了條件判斷,最終提取大于用戶余額的 Ether,且更新后的余額可能會(huì)是一個(gè)極其大的數(shù)。
解決方案:將條件判斷改為 require(balances[msg.sender] > _amount)
,這樣就不會(huì)執(zhí)行算術(shù)操作進(jìn)行邏輯判斷,一定程度上避免了整數(shù)溢出的發(fā)生。
總之,為了防止整數(shù)溢出的發(fā)生,一方面可以在算術(shù)邏輯前后進(jìn)行驗(yàn)證,另一方面可以直接使用 OpenZeppelin 維護(hù)的一套智能合約函數(shù)庫(kù)中的
來(lái)處理算術(shù)邏輯。
3. 重放攻擊(Replay attack)
重放攻擊是指“一條鏈上的交易在另一條鏈上也往往是合法的”,所以重放攻擊通常出現(xiàn)在區(qū)塊鏈硬分叉的時(shí)候。由于硬分叉的兩條鏈,它們的地址和私鑰生產(chǎn)的算法相同,交易格式也完全相同,因此導(dǎo)致在其中一條鏈上的交易在另一條鏈上很可能是完全合法的。所以你在其中一條鏈上發(fā)起的交易,就可以到另一條鏈上去重新廣播,可能也會(huì)得到確認(rèn)。
解決方案:
最常用的方式便是完善交易格式,讓分叉點(diǎn)之前即存在的資金所關(guān)聯(lián)的交易只能在一條鏈上生效,這就要讓分叉后的鏈條在交易結(jié)構(gòu)上做出區(qū)別。對(duì)于以升級(jí)為目的的分叉而言很容易就能達(dá)到,因?yàn)橛卜植嫔?jí)將采用不同的客戶端版本,交易的前綴中通常包含有發(fā)起交易客戶端的版本信息。分叉后礦工為了避免打包舊客戶端的“非法交易”(并非惡意交易,僅僅只是版本號(hào)過(guò)低不被其他節(jié)點(diǎn)所承認(rèn)),通常會(huì)拒絕一定版本號(hào)以前的交易,保證惡意攻擊者很難在硬分叉升級(jí)時(shí)通過(guò)重放攻擊竊取資金。
對(duì)于非升級(jí)目的發(fā)起的分叉,不論是算力戰(zhàn)爭(zhēng)導(dǎo)致的項(xiàng)目分裂,還是惡意攻擊者發(fā)起的分叉攻擊,由于交易發(fā)起版本大概率是不會(huì)變化的,分叉后的鏈條無(wú)法通過(guò)版本驗(yàn)證來(lái)防止重放攻擊,需要在其他方向做出努力。常見(jiàn)的方式之一是為每一個(gè)交易附加上隨機(jī)數(shù)
Nonce
,盡管Nonce
一般被認(rèn)為是用于防止重復(fù)交易與雙花交易的,但防止重放攻擊方面,Nonce
也功不可沒(méi)。重放攻擊需要監(jiān)聽(tīng)一條鏈上的交易情況并轉(zhuǎn)發(fā)至另一分叉鏈上以竊取資金,如果在一條分叉鏈上發(fā)起的交易,其使用的隨機(jī)數(shù)已被另一條分叉鏈中的相同用戶發(fā)起的交易所使用,那么節(jié)點(diǎn)將不會(huì)廣播該交易,礦工也不會(huì)打包此可疑交易。對(duì)于普通用戶而言只需要重新設(shè)立隨機(jī)數(shù)并用私鑰簽名即可恢復(fù)交易。

4. 重排攻擊(Reordering attack)
這種攻擊是指礦工或其他方試圖通過(guò)將自己的信息插入列表(list)或映射(mapping)中來(lái)與智能合約參與者進(jìn)行“競(jìng)爭(zhēng)”,從而使攻擊者有機(jī)會(huì)將自己的信息存儲(chǔ)到合約中。

5. 短地址漏洞(Short address attack)
將參數(shù)傳遞給智能合約時(shí),參數(shù)根據(jù)
進(jìn)行編碼,可以發(fā)送比預(yù)期參數(shù)長(zhǎng)度短的編碼參數(shù)(例如,發(fā)送一個(gè)只有 38 個(gè)十六進(jìn)制字符(19 個(gè)字節(jié))而不是標(biāo)準(zhǔn)的 40 個(gè)十六進(jìn)制字符(20 個(gè)字節(jié))的地址)。在這種情況下,EVM 將在編碼參數(shù)的末尾添加零以構(gòu)成預(yù)期長(zhǎng)度。例子:
現(xiàn)在考慮一個(gè)持有大量代幣的交易所和一個(gè)希望提取其 100 個(gè)代幣的用戶。該用戶提交自己的地址0xdeaddeaddeaddeaddeaddeaddeaddeaddeaddead
和需要取的代幣數(shù)量100
,交易所將按照transfer
函數(shù)指定的順序?qū)@些參數(shù)進(jìn)行編碼;也就是 address
+tokens
。則編碼結(jié)果為:
總字節(jié)數(shù)為4(transfer函數(shù)簽名)+32(合約地址)+32(代幣數(shù)量)。
如果我們發(fā)送的地址缺少1個(gè)字節(jié)(2個(gè)十六進(jìn)制數(shù)字),假設(shè)攻擊者發(fā)送地址為0xdeaddeaddeaddeaddeaddeaddeaddeaddeadde
(缺少后兩位數(shù)字),代幣數(shù)量不變?yōu)?00,則它將被編碼為:
此時(shí)整串編碼末尾會(huì)補(bǔ)上兩個(gè)0以達(dá)到預(yù)期長(zhǎng)度4+32+32,但這時(shí)tokens將被讀取為56bc75e2d6310000000
,該值現(xiàn)在是25600 tokens,而交易所認(rèn)為用戶只是在提取100 tokens。
解決方案:在將外部應(yīng)用程序中的所有輸入?yún)?shù)發(fā)送到區(qū)塊鏈之前,應(yīng)對(duì)其長(zhǎng)度進(jìn)行驗(yàn)證。
注:短地址攻擊通常發(fā)生在接受畸形地址的地方,如交易所提幣、錢包轉(zhuǎn)賬,所以除了在編寫合約的時(shí)候需要嚴(yán)格驗(yàn)證輸入數(shù)據(jù)的正確性,而且在 Off-Chain 的業(yè)務(wù)功能上也要對(duì)用戶所輸入的地址格式進(jìn)行驗(yàn)證,防止短地址攻擊的發(fā)生。

6. 拒絕服務(wù)漏洞(Denial of Service)
此類別非常廣泛,攻擊者通過(guò)破壞合約中原有的邏輯,消耗以太坊網(wǎng)絡(luò)中的資源(如以太幣和 Gas),從而使合約在一段時(shí)間內(nèi)無(wú)法正常執(zhí)行或提供正常服務(wù)。
針對(duì)智能合約的 DoS 攻擊方式通常有 3 種:
通過(guò)Revert (可觸發(fā)回滾)發(fā)動(dòng) DoS 攻擊。當(dāng)智能合約狀態(tài)的改變由外部函數(shù)的執(zhí)行結(jié)果決定并且這個(gè)執(zhí)行一直失敗時(shí),若未對(duì)函數(shù)執(zhí)行失敗的情況進(jìn)行處理,將會(huì)使智能合約處于容易遭到 DoS 攻擊的狀態(tài);
通過(guò)以太坊區(qū)塊的 Gas 限制發(fā)動(dòng) DoS 攻擊。以太坊網(wǎng)絡(luò)中每個(gè)區(qū)塊都設(shè)定了 Gas 上限,如果交易花費(fèi)的 Gas 超過(guò)上限會(huì)導(dǎo)致交易失敗。因此,即使沒(méi)有受到惡意攻擊,智能合約的運(yùn)行也可能因?yàn)槌^(guò) Gas 限制而出現(xiàn)問(wèn)題;更嚴(yán)重的情況是,若攻擊者惡意操縱 Gas 消耗而導(dǎo)致其達(dá)到區(qū)塊上限,則會(huì)使合約的交易過(guò)程以失敗告終;
合約 Owner 賬戶發(fā)動(dòng) DoS 攻擊。很多智能合約都有 Owner 賬戶,其擁有開(kāi)啟或停止合約交易的權(quán)限,若沒(méi)有保護(hù)好 Owner 賬戶,導(dǎo)致其被攻擊者操控,很可能會(huì)使合約交易被永久凍結(jié)。

7. 條件競(jìng)爭(zhēng)(Front Running)
條件競(jìng)爭(zhēng)也叫搶跑、提前交易,就是攻擊者提前獲取到交易者的具體交易信息(或者相關(guān)信息),搶在交易者完成操作之前,通過(guò)一系列手段(通常是提高報(bào)價(jià))來(lái)?yè)屧诮灰渍咔懊嫱瓿山灰住?/p>
在以太坊中所有的 TX 都需要經(jīng)過(guò)確認(rèn)才能完全記錄到鏈上,而每一筆 TX 都需要帶有相關(guān)手續(xù)費(fèi)gasPrice
,而手續(xù)費(fèi)的多少也決定了該筆 TX 被礦工確認(rèn)的優(yōu)先級(jí),手續(xù)費(fèi)高的 TX 會(huì)被優(yōu)先得到確認(rèn),而每一筆待確認(rèn)的 TX 在廣播到網(wǎng)絡(luò)之后就可以查看具體的交易詳情,一些涉及到合約調(diào)用的詳細(xì)方法和參數(shù)可以被直接獲取到。那么這里顯然就有 Front-Running 的隱患存在了。
解決方案:對(duì)鏈上數(shù)據(jù)進(jìn)行加密

8. 訪問(wèn)控制漏洞(Access Control)
根本原因:未能明確或未仔細(xì)檢查合約中函數(shù)的訪問(wèn)權(quán)限,從而允許惡意攻擊者能進(jìn)入本不該被其訪問(wèn)的函數(shù)或變量。
主要體現(xiàn)在 2 個(gè)層面:
合約代碼層面。Solidity 智能合約函數(shù)和變量的訪問(wèn)限制有 4 種,即 public、private、external、internal。如果函數(shù)未使用這些標(biāo)識(shí)符,那么默認(rèn)情況下,智能合約函數(shù)的訪問(wèn)權(quán)限為 public,亦即該函數(shù)允許被本合約或其他合約的任何函數(shù)調(diào)用,這種情況可能導(dǎo)致該函數(shù)被攻擊者惡意調(diào)用;
合約邏輯層面。通常使用函數(shù)修飾器對(duì)函數(shù)或變量進(jìn)行約束。例如,某些關(guān)鍵函數(shù)需要使用修飾器 onlyOwner 或 onlyAdmin 來(lái)約束,若未給這些函數(shù)添加修飾器,任何人都有權(quán)利訪問(wèn)并操縱這些關(guān)鍵函數(shù),則很有可能導(dǎo)致關(guān)鍵函數(shù)被惡意攻擊者操縱,從而進(jìn)一步地破壞智能合約邏輯。


9. 異常處理漏洞
以太坊智能合約中,有 3 種情況會(huì)拋出異常:
執(zhí)行過(guò)程中的 Gas(即部署或執(zhí)行智能合約的費(fèi)用)消耗殆盡;
調(diào)用棧溢出(最大層數(shù)1024);
執(zhí)行語(yǔ)句中有 throw 命令。
然而,智能合約中的一些底層調(diào)用函數(shù)(如 send,call,delegatecall)發(fā)生異常時(shí)只返回 False,而不拋出異常。因此僅僅根據(jù)有無(wú)異常拋出就判斷合約執(zhí)行是否成功是不安全的,在調(diào)用底層函數(shù)時(shí)必須嚴(yán)格檢查返回值,并且對(duì)異常采用一致性的處理方式。

10. 區(qū)塊參數(shù)依賴漏洞
以太坊智能合約中無(wú)法直接創(chuàng)建隨機(jī)數(shù),合約開(kāi)發(fā)者往往會(huì)編寫隨機(jī)函數(shù)來(lái)產(chǎn)生隨機(jī)數(shù),一般通過(guò)區(qū)塊號(hào)(block.number)、區(qū)塊時(shí)間戳(block.timestamp)或者區(qū)塊哈希(block.blockhash)等相關(guān)的區(qū)塊參數(shù)或信息作為產(chǎn)生隨機(jī)數(shù)的種子。然而由于隨機(jī)數(shù)生成依賴的這些區(qū)塊參數(shù)可以被礦工提前獲取,這將導(dǎo)致生成的隨機(jī)數(shù)是可預(yù)測(cè)的,從而可能會(huì)被惡意攻擊者利用并產(chǎn)生對(duì)他們有利的隨機(jī)數(shù)。

漏洞檢測(cè)方法
1. 形式化驗(yàn)證法
在智能合約部署之前,對(duì)其代碼和文檔進(jìn)行形式化建模,然后通過(guò)數(shù)學(xué)的手段對(duì)代碼的安全性和功能正確性進(jìn)行嚴(yán)格的證明,可有效檢測(cè)出智能合約是否存在安全漏洞和邏輯漏洞。該方法可以有效彌補(bǔ)傳統(tǒng)的靠人工經(jīng)驗(yàn)查找代碼邏輯漏洞的缺陷。
模型檢測(cè)列舉出所有可能的狀態(tài)并逐一檢驗(yàn),基本思想是通過(guò)狀態(tài)空間搜索來(lái)確認(rèn)合約是否具有相應(yīng)的性質(zhì)。
演繹驗(yàn)證該方法基于定理證明的思想,采用邏輯公式描述系統(tǒng)及其性質(zhì),通過(guò)一些推理規(guī)則證明系統(tǒng)具有某些性質(zhì)。

缺點(diǎn):需要交互式的驗(yàn)證與判斷,因此自動(dòng)化程度較低,并且依賴人工二次核驗(yàn),導(dǎo)致其無(wú)法較好地兼容 EVM 執(zhí)行層漏洞。同時(shí),由于形式化驗(yàn)證手段依賴于嚴(yán)謹(jǐn)?shù)臄?shù)學(xué)推導(dǎo)與驗(yàn)證,它無(wú)法執(zhí)行動(dòng)態(tài)分析,并且缺少對(duì)合約中可執(zhí)行路徑的檢測(cè)與判斷,從而導(dǎo)致了較高的誤報(bào)率和漏報(bào)率。
方案:
(1) F* framework. F是一種形式化驗(yàn)證方法,通過(guò)將 EVM 字節(jié)碼的語(yǔ)義形式化并把 EVM 字節(jié)碼編譯成 Ocaml 形式,最終將智能合約源碼和字節(jié)碼轉(zhuǎn)化成函數(shù)編程語(yǔ)言 F,以便分析和驗(yàn)證合約的安全性和功能正確性,從而成功檢測(cè)以太坊智能合約漏洞.
(2) KEVM framework. KEVM 是一種形式化分析的框架,它利用 K 框架構(gòu)建了基于 EVM 字節(jié)碼棧的可執(zhí)行形式化規(guī)范,提供了 EVM 的規(guī)范、參考解釋器以及用于程序分析和驗(yàn)證的工具.
(3) Isabelle/HOL. Isabelle/HOL 是一種 EVM 字節(jié)碼級(jí)別的形式化驗(yàn)證方法,其通過(guò)將字節(jié)碼序列構(gòu)造成直線代碼塊或?qū)⒑霞s拆分成基本塊,并在此基礎(chǔ)上創(chuàng)建邏輯程序進(jìn)行推理驗(yàn)證.
(4) ZEUS. ZEUS 是一種靜態(tài)分析工具, 其基于形式化驗(yàn)證的方法能夠正確且公平地分析智能合約.ZEUS 利用抽象解釋和符號(hào)模型檢查以及約束語(yǔ)句來(lái)快速驗(yàn)證合約的安全性,支持多種智能合約漏洞的檢測(cè),例如可重入漏洞、整數(shù)溢出漏洞、異常處理漏洞等.
(5) VaaS. VaaS 是基于形式化驗(yàn)證方法的“一鍵式”智能合約安全檢測(cè)平臺(tái),它可以自動(dòng)檢測(cè)智能合約中 10 大項(xiàng) 32 小項(xiàng)的常規(guī)安全漏洞,并且能夠精準(zhǔn)定位風(fēng)險(xiǎn)代碼位置以及給出修改建議.

2. 符號(hào)執(zhí)行法
主要思想是將代碼中的變量符號(hào)化。通過(guò)符號(hào)化程序輸入、符號(hào)執(zhí)行能夠?yàn)樗械膱?zhí)行路徑維護(hù)一組約束,執(zhí)行之后,約束求解器將用于求解約束并確定導(dǎo)致該執(zhí)行的輸入,最后利用約束求解器得到新的測(cè)試輸入,檢測(cè)符號(hào)值是否可以產(chǎn)生漏洞。
符號(hào)執(zhí)行法應(yīng)用于智能合約漏洞檢測(cè)的執(zhí)行過(guò)程為:首先,將合約中的變量值符號(hào)化,然后逐條解釋執(zhí)行程序中的指令,在解釋執(zhí)行過(guò)程中更新執(zhí)行狀態(tài)、搜集路徑約束,以完成程序中所有可執(zhí)行路徑的探索并發(fā)現(xiàn)相應(yīng)的安全問(wèn)題。
缺點(diǎn):顯著地提高了漏洞分析過(guò)程中的計(jì)算資源和時(shí)間開(kāi)銷,并且無(wú)法徹底解決狀態(tài)空間爆炸與執(zhí)行路徑指數(shù)級(jí)增長(zhǎng)等問(wèn)題。另外,很多符號(hào)執(zhí)行法其實(shí)并不能做到完全自動(dòng)化,同樣需要人工協(xié)助與反饋。
方案:
(1) Oyente. Oyente 是最早的智能合約漏洞靜態(tài)檢測(cè)工具之一,其在合約控制流圖的基礎(chǔ)上利用符號(hào)執(zhí)行的方法檢測(cè)智能合約漏洞.Oyente 以智能合約字節(jié)碼和以太坊狀態(tài)作為輸入,模擬 EVM 并且遍歷合約的不同執(zhí)行路徑,其支持檢測(cè)的漏洞類型包括可重入漏洞、異常處理漏洞、交易順序依賴漏洞等.
(2) Maian. Maian 是一種基于符號(hào)分析的智能合約分析工具,它通過(guò)長(zhǎng)序列的合約調(diào)用過(guò)程來(lái)發(fā)現(xiàn)安全漏洞.區(qū)別于一般的合約分析工具,Maian 只專注于 3 種類型的合約漏洞,即資產(chǎn)無(wú)限期凍結(jié)的合約漏洞 (Greedy),易泄露資產(chǎn)給陌生賬戶的合約漏洞(Prodigal),合約可以被任何人隨意銷毀的漏洞(Suicidal).
(3) Securify. Securify 是一種用于以太坊智能合約的靜態(tài)安全分析器,具有可伸縮、完全自動(dòng)化、準(zhǔn)確率高等特性,其通過(guò)分析合約的依賴圖以及從代碼中提取精確的語(yǔ)義信息來(lái)檢查合約的合規(guī)性與安全漏洞.
(4) Mythril. Mythril 是一種智能合約靜態(tài)分析工具,其使用概念分析、污點(diǎn)分析以及控制流驗(yàn)證來(lái)檢測(cè)以太坊智能合約中常見(jiàn)的漏洞類型,包括可重入漏洞、整數(shù)溢出漏洞、異常處理漏洞等.
(5) TeEther. TeEther 是一種智能合約靜態(tài)分析工具,區(qū)別于一般的漏洞檢測(cè)工具,它考慮了智能合約漏洞自動(dòng)識(shí)別以及合約生成方法,并通過(guò)分析合約字節(jié)碼查找關(guān)鍵的執(zhí)行路徑以檢測(cè)合約的安全問(wèn)題.
(6) Sereum. Sereum 是一種專注于智能合約可重入漏洞的新穎檢測(cè)方案,該解決方案利用動(dòng)態(tài)污點(diǎn)跟蹤監(jiān)視智能合約執(zhí)行過(guò)程中的數(shù)據(jù)流,從而自動(dòng)檢測(cè)并防止?fàn)顟B(tài)不一致的情況,有效地檢測(cè)了可重入攻擊.

3. 模糊測(cè)試法
從概念上講,模糊測(cè)試從目標(biāo)應(yīng)用程序中生成大量正常和異常的測(cè)試用例,嘗試將生成的用例提供給目標(biāo)應(yīng)用程序并監(jiān)視執(zhí)行狀態(tài)中的異常結(jié)果以發(fā)現(xiàn)安全問(wèn)題。與其他技術(shù)相比,模糊測(cè)試具有良好的可擴(kuò)展性和適用性,可以在沒(méi)有源代碼的情況下執(zhí)行。
缺點(diǎn):依賴于精心設(shè)計(jì)的測(cè)試用例,對(duì)導(dǎo)致漏洞的具體語(yǔ)義代碼洞察有限,很難追蹤到存在漏洞的確切代碼位置,同時(shí)由于測(cè)試用例的隨機(jī)性,其無(wú)法達(dá)到理想的測(cè)試路徑覆蓋率,很難找出所有的潛在威脅。
方案:
(1) ContractFuzzer. ContractFuzzer 是第一個(gè)基于模糊測(cè)試的以太坊智能合約安全漏洞的動(dòng)態(tài)分析方法,其基于智能合約 ABI 規(guī)范生成模糊測(cè)試用例并定義測(cè)試方案來(lái)檢測(cè)安全漏洞.首先,ContractFuzzer 對(duì) EVM 進(jìn) 行 配 置 并 記 錄 智 能 合 約 運(yùn) 行 時(shí) 的 行 為 , 然 后 通 過(guò) 分 析 這 些 日 志 并 檢 測(cè) 漏 洞 .
(2) Regurad. Regurad 是一種專注于智能合約可重入漏洞的模糊測(cè)試分析器,其通過(guò)迭代生成隨機(jī)且多樣化的測(cè)試用例對(duì)智能合約執(zhí)行模糊測(cè)試,從而在合約的執(zhí)行過(guò)程中進(jìn)行跟蹤,進(jìn)一步地動(dòng)態(tài)識(shí)別可重入漏洞.
(3) ILF. ILF 是基于神經(jīng)網(wǎng)絡(luò)的智能合約模糊測(cè)試器,它利用符號(hào)執(zhí)行引擎生成有效的測(cè)試和調(diào)用序列,以指導(dǎo)神經(jīng)網(wǎng)絡(luò)模型的特征學(xué)習(xí),從而實(shí)現(xiàn)有效的漏洞檢測(cè).

4. 中間表示法
研究者們通過(guò)將智能合約源碼或字節(jié)碼轉(zhuǎn)換成具有高語(yǔ)義表達(dá)的中間表示(intermediary representation,簡(jiǎn)稱 IR),然后利用控制流、數(shù)據(jù)流以及污點(diǎn)分析等手段對(duì)合約的中間表示進(jìn)行分析以發(fā)現(xiàn)安全問(wèn)題。
缺點(diǎn):依賴于預(yù)定義的語(yǔ)義規(guī)則或分析列表,從而無(wú)法檢測(cè)出智能合約復(fù)雜的業(yè)務(wù)邏輯問(wèn)題且極易產(chǎn)生誤報(bào)。另外,它們無(wú)法對(duì)合約中可能存在的執(zhí)行路徑進(jìn)行遍歷。
方案:
(1) Slither. Slither 是一種以太坊智能合約的靜態(tài)分析框架,它將智能合約 Solidity 源代碼轉(zhuǎn)換為 SlithIR 的中間表示,SlithIR 使用靜態(tài)單一分配(SSA)形式和精簡(jiǎn)指令集來(lái)簡(jiǎn)化合約分析過(guò)程,同時(shí)保留了 Solidity 源代碼轉(zhuǎn)換為 EVM 字節(jié)碼時(shí)丟失的語(yǔ)義信息.
(2) Vandal. Vandal 是一種 EVM 字節(jié)碼層面的智能合約靜態(tài)分析工具,它由一個(gè)分析管道和一個(gè)反編譯器組成.該反編譯器執(zhí)行抽象解釋,以邏輯關(guān)系的形式將字節(jié)碼轉(zhuǎn)換為更高級(jí)別的中間表示(IR),然后使用新穎的邏輯驅(qū)動(dòng)方法檢測(cè)合約漏洞.
(3) Madmax. Madmax 是一種專注于以太坊智能合約 Gas 相關(guān)的漏洞分析工具,它基于 Vandal 實(shí)現(xiàn)了 控制流分析和反編譯器的程序結(jié)構(gòu)性檢測(cè)方法,該工具同樣將 EVM 字節(jié)碼反編譯成具有高語(yǔ)義信息的中間表 示,能夠高精度地檢測(cè) Gas 相關(guān)的漏洞,例如以太凍結(jié)漏洞等.
(4) Ethir. Ethir 是一種基于 EVM 字節(jié)碼層面的分析工具,它基于 Oyente 生成控制流圖(CFG),然后將 CFG 轉(zhuǎn)換為基于規(guī)則的中間表示(RBP),從而分析和推斷 EVM 字節(jié)碼的安全屬性.
(5) Smartcheck. SmartCheck 是一種可擴(kuò)展的智能合約靜態(tài)分析工具,它將智能合約 Solidity 源代碼轉(zhuǎn)換為基于 XML 的中間表示,然后利用 XPath 的模式來(lái)檢測(cè)智能合約漏洞.
(6) ContractGuard. ContractGuard 是一種面向以太坊智能合約的入侵檢測(cè)工具,它基于入侵檢測(cè)系統(tǒng) (IDS)檢測(cè)潛在攻擊引發(fā)的異??刂屏?通過(guò)有效的上下文標(biāo)記(context-tagged)無(wú)環(huán)路徑實(shí)現(xiàn)入侵檢測(cè).

5. 深度學(xué)習(xí)法
缺點(diǎn):其大多數(shù)情況下可解釋性較差,即無(wú)法像傳統(tǒng)的檢測(cè)工具一樣給出可能存在漏洞的確切位置或代碼行。
方案:
(1) SaferSC. SaferSC 是第一個(gè)基于深度學(xué)習(xí)的智能合約漏洞檢測(cè)模型,其基于 Maian 劃分的 3 類合約漏洞,實(shí)現(xiàn)了比 Maian 更高的檢測(cè)準(zhǔn)確率.此外,SaferSC 在智能合約操作碼(operation code,簡(jiǎn)稱 opcode)層面進(jìn)行分析,利用 LSTM 網(wǎng)絡(luò)構(gòu)建了以太坊操作碼序列模型,實(shí)現(xiàn)了精準(zhǔn)地智能合約漏洞檢測(cè).
(2) ReChecker. ReChecker 是第一個(gè)基于深度學(xué)習(xí)的智能合約可重入漏洞檢測(cè)方法,其通過(guò)將智能合約 Solidity 源 代 碼 轉(zhuǎn) 換 為 合 約 塊 (contract snippet) 的 形 式 , 捕 獲 了 合 約 中 基 本 的 語(yǔ) 義 信 息 和 控 制 流 依 賴 信 息.ReChecker 利用雙向長(zhǎng)短期記憶模型(Bidirectional Long Short-Term Memory,簡(jiǎn)稱 BLSTM)和注意力機(jī)制 (Attention)實(shí)現(xiàn)了以太坊智能合約可重入漏洞的自動(dòng)化檢測(cè).
(3) DR-GCN. DR-GCN 是第一個(gè)利用合約圖(contract graph)的方式來(lái)檢測(cè)智能合約漏洞,其將智能合約源代碼轉(zhuǎn)換為具有高語(yǔ)義表示的合約圖結(jié)構(gòu),并利用圖卷積神經(jīng)網(wǎng)絡(luò)構(gòu)建了安全漏洞檢測(cè)模型.DR-GCN 支 持 2 個(gè)平臺(tái)(即以太坊和維特鏈)的智能合約漏洞分析,能夠檢測(cè)可重入漏洞、時(shí)間戳依賴漏洞以及死循環(huán)漏洞.
(4) TMP. TMP 通過(guò)將智能合約中的關(guān)鍵函數(shù)和關(guān)鍵變量轉(zhuǎn)換成具有高語(yǔ)義信息的核心結(jié)點(diǎn)來(lái)構(gòu)建合約圖,關(guān)鍵的執(zhí)行方式轉(zhuǎn)換成控制流和數(shù)據(jù)流依賴的有向時(shí)序邊.TMP 在 DR-GCN 的基礎(chǔ)上考慮了合約圖中邊的時(shí)序信息,并利用時(shí)序圖神經(jīng)網(wǎng)絡(luò)實(shí)現(xiàn)了相應(yīng)的智能合約漏洞檢測(cè).
(5) ContractWard. ContractWard 從智能合約操作碼中提取 bigram 特征,利用多種機(jī)器學(xué)習(xí)算法和采樣算法進(jìn)行智能合約漏洞檢測(cè),其總共支持 6 種漏洞類型,包括可重入漏洞、整數(shù)溢出漏洞以及時(shí)間戳依賴漏洞.


目前檢測(cè)工具存在的問(wèn)題
漏洞檢測(cè)準(zhǔn)確率低
漏洞類型覆蓋率低
漏洞審計(jì)時(shí)間較長(zhǎng)
漏洞檢測(cè)完全自動(dòng)化
智能合約語(yǔ)言多樣性

改進(jìn)思路
提高形式化驗(yàn)證自動(dòng)化程度,擴(kuò)展應(yīng)用范圍
重點(diǎn):自動(dòng)化程度不高,需突破其不適應(yīng)大規(guī)模合約及多漏洞類型等技術(shù)限制
提取符號(hào)執(zhí)行重點(diǎn)路徑,縮減路徑空間
重點(diǎn):狀態(tài)空間爆炸和執(zhí)行路徑指數(shù)級(jí)增長(zhǎng),可定義易產(chǎn)生漏洞的高危指令重點(diǎn)路徑
完善測(cè)試用例,改進(jìn)模糊測(cè)試工具
重點(diǎn):改進(jìn)現(xiàn)有的測(cè)試用例生成算法,考慮結(jié)合其他檢測(cè)方法來(lái)提高檢測(cè)效率
優(yōu)化中間表現(xiàn)形式,結(jié)合動(dòng)態(tài)執(zhí)行
重點(diǎn):兼顧不同智能合約的統(tǒng)一表示形式
加強(qiáng)深度學(xué)習(xí)可解釋性,融合專家規(guī)則
重點(diǎn):改善對(duì)漏洞檢測(cè)結(jié)果的合理解釋(如標(biāo)注可能存在漏洞的確切代碼位置或代碼行)

ps:錢鵬,劉振廣,何欽銘,黃步添,田端正,王勛.智能合約安全漏洞檢測(cè)技術(shù)研究綜述.軟件學(xué)報(bào),2021.