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

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

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

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

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

本質上,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函數的三個不良行爲,我們仍然需要手動地對它們的可利用性進行推理,這是非常重要的,並且需要安全專業知識。必須確保在手動推理過程中不遺漏任何關鍵細節。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章