大規模查找貪婪,揮霍和自殺的合約

大規模查找貪婪,揮霍和自殺的合約

7.1 引用

Nikolić I, Kolluri A, Sergey I, et al. Finding the greedy, prodigal, and suicidal contracts at scale[C]//Proceedings of the 34th Annual Computer Security Applications Conference. ACM, 2018: 653-663.

7.2 摘要

智能合約是在像以太坊這樣的區塊鏈上託管的有狀態可執行對象,它們攜帶了價值數十億美元的硬幣,且一旦部署就無法更新。我們提出了一類跟蹤漏洞的新系統特徵,這些漏洞是通過分析合約在其生命週期內的多次調用而產生的。我們將注意力集中在這些跟蹤漏洞的三個示例屬性上:找到無限期鎖定資金,不經意地向任意用戶洩露或者可能被任何人殺死的合約。我們實現了MAIAN,這是第一個精確指定和推理跟蹤屬性的工具,它採用程序間符號分析和具體驗證程序來展示真實的漏洞。我們對近百萬份合約的分析標誌著34,200(2,365種不同)合約易受攻擊,每份合約10秒。在我們為具體驗證和人工分析抽樣的3,759份合約的子集中,我們以89%的真實正率再現真實的漏洞利用,產生了3,686份合約的漏洞利用。我們的工具找到了臭名昭著的Parity漏洞的漏洞利用,這個漏洞間接鎖定了2億美元以太的價值,以前的分析無法捕獲。

7.3 技術介紹

智能合約提供了安全挑戰的獨特組合。一旦部署,它們就無法升級或修補,與傳統的消費設備軟件不同。其次,它們是在一個由語言和運行時環境組成的新生態系統中編寫的,其事實上的標準是以太坊虛擬機及其名為Solidity的編程語言。合約相對較難測試,特別是因為它們的運行時允許它們與其他智能合約和外部鏈外服務交互;它們可以由大量用戶的事務重複調用。第三,由於區塊鏈上的虛擬幣通常具有重大價值,攻擊者極有動機發現並利用處理或直接持有它們以獲取利潤的合約中的漏洞。對DAO合約的攻擊使以太坊社區損失了6000萬美元;最近的幾次攻擊也產生了類似規模的影響。

在這項工作中,我們提出了一類漏洞的系統描述,我們將其稱為跟蹤漏洞。與之前許多應用靜態和動態分析自動查找合約中的錯誤的工作不同,我們的工作側重於在調用合約的長序列中檢測漏洞。我們將易受攻擊的合約分為三類:貪婪、揮霍和自殺,這三類合約要麼無限期鎖定資金,要麼洩露給任意用戶,要麼容易被任何用戶殺死。我們精確定義的屬性捕獲了許多已知的bug的已知示例,但大致涵蓋了一類在以前的工作或公共報告中不知道的示例。更重要的是,我們的特性允許我們通過運行合約來具體檢查錯誤,這有助於確定確認的真實陽性。

雖然跟蹤漏洞是一個更廣泛的方向,但我們將注意力集中在三個用於檢查合約跟蹤的示例屬性上。具體來說,我們標記的合約(a)可以被任意地址殺死,(b)在某個執行狀態之後無法釋放ether,以及(c)不小心將ether釋放到任意地址。注意,對bug的任何描述都必須有一點把握,因為人們總是可以認為暴露的行為體現了意圖——正如DAO的例子中所討論的那樣。我們對漏洞的描述部分基於公開報道的新聞。然而,據我們所知,我們的特徵是第一個精確定義此類事件的可檢查屬性並測量其普遍性的特徵。

大規模查找貪婪,揮霍和自殺的合約

圖 7-1 賞金合約,payout 洩露以太幣

揮霍合約。合約通常會將資金返還給所有者(在受到攻擊時)、過去曾向其發送ether的地址(例如,在彩票中)或展示特定解決方案的地址(例如,在獎金中)。然而,當一份合約將ether洩露給一個任意的地址時——該地址不是所有者,從未在合約中存放ether,也沒有提供任何數據,這些數據是任意觀察員難以捏造的,我們認為這是一個漏洞。我們有興趣找到這樣的合約,我們稱之為揮霍合約。考慮圖1中給出的代碼片段的賞金合約。此合約從不同來源收集ether,並獎勵給選定的一組接收者。在合約中,函數payout發送給接收者指定數量的ether的列表。從函數定義可以清楚地看出,接收者和金額是作為輸入提供的,任何人都可以調用函數(即函數對發送者沒有限制)。未檢查事務的郵件發件人;唯一的檢查是列表大小。因此,任何用戶都可以使用自己選擇的接收者列表來調用此函數,並完全耗盡其ether。上面的合約需要一個函數調用來洩漏它的ether。但是,有一些合約示例需要兩個或多個調用(帶有特定參數的調用)才能導致洩漏。

大規模查找貪婪,揮霍和自殺的合約

圖 7-2 ParityWalletLibrary合約的簡化片段,可以被殺死。

自殺合約。在緊急情況下,如由於攻擊而耗盡ether或發生故障時,合約通常會啟用由其所有者(或受信任的地址)殺死的安全回退選項。然而,如果一個合約可以被任意的帳戶殺死,這將使它執行自殺指令,我們認為它是脆弱的,並稱之為自殺。最近的平價慘敗就是此類合約的一個具體例子。一個被認為是無辜的以太坊用戶殺死了一個主對等合約所依賴的庫合約,從而使後者失去功能並鎖定了它的所有以太。為了理解庫合約自殺的一面,請關注圖7-2中給出的這個合約的縮短代碼片段。要終止合約,用戶調用兩個不同的函數:一個用於設置所有權,三個用於實際終止合約。也就是說,用戶首先調用initMultiowned,為owners提供空數組,為required提供零數組。這實際上意味著合約沒有所有者,沒有人必須同意執行特定的合約功能。然後用戶調用kill函數在執行第22行的實際自殺命令之前,此功能需要所需數量的所有者同意終止合約但是,由於在上一次調用initMultiowned時,required的值被設置為零,執行自殺,因此合約被終止。

大規模查找貪婪,揮霍和自殺的合約

圖 7-3 AddressReg合約鎖定ether。

貪婪合約。我們指的是那些仍然有效並無限期鎖定以太的合約,允許它在任何條件下都不被釋放,我們稱之為貪婪。在Parity合約的例子中,許多其他類似multisigWallet的合約持有Ether,使用Parity庫合約中的函數向其用戶發放資金奇偶校驗庫合約被殺後,錢包合約再也無法訪問庫,從而變得貪婪此漏洞導致無限期鎖定價值2億美元的以太美元!貪婪的合約也可能由更直接的錯誤引起。最常見的此類錯誤發生在接受以太網的合約中,但要麼完全沒有發送以太網的指令(例如發送,呼叫,轉移),要麼無法訪問此類指令圖3中給出了一個缺少釋放ether的命令的合約示例,該命令已經鎖定了ether。

已死亡合約。當合約被終止時,其代碼和全局變量將從區塊鏈中清除,從而阻止其進一步執行其代碼。但是,所有被殺害的合約繼續接收交易雖然這些交易不能再調用合約代碼,但如果以及它們一起發送,則會將其添加到合約餘額中,類似於上述情況,它會無限期地被鎖定。已死亡合約不包含任何代碼,但具有ether。在發送以太之前,發件人有責任檢查合約是否存在,並且證據表明情況並非總是如此。由於死後合約不需要進一步的靜態分析,除了識別自殺合約之外,我們不會將其視為單獨的一類錯誤。我們只列出了我們在第5節中找到的現場以太坊區塊鏈上的所有死後合約。

我們的方法每次調用合約(稱為調用)都可以在給定輸入上下文的合約代碼中執行路徑。請注意,先前的工作已經考慮了作為一次調用的屬性的錯誤,忽略了鏈接效應,並且在一些調用中。我們開發了一種工具,使用系統技術來查找違反特定痕跡屬性的合約。違規行為是:(a)安全財產,聲稱存在來自指定區塊鏈狀態的痕跡,導致合約違反某些條件; (b)活躍屬性,斷言在從指定區塊鏈狀態開始的任何執行中是否不能採取某些行動。

大規模查找貪婪,揮霍和自殺的合約

圖 7-4 MAIAN

如圖7-4,我們將發現漏洞的技術實現了一種名為MAIAN的工具,它包括兩個主要組成部分:符號分析和具體驗證。符號分析組件將合約字節碼和分析規範作為輸入。規範包括搜索的漏洞類別和搜索空間的深度,我們將其稱為調用深度。為了開發我們的符號分析組件,我們實現了一個自定義的以太坊虛擬機器,便於合約字節碼的符號執行。對於每個合約候選者,我們的組件以符號方式運行可能的執行跟蹤,直到找到滿足一組預定屬性的跟蹤。每個執行跟蹤的輸入上下文是一組符號變量。標記合約後,組件將返回這些變量的具體值。我們的最後一步是具體執行合約並驗證結果的真實性;此步驟由我們的具體驗證組件實現。具體驗證組件獲取符號分析組件生成的輸入,並在以太坊區塊鏈的私有分支上檢查合約的利用。從本質上講,它是一個用於確認錯誤正確性的測試平臺環境。因此,在驗證結束時,候選合約被確定為真或假陽性,但主要區塊鏈上的合約狀態不受影響,因為沒有對官方以太坊區塊鏈進行任何更改。總共,在這三類漏洞中,MAIAN被用於分析公共以太坊區塊鏈的970898個實時合約。我們的技術足夠強大,可以找到臭名昭著的奇偶性錯誤,它間接導致了價值2億美元的ether,這是以前的分析所沒有發現的。

7.4 本文主要貢獻

•我們確定了三類跟蹤漏洞,這些漏洞可以作為執行跟蹤的屬性捕獲——可能是無限的合約調用序列。以前的技術和工具並不是為了找到這些錯誤而設計的,因為它們只模擬單個合約調用的行為。

•我們提供正式的高階屬性來檢查哪個允許機械化符號分析程序進行檢測。 我們完全實現了MAIAN,一種用於智能合約字節碼的符號分析工具(無需訪問源代碼)。

•我們測試了近100萬份合約,在每份合約的分析時間內,在幾秒鐘內找到了數千個確認的真陽性。使用MAIAN測試跟蹤屬性是切實可行的。

本文由南京大學軟件學院2018級碩士巫浩然翻譯轉述。


分享到:


相關文章: