智能合約的概念出現(xiàn)的非常早,在1994年就有人提出,但是因?yàn)楫?dāng)時(shí)沒(méi)有這種可信化的這種執(zhí)行環(huán)境,并沒(méi)有在當(dāng)時(shí)應(yīng)用到實(shí)際的場(chǎng)景當(dāng)中,但是在08年中本聰提出了比特幣的概念之后,人們發(fā)現(xiàn)作為比特幣底層的區(qū)塊鏈技術(shù)天然為智能合約提供了可信化的執(zhí)行環(huán)境。
智能合約是部署在EVM上,最終部署在區(qū)塊鏈的公鏈上的??梢赃@樣說(shuō),比特幣引領(lǐng)區(qū)塊鏈技術(shù),而以以太坊復(fù)活了智能合約。
其實(shí)智能合約的發(fā)展是非常穩(wěn)定的,通過(guò)獵豹區(qū)塊鏈安全在前一個(gè)月的統(tǒng)計(jì)中,可以看到,智能合約平均每天的增量在2200左右,還是非常穩(wěn)定的。
智能合約現(xiàn)在的應(yīng)用場(chǎng)景有很多,比如說(shuō)去中心化的錢(qián)包、比如說(shuō)代幣發(fā)行、眾籌基金,還有現(xiàn)在非?;鸬谋热鏔O3D、以太貓之類的區(qū)塊鏈游戲當(dāng)中,隨著智能合約如火如荼的發(fā)展,我們也開(kāi)始發(fā)現(xiàn)很多關(guān)于智能合約的攻擊事件。
這是11年到18年智能合約安全事件統(tǒng)計(jì):
其實(shí)智能合約安全事件的比例其實(shí)非常低,只有6%左右。但是在另一個(gè)統(tǒng)計(jì)中可以發(fā)現(xiàn),損失統(tǒng)計(jì)已經(jīng)達(dá)到了12.4億美元,這說(shuō)明了智能合約雖然事件比較少,但是造成了這個(gè)后果是非常嚴(yán)重的,因?yàn)樗怯捎谶@個(gè)這個(gè)數(shù)字貨幣實(shí)時(shí)交易造成了非常大的影響,所以我們應(yīng)該更注重這個(gè)智能合約的安全。
比如我們非常熟悉的The DAO事件,在16年的6月,造成了以太坊的硬分叉,導(dǎo)致了當(dāng)時(shí)1/3,接近6000萬(wàn)美元數(shù)字資產(chǎn)的損失。
還有17年7月parity錢(qián)包的多重簽名漏洞,造成了150萬(wàn)以太幣的損失。18年4月,我們眾所周知的美鏈?zhǔn)录?,使BEC 的10億的資產(chǎn)在幾天內(nèi)消亡,類似的還有smartmash事件,在溢出和權(quán)限控制出現(xiàn)了問(wèn)題,造成了1.4億美元的重大財(cái)產(chǎn)損失。
伴隨著智能合約出現(xiàn)的這些重大事件,讓我們不禁思考,在solidity的代碼層面到底出現(xiàn)了什么樣的問(wèn)題,又有哪些智能合約的漏洞類型呢?
我們這里簡(jiǎn)單的總結(jié)了智能合約TOP10的攻擊類型:重入攻擊、權(quán)限控制、整型溢出、未檢查的call返回值、交易順序依賴、時(shí)間戳依賴、條件競(jìng)爭(zhēng)、短地址攻擊、可預(yù)測(cè)的隨機(jī)處理等。
今天我們就來(lái)簡(jiǎn)單聊一聊前面三個(gè)常見(jiàn)的漏洞類型,
整形溢出
大家都可能都比較了解汽車的里程表,在里程碑表上的范圍是從0到9999的數(shù)值,當(dāng)這個(gè)數(shù)值達(dá)到一定數(shù)值的時(shí)候,再增加時(shí)就會(huì)重新歸零,其實(shí)這個(gè)就是生活中的整型型溢出。
而再EVM和智能合約的漏洞當(dāng)中,EVM的數(shù)據(jù)位數(shù)就相當(dāng)于我們里程表的1-999999,EVM的數(shù)據(jù)位數(shù)是0到255的取值,向上加1就會(huì)溢出,造成歸零的情況,0到減1之后,就會(huì)產(chǎn)生下溢,然后變成極大值,
在上上溢的過(guò)程中,可能就是數(shù)字加法、數(shù)字乘法,會(huì)出現(xiàn)相關(guān)的問(wèn)題,減法會(huì)產(chǎn)生下溢,這是我們寫(xiě)代碼時(shí)要注意到的問(wèn)題。
在著名的美鏈?zhǔn)录?,大家可以看到一行代碼,第257行,簡(jiǎn)單的一個(gè)amount類型,amount那個(gè)參數(shù)等于局部變量CNT的這個(gè)值,這樣簡(jiǎn)單的一個(gè)操作,其實(shí)對(duì)cnt是進(jìn)行驗(yàn)證的,但是對(duì)amount沒(méi)有進(jìn)行驗(yàn)證。
所以在實(shí)際的攻擊過(guò)程中,我們攻擊者通過(guò)傳入了一個(gè)非常大value值,導(dǎo)致amount溢出,當(dāng)這個(gè)參數(shù)可以使amount的這個(gè)值為零,然后繞過(guò)檢測(cè),(其實(shí)下面他還做了很強(qiáng)勁的檢測(cè))但是因?yàn)閍mount達(dá)到零之后,它繞過(guò)了這個(gè)檢測(cè),所以這個(gè)結(jié)果就是,他獲取了非常大的value值這個(gè)數(shù)字貨幣,但是他自己的錢(qián)包里卻沒(méi)有支付一分錢(qián)。
從etherscan上,我們也可以通過(guò)很多這種攻擊事件來(lái)回顧這些攻擊事件,就像剛才我們分享的一樣,仔細(xì)分析一下攻擊過(guò)程到底是怎么產(chǎn)生的。
還有類似的edu事件,也是因?yàn)檎麛?shù)溢出,當(dāng)然還結(jié)合了數(shù)據(jù)的權(quán)限控制的問(wèn)題,這兩個(gè)事件有共同的地方,也有不一樣的地方。
權(quán)限控制
下面我們就說(shuō)一下這個(gè)權(quán)限問(wèn)題,其實(shí)權(quán)限問(wèn)題包含種類比較多,這里我只簡(jiǎn)單的介紹一下構(gòu)造函數(shù)的失控的問(wèn)題,構(gòu)造函數(shù)其實(shí)是智能合約里一個(gè)非常重要的函數(shù),也非常特殊的函數(shù),它是用來(lái)初始化這個(gè)智能合約的所有權(quán)。
所以在這個(gè)例子中,大家可以看到,智能合約在0.4.2之前的版本中,我們要求這個(gè)合約名與構(gòu)造函數(shù)名嚴(yán)格一致,如果他們不同,構(gòu)造函數(shù)可以被其他合約所調(diào)用,通過(guò)這種方式,惡意的攻擊者可能獲取了我們當(dāng)前智能合約的所有權(quán),然后進(jìn)行一些其他的操作。
在MorphToken這個(gè)合約上,因?yàn)閮烧叩拇笮?xiě)不一致,導(dǎo)致了這個(gè)攻擊事件這個(gè)發(fā)生。
重入漏洞
接下來(lái)介紹重入漏洞,這里我再簡(jiǎn)單的說(shuō)一下,重入其實(shí)就是遞歸,就是說(shuō)對(duì)于一個(gè)函數(shù)的循環(huán)調(diào)用,對(duì)于自身的循環(huán)調(diào)用。最簡(jiǎn)單來(lái)說(shuō),就是左邊那個(gè)如果是一個(gè)代碼的合約,它的withdraw這個(gè)函數(shù)其實(shí)是可以進(jìn)行遞歸操作,存在的問(wèn)題在于他事先沒(méi)有進(jìn)行先判斷后轉(zhuǎn)賬的操作,而繼而進(jìn)行重入攻擊,所以可以給攻擊者產(chǎn)生這樣可以成功進(jìn)行重入漏洞的一個(gè)條件。
在靠value的時(shí)候可以調(diào)用這個(gè)fallback函數(shù),攻擊者通過(guò)這樣的合約,可以循環(huán)的調(diào)用withdraw,也就是提款操作。
經(jīng)過(guò)這樣一個(gè)復(fù)雜操作,循環(huán)之后,攻擊者可以通過(guò)自己的合約,把整個(gè)公共的合約的所有的數(shù)字貨幣轉(zhuǎn)到自己的錢(qián)包當(dāng)中。著名The DAO事件,也是因?yàn)檫@樓棟號(hào)而產(chǎn)生的,當(dāng)時(shí)也損失了大約1/3,約1.15億美元當(dāng)時(shí)的市值的財(cái)產(chǎn)。
漏洞防范
以上三類漏洞我們簡(jiǎn)單了解之后了,大家會(huì)考慮,對(duì)于這些漏洞我們應(yīng)該如何防范?
到底怎么解決?比如說(shuō)剛才的這個(gè)整數(shù)溢出漏洞,我們可以通過(guò)對(duì)于參數(shù)的一個(gè)詳細(xì)控制,或者說(shuō)利用一些第三方的這個(gè)safemath庫(kù)來(lái)保證這個(gè)數(shù)字操作的安全。
還有剛才第二個(gè)所說(shuō)的權(quán)限控制,我們要注意編碼規(guī)范,保證合約名與構(gòu)造函數(shù)名相同。如果現(xiàn)在使用構(gòu)造函數(shù),我們建議使用constractor來(lái)進(jìn)行一些復(fù)合函數(shù)的創(chuàng)建,
到最后的重入漏洞,要注意三點(diǎn),也是剛才說(shuō)的,金額轉(zhuǎn)移變量之前,一定要先進(jìn)行進(jìn)行金額轉(zhuǎn)移操作,而后進(jìn)行一些相關(guān)的循環(huán)操作。
或者是我們剛才的那個(gè)call.value它是沒(méi)有限制gas上限的,我們可以用這個(gè)transfer操作的2300的gas上限,來(lái)保證這個(gè)循環(huán)不會(huì)遞歸的發(fā)生。最后我們可以在代碼中的互斥鎖來(lái)完成這些功能。
常見(jiàn)的自動(dòng)化審計(jì)方法
在我們統(tǒng)計(jì)的數(shù)據(jù)上,現(xiàn)在的智能合約已經(jīng)達(dá)到20萬(wàn)之多。所以單純的從第三方的人工角度審計(jì)來(lái)說(shuō),可能已經(jīng)跟不上合約發(fā)展了,所以自動(dòng)化審批現(xiàn)在嗯也是大家比較關(guān)注的。
自動(dòng)化審計(jì)大約分成三種類型,第一種是基于特征碼代碼的匹配,第二個(gè)就是基于形式化驗(yàn)證自動(dòng)化檢測(cè),第三種可能就是基于符號(hào)執(zhí)行、符合抽象的這種自動(dòng)化審批。
智能合約的特征碼匹配與傳統(tǒng)的特征代碼類似,都是我們對(duì)智能合約的對(duì)于未經(jīng)代碼的檢測(cè)和抽象,也是通過(guò)對(duì)檢測(cè)模塊的這個(gè)源碼進(jìn)行匹配。
但是智能合約還存在著一個(gè)問(wèn)題,就是智能合約在我們的公網(wǎng)上并不是都所有都是有明碼的,據(jù)我們統(tǒng)計(jì),大約只有40%左右是有明碼的。
所以對(duì)于特征碼匹配這一塊,我們可能要結(jié)合一些逆向來(lái)進(jìn)行一些特征碼的匹配,所以說(shuō)具有一定的難度。
基于符號(hào)執(zhí)行和包括抽象的自動(dòng)化檢測(cè),目前這類檢測(cè)工具比較多,比如比較知名的Mythril、Oyente、Maian,還有這些其他的這個(gè)符號(hào)執(zhí)行的這個(gè)工具。其實(shí)在智能合約的源碼。
它是通過(guò)SOC的編譯器編譯成我們剛才所說(shuō)的這個(gè)OPcode,也就EVM,類似于匯編執(zhí)行的這種操作碼,然后再通過(guò)CFG的建立,也就是控制流程圖,通過(guò)這種建模的形式把它轉(zhuǎn)化成圖,讓我們更能清晰地理解opcode這個(gè)源碼邏輯,比如出現(xiàn)了判斷的時(shí)候,我們能更清晰的分析出這些問(wèn)題。
到最后我們可能就是符號(hào)抽象的分析,就是Securify,在這個(gè)智能合約中與其他源碼有一個(gè)非常不一樣的地方,就是其實(shí)智能合約的這個(gè)代碼的耦合度是非常低的,我們?cè)瓉?lái)原來(lái)以前的這些代碼耦合度非常高,所以在智能合約的檢測(cè)當(dāng)中,我們可能就針對(duì)個(gè)別模塊進(jìn)行檢測(cè),將各個(gè)模塊進(jìn)行建模,然后匹配出他的一些惡意攻擊方式。
這是與傳統(tǒng)資自動(dòng)化檢測(cè)分析不一樣的地方,Securify也是通過(guò)這種方式,完成自己符號(hào)抽象分析的這種檢測(cè)。
共建區(qū)塊鏈生態(tài)安全
以上就是我所分享的基礎(chǔ)的四個(gè)方向,但是我還想再跟大家提一個(gè)問(wèn)題,單純從智能合約的這個(gè)角度,如果我們解決了這個(gè)代碼問(wèn)題,就真的能保證一個(gè)項(xiàng)目的安全了嘛?
我覺(jué)得可能不是可能可能不是這樣,智能合約作為項(xiàng)目很重要的一個(gè)點(diǎn),肯定是我們不能忽視,但是智能合約還會(huì)存在存在一些其他的問(wèn)題。比如說(shuō)一個(gè)項(xiàng)目,它不僅僅包含智能合約,還有他后后面的技術(shù)團(tuán)隊(duì)、或者白皮書(shū)質(zhì)量,還有對(duì)于自己的一些嗯社交網(wǎng)絡(luò)輿情的一些推廣,這些都可能對(duì)我們的這個(gè)項(xiàng)目安全產(chǎn)生一定的風(fēng)險(xiǎn)。
比如說(shuō)嗯技術(shù)團(tuán)隊(duì)中,我們看到我們自己統(tǒng)計(jì)過(guò),有很多啊技術(shù)團(tuán)隊(duì)造假,這些簡(jiǎn)歷其實(shí)他個(gè)人簡(jiǎn)歷其實(shí)寫(xiě)的并不真實(shí),或者是白皮書(shū)相似度非常高,但是質(zhì)量卻非常滴。
到最后的薅羊毛現(xiàn)象,比如說(shuō)一個(gè)項(xiàng)目的空投,一個(gè)地址,可以薅走很多的幣,還有比較明顯的現(xiàn)象是類似于社工,啊
比如說(shuō)在官方的這個(gè)地址下,我們輸入一些利用這些官方的名字,然后假裝發(fā)現(xiàn)了一些空投,然后騙取正常用戶的以太幣。
所以我們覺(jué)得,可能安全是一個(gè)多維度的安全,光光從一個(gè)智能合約或者代碼的角度,并不能保證整個(gè)項(xiàng)目的安全,我們應(yīng)該更多的結(jié)合大數(shù)據(jù)技術(shù)、或者是用智能技術(shù),或者說(shuō)npl這樣的自然語(yǔ)言分析技術(shù),
獵豹在這塊也做了一款ratingtoken的產(chǎn)品,通過(guò)對(duì)項(xiàng)目鏈上鏈下的數(shù)據(jù)提取分析,并通過(guò)nlp自然語(yǔ)言這種處理,對(duì)整個(gè)項(xiàng)目進(jìn)行了一個(gè)情感的分析。
所以我們也希望就是通過(guò)更多維度的引入,與大家共同努力,讓這個(gè)圈子引進(jìn)更多的人才,共同維持這個(gè)區(qū)塊鏈生態(tài)的安全。
Ratingtoken官網(wǎng):https://www.ratingtoken.net/?from=z