1. 程式人生 > >淺析智慧合的約攻與防

淺析智慧合的約攻與防

智慧合約的概念其實出現的非常早,在1994年就有人提出,但是因為當時沒有這種可信化的這種執行環境,所以也並沒有在當時應用到實際的場景當中,但是在08年中本聰提出了比特幣的概念之後,人們發現作為比特幣底層的區塊鏈技術天然為智慧合約提供了可信化的執行環境。

智慧合約是部署在EVM上,最終部署在區塊鏈的公鏈上的。可以這樣說,比特幣引領區塊鏈技術,而以太坊復活了智慧合約

 

其實智慧合約的發展是非常穩定的,通過獵豹區塊鏈安全中心在前一個月的統計中,可以看到,智慧合約平均每天的增量在2200左右,還是非常穩定的

智慧合約現在的應用場景有很多,比如說去中心化的錢包、比如說代幣發行、眾籌基金,還有現在非常火的比如FO3D、以太貓之類的區塊鏈遊戲當中,隨著智慧合約如火如荼的發展,我們也開始發現很多關於智慧合約的攻擊事件,大家可以看到,這是11年到18年智慧合約安全事件統計。

其實智慧合約安全事件的比例其實非常低,只有6%左右。但是在另一個統計中可以發現,損失統計已經達到了12.4億美元,這說明了智慧合約雖然事件比較少,但是造成了這個後果是非常嚴重的,因為它是由於這個這個數字貨幣實時交易造成了非常大的影響,所以我們應該更注重這個智慧合約的安全。

比如我們非常熟悉的The DAO事件,在16年的6月,造成了以太坊的硬分叉,導致了當時1/3,接近6000萬美元數字資產的損失。

還有17年7月parity錢包的多重簽名漏洞,造成了150萬以太幣的損失。18年4月,我們眾所周知的美鏈事件,使BEC 的10億的資產在幾天內消亡,類似的還有smartmash事件,在溢位和許可權控制出現了問題,造成了1.4億美元的重大財產損失。

伴隨著智慧合約出現的這些重大事件,讓我們不禁思考,在solidity的程式碼層面到底出現了什麼樣的問題,又有哪些智慧合約的漏洞型別呢?

我們這裡簡單的總結了智慧合約TOP10的攻擊型別:重入攻擊、許可權控制、整型溢位、未檢查的call返回值、交易順序依賴、時間戳依賴、條件競爭、短地址攻擊、可預測的隨機處理等。

 

今天我們就來簡單聊一聊前面三個常見的漏洞型別

 

首先是整形溢位

 

大家都可能都比較瞭解汽車的里程錶,在里程碑表上的範圍是從0到9999的數值,當這個數值達到一定數值的時候,再增加時就會重新歸零,其實這個就是生活中的整型型溢位。

而再EVM和智慧合約的漏洞當中,EVM的資料位數就相當於我們里程錶的1-999999,EVM的資料位數是0到255的取值,向上加1就會溢位,造成歸零的情況,0到減1之後,就會產生下溢,然後變成極大值,

在上上溢的過程中,可能就是數字加法、數字乘法,會出現相關的問題,減法會產生下溢,這是我們寫程式碼時要注意到的問題。

在著名的美鏈事件中,大家可以看到一行程式碼,第257行,簡單的一個amount型別,amount那個引數等於區域性變數CNT的這個值,這樣簡單的一個操作,其實對cnt是進行驗證的,但是對amount沒有進行驗證。

所以在實際的攻擊過程中,我們攻擊者通過傳入了一個非常大value值,導致amount溢位,當這個引數可以使amount的這個值為零,然後繞過檢測,(其實下面他還做了很強勁的檢測)但是因為amount達到零之後,它繞過了這個檢測,所以這個結果就是,他獲取了非常大的value值這個數字貨幣,但是他自己的錢包裡卻沒有支付一分錢。

從etherscan上,我們也可以通過很多這種攻擊事件來回顧這些攻擊事件,就像剛才我們分享的一樣,仔細分析一下攻擊過程到底是怎麼產生的。

還有類似的edu事件,也是因為整數溢位,當然還結合了資料的許可權控制的問題,這兩個事件有共同的地方,也有不一樣的地方。

許可權失控

下面我們就說一下這個許可權問題,其實許可權問題包含種類比較多,這裡我只簡單的介紹一下建構函式的失控的問題,建構函式其實是智慧合約裡一個非常重要的函式,也非常特殊的函式,它是用來初始化這個智慧合約的所有權。

所以在這個例子中,大家可以看到,智慧合約在0.4.2之前的版本中,我們要求這個合約名與建構函式名嚴格一致,如果他們不同,建構函式可以被其他合約所呼叫,通過這種方式,惡意的攻擊者可能獲取了我們當前智慧合約的所有權,然後進行一些其他的操作。

在MorphToken這個合約上,因為兩者的大小寫不一致,導致了這個攻擊事件這個發生。

重入漏洞

接下來介紹重入漏洞,這裡我再簡單的說一下,重入其實就是遞迴,就是說對於一個函式的迴圈呼叫,對於自身的迴圈呼叫。最簡單來說,就是左邊那個如果是一個程式碼的合約,它的withdraw這個函式其實是可以進行遞迴操作,存在的問題在於他事先沒有進行先判斷後轉賬的操作,而繼而進行重入攻擊,所以可以給攻擊者產生這樣可以成功進行重入漏洞的一個條件。

在靠value的時候可以呼叫這個fallback函式,攻擊者通過這樣的合約,可以迴圈的呼叫withdraw,也就是提款操作

經過這樣一個複雜操作,迴圈之後,攻擊者可以通過自己的合約,把整個公共的合約的所有的數字貨幣轉到自己的錢包當中。著名The DAO事件,也是因為這樓棟號而產生的,當時也損失了大約1/3,約1.15億美元當時的市值的財產。

漏洞防範

以上三類漏洞我們簡單瞭解之後了,大家會考慮,對於這些漏洞我們應該如何防範?

到底怎麼解決?比如說剛才的這個整數溢位漏洞,我們可以通過對於引數的一個詳細控制,或者說利用一些第三方的這個safemath庫來保證這個數字操作的安全。

還有剛才第二個所說的許可權控制,我們要注意編碼規範,保證合約名與建構函式名相同。如果現在使用建構函式,我們建議使用constractor來進行一些複合函式的建立,

到最後的重入漏洞,要注意三點,也是剛才說的,金額轉移變數之前,一定要先進行進行金額轉移操作,而後進行一些相關的迴圈操作。

或者是我們剛才的那個call.value它是沒有限制gas上限的,我們可以用這個transfer操作的2300的gas上限,來保證這個迴圈不會遞迴的發生。

最後我們可以在程式碼中的互斥鎖來完成這些功能。

 

自動化審計

在我們統計的資料上,現在的智慧合約已經達到20萬之多。所以單純的從第三方的人工角度審計來說,可能已經跟不上合約發展了,所以自動化審批現在嗯也是大家比較關注的。

自動化審計大約分成三種類型,第一種是基於特徵碼程式碼的匹配,第二個就是基於形式化驗證自動化檢測,第三種可能就是基於符號執行、符合抽象的這種自動化審批。

智慧合約的特徵碼匹配與傳統的特徵程式碼類似,都是我們對智慧合約的對於未經程式碼的檢測和抽象,也是通過對檢測模組的這個原始碼進行匹配。

但是智慧合約還存在著一個問題,就是智慧合約在我們的公網上並不是都所有都是有明碼的,據我們統計,大約只有40%左右是有明碼的。

所以對於特徵碼匹配這一塊,我們可能要結合一些逆向來進行一些特徵碼的匹配,所以說具有一定的難度。

然後基於行政化的驗證,這裡可能一會兒會有更更詳盡的分享,這裡就不具體說。

然後基於符號執行和包括抽象的自動化檢測,目前這類檢測工具比較多,比如比較知名的Mythril、Oyente、Maian,還有這些其他的這個符號執行的這個工具。其實在智慧合約的原始碼,他是通過SOC的編譯器編譯成我們剛才所說的這個OPcode,也就EVM,類似於彙編執行的這種操作碼,然後再通過CFG的建立,也就是控制流程圖,通過這種建模的形式把它轉化成圖,讓我們更能清晰地理解opcode這個原始碼邏輯,比如出現了判斷的時候,我們能更清晰的分析出這些問題。

 

到最後我們可能就是符號抽象的分析,就是Securify,在這個智慧合約中與其他原始碼有一個非常不一樣的地方,就是其實智慧合約的這個程式碼的耦合度是非常低的,我們原來原來以前的這些程式碼耦合度非常高,所以在智慧合約的檢測當中,我們可能就針對個別模組進行檢測,將各個模組進行建模,然後匹配出他的一些惡意攻擊方式。

這是與傳統資自動化檢測分析不一樣的地方,Securify也是通過這種方式,完成自己符號抽象分析的這種檢測。

 

 區塊鏈生態安全

最後我還想再跟大家提一個問題,單純從智慧合約的這個角度,如果我們解決了這個程式碼問題,就真的能保證一個專案的安全了嘛?

我覺得可能不是可能可能不是這樣,智慧合約作為專案很重要的一個點,肯定是我們不能忽視,但是智慧合約還會存在存在一些其他的問題。比如說一個專案,它不僅僅包含智慧合約,還有他後後面的技術團隊、或者白皮書質量,還有對於自己的一些嗯社交網路輿情的一些推廣,這些都可能對我們的這個專案安全產生一定的風險。

 

比如說技術團隊中,我們看到我們自己統計過,有很多啊技術團隊造假,這些簡歷其實他個人簡歷其實寫的並不真實,或者是白皮書相似度非常高,但是質量卻非常滴。

 

到最後的薅羊毛現象,比如說一個專案的空投,一個地址,可以薅走很多的幣,還有比較明顯的現象是類似於社工,啊

比如說在官方的這個地址下,我們輸入一些利用這些官方的名字,然後假裝發現了一些空投,然後騙取正常使用者的以太幣。

 

所以我們覺得,可能安全是一個多維度的安全,光光從一個智慧合約或者程式碼的角度,並不能保證整個專案的安全,我們應該更多的結合大資料技術、或者是用智慧技術,或者說npl這樣的自然語言分析技術來保證專案安全。