?

基于蛻變測試的區塊鏈智能合約漏洞檢測方法

2023-11-19 06:53陳錦富王震鑫蔡賽華馮喬偉陳宇豪許容天PatrickKwakuKudjo
通信學報 2023年10期
關鍵詞:安全漏洞測試用例合約

陳錦富,王震鑫,蔡賽華,馮喬偉,陳宇豪,許容天,Patrick Kwaku Kudjo

(1.江蘇大學計算機科學與通信工程學院,江蘇 鎮江 212013;2.江蘇省工業網絡安全技術重點實驗室,江蘇 鎮江 212013;3.威斯康星國際大學學院商業計算系,阿克拉 RE 00233)

0 引言

隨著區塊鏈的發展,智能合約的使用得到了極大的普及[1]。由于不需要第三方就可以直接被調用并且自動執行交易[2-4],智能合約的影響力已經擴散到很多方面。同時,針對智能合約的攻擊造成經濟損失的風險也在逐漸提升,與傳統的分布式應用程序平臺不同的是,區塊鏈的智能合約平臺在開放的網絡中運行,任何用戶都可以參與其中。這就導致了任意存在惡意的節點都可能利用一些安全漏洞非法地從智能合約中獲利[5]。

目前,以太坊智能合約[6]安全事故發生的頻率逐年增加,每一次安全問題帶來的破壞力都是巨大的,這不僅對市場造成了毀滅性的打擊,還使用戶對智能合約的安全性產生懷疑。TheDao 事件[7-8]是以太坊歷史上最著名的安全事件,它導致了以太坊公鏈的硬分叉。

雖然已經發現了智能合約安全漏洞的多種類型[9],但是這些漏洞通常在編寫智能合約代碼時易被忽視或者在合約分析時沒有完全被檢測出來,因此仍然有大量的智能合約存在安全漏洞[10-11]。到目前為止,研究人員已經提出了多款針對智能合約的測試工具[12-13],如SmartDec 開發的分析工具SmartCheck[14],SRI 系統實驗室開發的Securify 分析工具[15],Badruddoja等[16]開發的Oyente 靜態分析工具,Feist 等[17]提出的智能合約分析工具Slither。

一般來說,區塊鏈模型由數據層、網絡層、共識層、合約層、應用層組成,共識層中封裝了網絡節點之間的共識算法以及激勵機制,在合約部署的調用過程中,數據存儲在節點中的順序與優先級均服從共識機制的算法,因此調用智能合約需要額外的支出以保證各節點之間的協同和共識。以以太坊為例,調用智能合約涉及計算資源gas 的支付,它與以太幣之間存在較復雜的換算標準,因此在動態測試中獲取測試預言時將會面臨更大的困難[18-19],這將導致獲取預期結果消耗的資源代價過大或無法獲取預期結果。

綜上,本文提出了基于蛻變測試(MT,metamorphic testing)的方法用于檢測智能合約的安全漏洞。通過分析多種類型的智能合約安全漏洞,設計相應的蛻變關系,將生成的測試用例分為源測試用例和后續測試用例,并分別在部署的智能合約中執行,進而驗證兩組測試用例執行的結果是否符合蛻變關系。

本文的主要貢獻如下。

1) 提出了一種基于蛻變測試的區塊鏈智能合約漏洞檢測方法,通過收集智能合約實例驗證測試結果是否符合蛻變關系,從而判斷智能合約是否存在相應的安全漏洞。

2) 從區塊鏈智能合約漏洞觸發原理的角度出發,提出了面向區塊鏈智能合約安全漏洞的蛻變關系設計方法,并根據此方法設計了6 種適于智能合約安全漏洞測試的蛻變關系。

1 相關工作

由于區塊鏈具有不可篡改的特性,為了在智能合約被部署前盡可能地檢測智能合約是否存在安全風險,國內外研究人員對智能合約分析工具進行了相關的研究。

由 SmartDec 開發的智能合約分析工具SmartCheck[18]通過將Solidity 源代碼直接轉換為基于XML 的中間表示,然后根據XPath 模式檢查中間表示以識別潛在的安全漏洞,這種方法缺乏準確性,因為某些錯誤不能表示為XPath 模式。例如,重入攻擊漏洞很難表示為XPath 模式,因此不會被檢測到。此外,由于Smartcheck 使用XPath 模式來檢測某些bug 的特定語法,因此即使bug 片段語法發生細微變化,也不會與XPath 模式匹配。由SRI系統實驗室開發的Securify[19]通過解析和反編譯EVM 字節碼,然后將生成的代碼轉換為語義事實,最后將事實與預定義的模式列表相匹配以檢測安全漏洞,但是Securify 無法檢測到重入、未經檢查的發送、未處理的異常,還存在TOD 誤報的問題。根據研究發現,Securify 報告的誤報是因為過度的近似執行[20]。此外,Grieco 等[21]提出使用模糊測試對智能合約安全漏洞進行檢測的方法Echidna,該方法使用靜態分析框架Slither編譯合約并對其進行預處理,處理并識別智能合約中的重要常量和函數,然后進行模糊測試。該方法需要檢測隨機交易中的違規屬性,這使對違規屬性的定義顯得非常重要。在軟件測試中,預言問題會經常伴隨著測試軟件類型的多樣化出現,有時難以對隨機的測試用例得出的結果進行判斷。因此,本文將使用蛻變測試解決在區塊鏈智能合約領域中出現的預言問題。

蛻變測試與其他智能合約檢測方法的優勢對比如表1 所示。

表1 蛻變測試與其他智能合約檢測方法的優勢對比

2 預備工作

本文所提方法主要基于區塊鏈智能合約漏洞分析和蛻變測試,下面針對相關概念和預備工作進行介紹。

2.1 蛻變測試分析以及蛻變關系的設計

針對區塊鏈軟件的測試普遍面臨預言問題。通常,在執行測試用例x之后,需要一種稱為測試預言的系統機制來檢查執行結果。如果執行結果與預期結果不一致,說明x是導致失敗的測試用例;否則,說明x不是導致失敗的測試用例。然而,在許多現實測試中,測試預言可能不存在,或者它可能存在但資源限制使其無法使用。當預言問題發生時,許多可靠測試集問題策略的適用性和有效性都會變得有限。

目前,蛻變測試被廣泛應用于多個場景,具有代表性的是將蛻變測試應用于機器學習分類器[22]。在Weka3.5.7版本上進行了測試,以k-最近鄰(KNN,k-nearest neighbor)和樸素貝葉斯分類器(NBC,naive Bayesian classifier)的實現為例。通過改變算法的實現來注入漏洞,然后使用交叉驗證和蛻變測試方法來檢測漏洞。實驗證明,一些錯誤很難通過交叉驗證檢測到,但可以通過蛻變測試檢測到。

蛻變測試的核心元素是一組蛻變關系(MR,metamorphic relation)[23],它是與多個輸入及其預期輸出相關的目標函數或算法的必要屬性。在實現蛻變測試時,首先生成一些程序輸入(稱為源輸入)作為原始測試用例,在此基礎上使用蛻變關系生成新的輸入作為后續測試用例。蛻變測試會根據相應的蛻變關系驗證源測試用例和后續測試用例的輸出。

基于上述的指導思想,在區塊鏈智能合約中構建蛻變關系需要滿足以下兩點特性。

1) 針對區塊鏈智能合約的蛻變測試中,蛻變關系是它的核心元素。

2) 蛻變關系的生成,需要確定多個輸入及其預期輸出的目標函數或算法。

針對這兩點特性,需要對待測的智能合約進行處理和分析,通過處理確定目標算法,作為構建蛻變關系的依據。

2.2 智能合約整型溢出漏洞原理

使用蛻變測試方法,通過設計蛻變關系的多樣性可以檢測多種類型的漏洞。在此之前,需要對相應類型的漏洞原理進行分析。

在區塊鏈中,整型溢出漏洞是最常見同樣也是非常嚴重的安全漏洞,它導致的經濟損失在區塊鏈領域中占比很高。

在solidity 語言中,整型變量支持的整數類型以8 bit 為步長遞增,定義的范圍為28~2256,在定義時沒有特別說明的整型變量是256 bit。如圖1 所示,一個uint8 類型變量可以存儲的數據范圍為[0,28-1]。這意味著在智能合約的使用中,通過算數操作使變量存儲的內容超過整型定義的上限或下限(變量x1在算數操作后溢出到x2的位置),那么將會導致合約執行的結果發生錯誤,對使用合約的用戶都將造成巨大損失。

圖1 智能合約中溢出漏洞的觸發原理

存在此類漏洞的智能合約通常出現在交易轉賬、代幣發行等智能合約中。根據國家區塊鏈漏洞庫中近年來收錄的有關整型溢出的漏洞案例可知,多數受到攻擊的智能合約為通過代幣發行的整型溢出漏洞造成項目增發無限量代幣,它們通常與存儲代幣的參數未進行溢出漏洞的檢查相關。

2.3 智能合約重入攻擊漏洞原理

重入攻擊是區塊鏈系統早期最著名同時也是危害性最大的攻擊方式之一[24]。近幾年來,重入攻擊對區塊鏈造成了巨大的經濟損失。在以太坊的智能合約中,可以聲明一個不帶任何參數和返回值的匿名函數,稱為fallback 函數,當對這個合約發送消息時,如果沒有找到相匹配的函數就會調用fallback 函數。如圖2 所示,攻擊者調用攻擊合約,在被攻擊合約更新攻擊者的余額之前調用fallback函數,fallback 函數再次調用取款方法,然后繼續循環上述流程,直至攻擊合約中的資源被消耗完畢或攻擊合約中的余額被完全盜取。

根據solidity 的定義,向合約發送send、transfer、call 消息時都會調用fallback 函數,不同的是send和transfer 有2 300 gas 的限制,傳遞給fallback 函數的gas 只用于日志的記錄。因此,如果增加其他操作則可能會超過gas 的限制。而call 則會把剩余的gas 都傳遞給fallback 函數,使其可能會擁有足夠的gas 進行循環調用和使用其他方法進行攻擊。

3 區塊鏈智能合約蛻變測試方法

本節將在傳統軟件的蛻變測試基礎上,結合區塊鏈智能合約的特點,與傳統蛻變測試的流程融合后設計出適合智能合約的蛻變測試框架。

3.1 區塊鏈智能合約的蛻變測試特點

區塊鏈系統中,智能合約有“公開透明”“不可篡改”的特點。隨著區塊鏈的發展,智能合約的類型更加多元,可實現的功能也更加豐富,因此帶來的安全缺陷也更加多樣。這意味著在針對智能合約的整個蛻變測試中,需要對智能合約進行完整的分析或預處理,包括智能合約每個方法實現的功能。根據智能合約的具體功能分析合約可能存在的潛在漏洞,這些依據對后續確定目標變量、設計蛻變關系都是至關重要的。因此,智能合約應在部署上鏈之前進行完備的安全漏洞測試。為了應對在區塊鏈測試中更加頻發的測試預言獲取難題,本文提出了基于蛻變測試的智能合約安全漏洞檢測方法。

3.2 區塊鏈智能合約的蛻變測試原理

由于蛻變測試中蛻變關系的特殊機制,蛻變測試擁有兩組相對應的測試用例輸入,即源測試用例和后續測試用例,通過判斷它們的輸出是否符合蛻變關系從而獲得測試判定。在智能合約測試中可以繞過測試預言的獲取階段,有效地應對了測試預言獲取的難題,從漏洞觸發角度設計蛻變關系并用于相應智能合約的蛻變測試,保證了測試的準確率。

3.3 區塊鏈智能合約的蛻變測試方法流程

為了將蛻變測試方法在區塊鏈智能合約中有效實現,本文提出了一種區塊鏈智能合約蛻變測試方法。圖3 給出該方法的實施流程,整個方法分為4個模塊:智能合約分析模塊,通過分析和預處理確定待測合約的相關變量和輸入域;蛻變關系設計模塊,根據智能合約存在的多類型漏洞觸發邏輯構建蛻變關系;測試用例生成模塊以及蛻變關系驗證模塊。

圖3 區塊鏈智能合約蛻變測試方法

為了更全面地對區塊鏈智能合約的蛻變測試的流程進行解釋,在算法1 中以偽代碼的形式對圖3中展示的流程進行進一步展示。其中,k[i]為輸入域內隨機生成的源測試用例,MR 為設計的蛻變關系,k’[i]為后續測試用例。判斷輸出的結果是否符合預先設計的蛻變關系,若不符合,則說明智能合約存在相應的安全漏洞。

算法1區塊鏈智能合約蛻變測試算法

3.4 區塊鏈智能合約的蛻變測試框架

根據3.1 節中描述的特點可知,與傳統軟件的蛻變測試相比,針對區塊鏈智能合約的蛻變測試對智能合約的分析或預處理也在整體的測試流程中占有重要的作用。因此,將蛻變測試方法融入區塊鏈智能合約中。智能合約分析、蛻變關系設計以及蛻變關系驗證3 個方面組成了整個測試流程的框架,如圖4 所示。

根據圖4 可以看出,除了智能合約分析,蛻變關系設計和蛻變關系驗證也是整個蛻變測試的核心。因此,第4 節將詳細介紹蛻變關系的設計方法和設計過程。

4 區塊鏈智能合約漏洞的蛻變關系設計

本節將詳細展示針對第3 節中介紹的區塊鏈智能合約出現的漏洞的蛻變關系應如何設計。具體來說,蛻變關系的設計涉及2 個步驟:1) 將待測的智能合約進行分析,提取可能觸發漏洞的函數及目標變量,涉及蛻變關系中測試用例輸入的變量,需要確定它們的輸入域;2) 針對待測智能合約的功能及可能出現的漏洞類,根據潛在漏洞涉及的變量與輸出之間的屬性設計蛻變關系。

4.1 整型溢出漏洞蛻變關系設計——上溢

根據整型溢出的特點,將對可能存在整型溢出漏洞的智能合約進行初步分析,使生成的源測試用例和后續測試用例的蛻變關系滿足觸發整型溢出漏洞的必要條件。圖5 為一個存在加法溢出漏洞的智能合約的部分內容,其描述了一個銀行定期儲蓄的智能合約。在合約中,針對每個用戶設置了一個mapping 用于設置定期儲蓄時間,值為uint256 類型。之后的3個函數:deposit()為存款函數,并且儲蓄時間至少為一周;increaseLockTime()為增加儲蓄時間的函數,用戶可以根據需求自行增加儲蓄時間;withdraw()為取款函數,當用戶擁有余額且當前的時間戳遲于儲蓄結束后預定的時間戳后可以將儲蓄余額取出。

圖5 存在加法溢出漏洞的智能合約的部分內容

此案例為智能合約加法溢出的實例。通過分析,合約中涉及輸入的主要參數為存款數和定期儲蓄時間,這兩類參數雖然同時影響取款操作的輸出結果,但整型溢出漏洞是否觸發主要在于儲蓄時間lockTime,由于設置定期儲蓄時間時并未使用SafeMath 進行溢出檢測,因此通過增加定期儲蓄時間,可以使儲蓄時間發生上溢,使儲蓄時間溢出,那么定期儲蓄時間將會溢出到0。以此跳過時間檢測機制取出存款。

根據此智能合約的設計邏輯,當目標變量x為定期儲蓄時間時,f(x)為取款操作執行時取出的存款,得出蛻變關系設計依據的必要屬性為

在沒有觸發加法溢出的前提下,每次在確定的輸入域中根據蛻變關系改變目標變量的輸入,相應的輸出就必然遵循該必要屬性?;诖?,可以設計蛻變關系MR1

其中,x1、x2分別表示目標變量(儲蓄時間),對應的P(x1)、P(x2)分別表示在改變了儲蓄時間后進行取款操作的結果。

MR 的公式基于已提出的一階謂詞邏輯的蛻變關系形式化模型[25],具有精確的描述形式,同時也具備較強的兼容性,MR2~MR6的蛻變關系也是基于此模型構建的。根據智能合約中的定義,確定了構建蛻變關系涉及的4 個輸入變量和一個輸出變量:定期儲蓄時間A、存款金額B、增加儲蓄時間P、取款金額M和儲蓄余額在每一次測試前后的差值S。因此,將MR1的形式化公式分解為表格形式,如表2 所示。

表2 MR1 中目標變量間的蛻變關系

在該蛻變關系中,源測試用例的輸入以隨機測試的方法隨機生成。后續測試用例生成的蛻變關系在源測試用例的基礎上倍數遞增,當儲蓄時間遞增到發生溢出時,儲蓄時間將會溢出到從0 開始,因此每次后續測試用例執行后,將執行一次取款操作。如果該操作成功執行,即取款金額與儲蓄余額的差值相等,說明檢測出了儲蓄時間的溢出,該合約存在整型溢出的漏洞。

根據此智能合約的設計,當目標變量x為定期儲蓄時間時,f(x)為取款操作后用戶的余額差值,得出蛻變關系設計依據的必要屬性為

在沒有觸發溢出漏洞的前提下,每次在確定的輸入域中根據蛻變關系改變目標變量的輸入,相應的輸出就必然遵循該必要屬性。在表2 所示的蛻變關系的基礎上,可以進一步改進對智能合約整型溢出漏洞檢測的蛻變關系MR2

其中,x1、x2分別表示目標變量(單次轉賬金額),對應的P(x1)、P(x2)分別表示目標變量的兩次不同的實際取值(轉賬操作后接收方賬戶的余額)。

在solidity 中,整型變量支持的整數類型以8 bit為步長遞增,即整型定義的范圍為28~2256,在定義時沒有特別說明的整型變量是256 bit。在蛻變測試中以28為下限,試圖在一個uint8 的整型變量中存儲數字256,則它將會溢出變成0。

將MR2的形式化公式分解為表格形式,如表3所示。

表3 MR2 中目標變量間的蛻變關系

在隨機生成的源測試用例的基礎上,每一次生成后續測試用例時依次增加28n的儲蓄時間,這種蛻變關系可以大大減少測試整型溢出漏洞時的時間復雜度。

通過上述2 種關于檢測智能合約整型溢出漏洞的蛻變關系,可以在實驗中針對測試具體的智能合約中觸發漏洞的變量進行修改,從而驗證待測合約是否存在整型溢出漏洞。

4.2 整型溢出漏洞蛻變關系設計——下溢

對于智能合約中出現的減法溢出型漏洞,通常其整型變量的賦值會超出其下限。圖6 是一個存在減法溢出漏洞的智能合約的部分內容。

圖6 存在減法溢出漏洞的智能合約的部分內容

此案例為智能合約減法溢出漏洞的實例。通過分析,合約中涉及輸入的主要參數為接收轉賬用戶的代幣存量,如果在對balances[owner]的計算中未使用SafeMath,當轉出代幣總量大于owner 賬戶余額時,balances[owner]產生減法溢出,變成一個極大值,造成代幣增發的嚴重后果。

根據此智能合約的設計,當目標變量x為單次發起轉賬交易的金額時,f(x)為轉賬操作后發送方賬戶的余額,得出蛻變關系設計依據的必要屬性為

在沒有觸發漏洞的前提下,每次在確定的輸入域中根據蛻變關系改變目標變量的輸入,相應的輸出就必然遵循該必要屬性?;诖撕?.1 節加法溢出中改進的蛻變關系設計思路,可以設計減法溢出的蛻變關系MR3

其中,x1、x2分別表示目標變量(單次轉賬金額),對應的P(x1)、P(x2)分別表示目標變量的兩次不同的實際取值(轉賬操作后發送方賬戶的余額)。

根據智能合約中的定義,確定了構建蛻變關系涉及的4 個參數:發送方賬戶A、接收方賬戶的個數B、每次給接收方賬戶轉賬的金額M、發送方賬戶余額在每一次測試前后的差值S。將MR3的形式化公式分解為表格形式,如表4 所示。

表4 MR3 中目標變量間的蛻變關系

在該蛻變關系中,為了檢測后續測試用例是否會觸發減法溢出,將給每個接收方賬戶轉賬的金額作為變量,通過增加該變量逐步增加發送方轉賬的總金額,當發送方賬戶轉賬金額的總量大于發送方本身的余額時,如果觸發減法溢出,發送方在轉賬操作后的余額將會大于轉賬操作前的余額。

4.3 整型溢出漏洞蛻變關系設計——乘法溢出

根據合約功能的設計,若在合約功能中出現乘法運算,則可能伴隨著加減法超過整型定義范圍的上下限導致乘法溢出。圖6 中智能合約中轉賬功能的設計就伴隨著乘法溢出。

在圖6 所示的合約中,發送方賬戶每次可以轉給不止一個接收方賬戶等量的金額,那么當接收方賬戶數量遞增時,發送方每次轉賬的總金額也會根據乘數數量的遞增而增加,從而發生溢出。

根據此功能設計,當目標變量x為單次發起轉賬交易的目標賬戶數時,f(x)為轉賬操作后發送方賬戶的余額,得出蛻變關系設計依據的必要屬性為

在沒有觸發漏洞的前提下,每次在確定的輸入域中根據蛻變關系改變目標變量的輸入,相應的輸出就必然遵循該必要屬性?;诖?,可以設計乘法溢出的蛻變關系MR4

其中,x1、x2表示目標變量(接收方賬戶的數量),對應的P(x1)、P(x2)分別表示目標變量的兩次不同的實際取值(轉賬操作后發送方賬戶的余額)。

將MR4的形式化公式分解為表格形式,如表5所示。

表5 MR4 中目標變量間的蛻變關系

在該蛻變關系中,為了檢測后續測試用例是否會觸發溢出,將接收方賬戶的個數作為變量,通過接收方賬戶數量自增的方式逐步增加發送方轉賬的總金額,當發送方賬戶轉賬金額的總量大于發送方本身的余額時,如果觸發溢出,發送方在轉賬操作后的余額將會大于轉賬操作前的余額,變為一個極大值。

4.4 針對智能合約重入攻擊漏洞的蛻變關系設計

根據重入攻擊漏洞的原理,將針對存在重入攻擊漏洞的智能合約進行初步分析,將源測試用例和生成的后續測試用例認為是滿足觸發重入攻擊漏洞的必要關系。和整型溢出漏洞不同的是,觸發重入攻擊漏洞需要通過重入攻擊操作而不是改變相關參數,因此測試用例需要在涉及相應的攻擊合約的基礎上生成。圖7 是一個存在重入攻擊漏洞的智能合約和攻擊者在觸發重入攻擊漏洞時調用的攻擊合約的部分內容。

圖7 存在重入攻擊漏洞的智能合約和攻擊者在觸發重入攻擊漏洞時調用的攻擊合約的部分內容

存在重入攻擊漏洞的代碼在6 行和7 行,根據1.3 節中的描述,向合約發送call 消息存在重入攻擊的風險,攻擊者會在7 行更新用戶余額之前遞歸地從合約中取款。在分析重入攻擊漏洞的原理后,針對這兩行存在重入攻擊漏洞的代碼,設計一個重入攻擊的智能合約,在后續的實驗中可以通過攻擊操作作為測試用例,檢測智能合約是否存在重入攻擊漏洞的風險。圖8 是一個發起重入攻擊的合約的部分內容。

圖8 發起重入攻擊的合約的部分內容

此案例是智能合約重入攻擊漏洞的實例。根據分析,在合約需要接收ether 時,fallback 函數必須聲明為payable,因此第4 行函數為fallback 函數??梢钥闯?,fallback 函數內再次調用了withdraw 方法,使被攻擊合約再次進行新一輪的轉賬操作,實現重入攻擊。

重入攻擊的次數和攻擊合約的gas 數量由被攻擊合約的具體余額決定,因此可能存在假陰性的問題(合約存在重入攻擊漏洞,但是gas 數量和余額的條件不滿足二次攻擊的實現,會誤以為被測合約不存在重入攻擊漏洞)。

根據此功能設計,當目標變量x為fallback 函數每次使用withdraw 取出的金額時,f(x)為使用攻擊合約調用該智能合約的地址余額,得出蛻變關系設計依據的必要屬性為

在沒有觸發漏洞的前提下,每次在確定的輸入域中根據蛻變關系改變目標變量的輸入,相應的輸出就必然遵循該必要屬性。為了在測試的基礎上減小假陰性出現的概率,針對蛻變關系進行了優化,設計蛻變關系MR5

其中,x1、x2表示目標變量(fallback 函數中每次使用withdraw 取出的金額),對應的P(x1)、P(x2)分別表示使用攻擊合約模擬重入攻擊時合約地址的余額數量。

根據智能合約中的定義,確定了構建蛻變關系涉及的4 個輸入變量和一個輸出變量:攻擊者的錢包地址A、攻擊者發動攻擊使用的合約地址B、被攻擊合約的地址P、fallback 函數中每次攻擊取出的金額M和攻擊合約中的余額S。因此,將MR5的形式化公式分解為表格形式,如表6 所示。

表6 MR5 中目標變量間的蛻變關系

在該蛻變關系中,為了準確檢測是否會觸發合約中可能存在的重入攻擊漏洞,將測試用例設置為調用攻擊合約發動的重入攻擊,在源測試用例測試階段就有可能觸發重入攻擊漏洞。為了避免假陰性的情況,源測試用例中的目標變量將在合約規定的范圍內隨機生成,如果滿足蛻變關系,則說明重入攻擊沒有觸發。后續測試用例將會在源測試用例的基礎上自減并進行下一輪的重入測試。直到源測試用例自減到一個設置的極小值,如果輸出的結果仍然滿足輸出關系,則證明被測合約不存在重入攻擊漏洞。

通過后續實驗發現蛻變關系MR5存在局限性:如果源測試用例和后續測試用例均能成功地觸發重入攻擊漏洞,那么仍然無法驗證該合約是否存在重入攻擊漏洞。因此,對蛻變關系進行進一步的改進。

根據此功能設計,當目標變量x為fallback 函數每次使用withdraw 取出的金額時,f(x)為用戶直接調用智能合約進行取款操作后用戶地址的余額差值,g(x)為用戶通過調用攻擊合約對該智能合約進行取款操作后用戶地址的余額差值,得出蛻變關系設計依據的必要屬性為

在沒有觸發漏洞的前提下,每次在確定的輸入域中根據蛻變關系改變目標變量的輸入,相應的輸出就必然遵循該必要屬性?;诖?,得到蛻變關系MR6

其中,x1、x2表示目標變量(正常取款操作和調用攻擊合約的操作取出的金額),對應的P(x1)、P(x2)分別表示2 種操作后取款用戶錢包中的余額差值。

為了充分避免假陰性的情況出現,將攻擊合約中fallback 函數中的withdraw 函數每次遞歸取款的金額設置為1。

根據智能合約中的定義,確定了蛻變關系涉及的4 個輸入變量和一個輸出變量:正常取款操作A、調用的攻擊合約觸發重入攻擊的操作B、被攻擊合約的地址P、2 種操作取款的金額M和不同操作執行后取款用戶的錢包余額差值S。因此,將MR6的形式化公式分解為表格形式,如表7 所示。

表7 MR6 中目標變量間的蛻變關系

在該蛻變關系中,將目標變量轉化成2 種不同的操作,分別是正常取款和調用攻擊合約取款的操作,通過對比不同操作執行的結果是否符合輸出蛻變關系,判斷合約是否存在重入攻擊漏洞。

5 實驗分析

為驗證本文提出的蛻變測試方法在檢測智能合約中存在相應漏洞的有效性,設計了多個存在相關漏洞的實例進行驗證。本節展示了實驗的細節,主要包括實驗設置、實驗流程、實驗數據和實驗結果與分析。

5.1 實驗設置

存在不同漏洞的智能合約在進行蛻變測試時需要相應的蛻變關系進行測試,利用國家安全漏洞庫CNVD、CVE 和GitHub 中收錄的漏洞實例及其他文獻的數據集中收集的漏洞合約實例進行實驗,收集的每個實例都有完整的源代碼。使用相應的蛻變關系進行蛻變測試,驗證蛻變測試的有效性。

本文具體方案設置如下:在Remix IDE 上編譯和部署待測試的智能合約,版本號為0.4.26+commit.4563c3fc,EVM 鏡像選擇default,調用合約的用戶地址為 0x5B38Da6a701c568545dC fcB03FcB875f56beddC4,測試重入攻擊漏洞時調用攻擊合約的用戶地址為0xAb8483F64d9C6d1EcF9b849 Ae677dD3315835cb2。蛻變測試實驗中待選的蛻變關系如表8 所示。

表8 蛻變測試實驗中待選的蛻變關系

5.2 實驗流程

第4 節已經完成了針對蛻變關系設計的工作。針對區塊鏈智能合約安全漏洞的蛻變測試的整體流程介紹如下。

1) 分析智能合約的具體功能和調用方法涉及的參數變量,確定測試用例生成的目標變量與輸入域,并在輸入域中生成源測試用例集E。

2) 根據目標變量中存在的函數關系確定其中的必要屬性,根據必要屬性設計相應的蛻變關系,包括輸入蛻變關系和輸出蛻變關系。

3) 使用設計的蛻變關系,基于源測試用例集生成相應的后續測試用例集E’。

4) 將源測試用例e和與之對應的后續測試用例e’在待測智能合約中運行,獲取相應的輸出結果。

5) 驗證源測試用例e和對應的后續測試用例e’的輸出結果是否符合輸出蛻變關系,如果不符合,則證明測試結果不通過。

智能合約的蛻變測試總體流程如圖9 所示。

5.3 實驗數據

被測合約均來源于近年來區塊鏈的安全事故實例以及一些經典案例,其中大量的智能合約都存在的漏洞類型包含整型(加法、減法及乘法)溢出漏洞和重入攻擊漏洞。實驗驗證的合約實例及存在的漏洞如表9 所示。

表9 實驗驗證的合約實例與存在的漏洞

通過對智能合約的具體功能和相應漏洞的分析,待測的智能合約使用的蛻變關系將在第4 節中構建的6 個蛻變關系中選取,蛻變測試流程中所有的源測試用例生成策略采取蛻變測試常用的隨機測試用例生成技術[26],即它們都來源于目標變量輸入域內的隨機值,在此基礎上獲得的源測試用例和選取的蛻變關系進一步獲得后續測試用例。根據表9所示的合約實例,使用蛻變測試驗證在區塊鏈智能合約上的蛻變測試有效性,并且和常用的智能合約檢測方法Slither 的檢測結果進行對比。

5.4 實驗結果與分析

為了評估基于蛻變測試的區塊鏈智能合約安全漏洞檢測方法的有效性,針對以下2 個問題對實驗結果進行分析:MT 是否可以檢測到MR 對應的智能合約安全漏洞?MT 是否比其他智能合約測試方法更好?

1) MT 是否可以檢測到MR 對應的智能合約安全漏洞?

為了驗證這個問題,根據表8 提供的蛻變關系,使用圖9 提出的蛻變測試流程對表9 中的智能合約實例進行了完整的蛻變測試,結果如表10 所示,實驗按照智能合約編號順序依次進行檢測。其中,“√”表示檢測出相應的漏洞,“×”表示未檢測出相應的漏洞。

表10 蛻變測試方法的檢測結果

根據表10 的實驗結果可以看出,針對區塊鏈智能合約的蛻變測試方法的有效性得到了驗證,蛻變關系使后續測試用例的生成具有較強的針對性。顯然,蛻變測試開展的基礎就是蛻變關系的正確性,即需要事先確定蛻變關系一定符合程序的必要關系。如果測試輸出不滿足蛻變關系,則相應的測試用例中一定存在失效,即程序一定存在故障?;谶@個原則,參考沒有通過蛻變關系驗證的輸出結果(失敗的測試用例),得出相應的智能合約存在漏洞的結果。

如果測試輸出滿足蛻變關系,則并不意味著相應的測試用例執行結果一定是正確的。由于現有的源測試用例的生成策略具有隨機性,定量的測試用例可能導致測試結果存在假陰性的概率,使編號2和編號4 的智能合約實例中存在的漏洞未能檢測出。因此有限類型和數量的蛻變關系對不同智能合約檢測仍然存在局限性。

綜上,蛻變測試在區塊鏈智能合約中的應用是可行的,并且具有有效性。

2) MT 是否比其他智能合約測試方法更好?

為了驗證這個問題,使用常用的智能合約檢測方法Slither 對表9 中的智能合約實例進行測試。Slither 方法的結果針對合約中的方法設置相應指標和潛在漏洞的置信度,具體的潛在漏洞以置信度評級的方式顯示,在此將置信度不高的測試指標結果認定為Slither 檢出的漏洞。根據Slither 的檢測結果和蛻變測試的檢測結果進行對比,實驗結果如表11和圖10 所示。其中,“?”表示未能檢測出任何漏洞。

圖10 兩種檢測方法的檢測結果

表11 Slither 測試方法的測試結果

從表11 和圖10 可以看出,蛻變測試在檢測整型溢出漏洞方面明顯優于Slither 方法。在智能合約中,整型溢出漏洞是最常見的智能合約安全漏洞,但是在檢測整型溢出漏洞的各種方法中,蛻變測試可以通過觸發漏洞的形式以檢測是否存在具體的漏洞,在準確率上占有明顯優勢。

相比于Slither 方法,蛻變測試有較大優勢,并且隨著蛻變關系進一步的完善,這種優勢將擴散到更多的漏洞類型和更廣泛的智能合約應用場景中。

5.5 實驗說明

根據文獻[27]可知,Slither 作為一款常用且精確度較高的測試工具,由于自身局限性,截止到該文獻發表日期,它還無法檢測與整型溢出相關的智能合約漏洞。之所以選擇Slither作為對比方法,是因為Slither工具在提高測試者對合約的了解、協助代碼審查方面具有優秀的表現。在未來的工作中,將參考Slither的相關功能嘗試為區塊鏈智能合約的蛻變測試方法增加預處理機制,這樣可以為測試時蛻變關系的選擇以及蛻變關系的設計階段提供更客觀全面的依據。

此外,蛻變關系作為蛻變測試中重要的元素組成部分,蛻變關系的識別是影響測試結果的重要因素。蛻變測試在整型溢出漏洞和重入攻擊漏洞的檢測中最明顯的優勢在于通過蛻變關系優化了動態測試面臨的測試預言難以獲取導致影響測試準確率的問題,由于這類漏洞的目標變量較固定,在面臨不同功能的智能合約測試都有較好的泛化性,在動態測試的過程中通過觸發漏洞從而進行檢測也更加實用。因此蛻變測試在針對這兩類漏洞的測試中有著良好的表現。本文根據已知漏洞的觸發原理設計蛻變關系,但此類方法存在部分局限性,主要在于智能合約的常見漏洞并不局限于整型溢出漏洞和重入攻擊漏洞,還有時間戳依賴漏洞和交易順序依賴漏洞等,這些漏洞的觸發條件也與區塊鏈網絡層的安全熟悉相關,因此暫時還無法僅通過合約層的漏洞觸發原理構建蛻變關系,隨著區塊鏈智能合約的發展,漏洞類型也將進一步增加,筆者將基于此方法分析更多類型的漏洞并設計蛻變關系,使蛻變測試的適用范圍更廣。此外,對于未知漏洞,筆者仍然需要從輸入域和輸出域的關系入手,識別科學的蛻變關系。與蛻變測試在其他的場景中應用類似,此方法最重要的內容是蛻變關系的識別,因此該方法的有效性在很大程度上取決于蛻變關系的選擇,這是此類方法應用到區塊鏈智能合約領域中依然存在的挑戰。在后續的工作中,尋找有效的蛻變關系識別方法[28]并應用到區塊鏈智能合約領域將作為筆者改進此方法的一部分。

6 結束語

在區塊鏈智能合約方面,本文提出了一種基于蛻變測試的智能合約安全漏洞檢測方法,通過對實例合約的測試,檢測智能合約中存在的整型溢出和重入攻擊漏洞??紤]到區塊鏈的不可篡改性和gas的消耗問題,蛻變測試具有明顯的優勢。一方面,蛻變測試避免了獲取測試預言可能存在的大量資源消耗和獲取困難的情況,緩解了動態測試中的Oracle 問題。另一方面,對具體的智能合約漏洞設計了相應的蛻變關系,使蛻變測試中測試用例的生成具有更強的針對性,提升了測試過程中觸發與檢測相應漏洞的概率,降低了假陽性的概率。

未來的工作主要有:1) 為了覆蓋更廣泛的智能合約安全漏洞類型,將進一步設計更多的蛻變關系,在現有的智能合約功能和已發現的漏洞的基礎上,完善關于智能合約的蛻變關系庫;2) 針對整體測試框架中智能合約分析的部分,將結合Slither 智能合約分析工具,對蛻變關系的設計和選擇提供更合理的指標支撐并提高蛻變測試的自動化程度。

猜你喜歡
安全漏洞測試用例合約
基于SmartUnit的安全通信系統單元測試用例自動生成
安全漏洞太大亞馬遜、沃爾瑪和Target緊急下架這種玩具
基于混合遺傳算法的回歸測試用例集最小化研究
基于安全漏洞掃描的校園網告警系統的開發與設計
基于依賴結構的測試用例優先級技術
安全漏洞Shellshock簡介
合約必守,誰能例外!——對“情勢變更”制度不可寄于過高期望
軟件回歸測試用例選取方法研究
NSFOCUS 2010年2月之十大安全漏洞
91香蕉高清国产线观看免费-97夜夜澡人人爽人人喊a-99久久久无码国产精品9-国产亚洲日韩欧美综合