區塊鏈研究實驗室|形式驗證如何幫助防止Gridlock錯誤

最近在Edgeware的Lockdrop智能合約中發現了一個隱藏的DoS錯誤(稱為Gridlock),該合約已鎖定了價值數億美元的以太幣。 由於存在此錯誤,Edgeware必須重新部署合約的穩定版本。因此,當前在主網上並行存在兩個Lockdrop合約(舊版本和新版本)。(這意味著您可以向這兩個合約中的任何一個發送交易以鎖定您的以太幣,直到舊的合約遭到攻擊並無法使用為止。)

在本文中,我們將回顧Gridlock錯誤,並討論形式驗證如何有助於防止此類錯誤。

正如Neil McLaren的博客文章中所描述的那樣,這個錯誤源於一個錯誤的(但非常合理的)假設,即新創建的帳戶餘額總是為零。

要了解更多詳細信息,讓我們看一下原始buggy合約(簡化)代碼片段:

區塊鏈研究實驗室|形式驗證如何幫助防止Gridlock錯誤

本質上,lock函數會繞過收到的以太幣金額(即msg.value)創建一個新lock合約賬戶,並確保新創建的賬戶(lockAddr)具有繞過的以太幣餘額。

儘管乍看之下看起來不錯,但是此代碼僅在新創建的帳戶的餘額為零時才有效,但不幸的是並非總是如此。 這是因為可以預先計算新帳戶的地址,因此惡意用戶甚至可以在通過lock函數創建之前向其發送一些以太幣。 一旦發生這種情況,assert語句將在任何進一步的lock函數調用中繼續失敗,這意味著該函數將永遠無法執行應做的事情,變得完全無法使用。

(請注意,此行為特定於EVM。在可以識別不存在的帳戶並禁止其收取資金的其他VM中,該錯誤可能並不存在。)

形式驗證可以幫助嗎?

現在讓我們解釋一下如何通過正式驗證,尤其是在EVM字節碼級別的驗證來發現Gridlock錯誤。

形式驗證的基本過程之一是通過符號執行來探索給定程序的所有可能行為(在這種情況下為Lockdrop合同的EVM字節碼)。在這裡,我們使用KEVM驗證程序來象徵性地執行字節碼。長話短說,上述lock函數字節碼的符號執行將產生以下行為(例如由於用盡gas而導致的功能故障)。

1. 如果在新帳戶地址上已經存在一個帳戶,且現有帳戶的代碼為非空或其現時值為非零,則還原(由於第3行的新合同創建失敗)。

2. 還原(由於第5行斷言失敗),如果新帳戶地址上已經存在一個帳戶,現有帳戶的代碼為空,其現時值為0,餘額為非零。

3. 成功終止後,如果在新帳戶地址上已經存在一個帳戶,該帳戶的現有代碼為空,其現時數為零,其餘額為零。 (如果現有帳戶為非空,則清除其存儲。)

4. 如果新帳戶地址沒有帳戶,則成功終止。

(注意,第三個和第四個行為需要更多的條件,例如沒有用完gas,或者正確地給出了枚舉類型參數,但是為了簡單起見,我們在這裡省略了它們。)

一旦研究了合同的所有可能行為,下一個重要步驟便是仔細檢查每種行為,以確保它是有意或無意的,否則就很難被利用。確實在上述四種可能的行為中,只希望有第四種,並且我們需要分析其他行為以檢查它們是否可利用。

如果可以利用第一行為和第二行為,則可以將其用於DoS攻擊。但是,據我們所知,第一個行為幾乎是無法利用的,因為在密碼上很難在給定的特定地址創建合約帳戶(即具有非空代碼的帳戶)。 (為此,需要使用CREATE2操作碼來查找對應於特定地址的鹽,這與查找SHA3哈希的原像一樣困難。)但是第二種行為是可利用的,因為可以輕鬆地啟動一個如前所述,只需向其發送一些以太幣即可在任何特定地址的非合同賬戶(即無代碼的賬戶)。

另一方面,第三種行為(如果可以利用)可以用來耗盡其他人的“locked”以太幣,這確實是致命的。然而據我們所知,由於與第一種情況相似的原因,它幾乎無法被利用。 (一個人可以很容易地在一個特定的地址“啟動”一個帳戶,但是很難“擁有”該帳戶,因為這需要找到密鑰。)

綜上所述,對lock函數節碼的符號執行可能揭示了這三種不良行為,並且仔細檢查它們可能發現其中一種可被DoS攻擊利用,從而在部署之前修復了Gridlock錯誤。

吸取教訓

EVM通常是不直觀的。

Gridlock錯誤源自對EVM設計中某些非顯而易見部分的錯誤理解。如果不考慮EVM級別的智能合約,就很容易錯過這種EVM問題,並且可能會再次引入類似的bug。

形式驗證可以提供幫助。

如果不採用有原則的方法,那麼探索所有可能的行為(尤其是在EVM級別)並非易事。形式驗證,尤其是它的符號執行過程,可以系統地探索給定智能合約的所有可能行為,這比僅手工檢查代碼要嚴格得多。

具體來說,我們的KEVM驗證程序使用的是EVM的確切規範(又稱KEVM),不會讓您擺脫錯誤的假設。如上所示,它甚至會發現執行路徑非常不可能,例如攻擊者找到哈希的預映像並將其合同部署到下一個地址的情況。

形式驗證不是萬靈丹。

雖然形式驗證引導我們系統地探索和嚴格地推理給定程序的所有可能行為,實際上,它是找到程序的關鍵問題的最終途徑,如果有的話,它仍然需要大量的人工努力,有時在智力上具有挑戰性。例如即使我們自動找到了lock函數的三個不良行為,我們仍然需要手動地對它們的可利用性進行推理,這是非常重要的,並且需要安全專業知識。必須確保在手動推理過程中不遺漏任何關鍵細節。


分享到:


相關文章: