黑客來襲,手把手帶你深挖區(qū)塊鏈安全漏洞區(qū)塊鏈

區(qū)塊鏈大本營 2018-08-04 17:25
分享到:
導讀

區(qū)塊鏈行業(yè)正面臨著私鑰生成與保護、共識過程中心化、智能合約代碼漏洞等安全問題,開發(fā)者該如何應對及避免漏洞頻發(fā)呢?

黑客來襲,手把手帶你深挖區(qū)塊鏈安全漏洞

目前,區(qū)塊鏈漏洞安全問題頻發(fā)。

區(qū)塊鏈行業(yè)正面臨著私鑰生成與保護、共識過程中心化、智能合約代碼漏洞、簽名過程算法漏洞、系統(tǒng)實現(xiàn)代碼漏洞等安全問題,對于以上問題,開發(fā)者該如何應對及避免漏洞頻發(fā)呢?

以下為吳家志在CSDN主辦,區(qū)塊鏈大本營、柏鏈道捷、極客幫創(chuàng)投協(xié)辦的技術沙龍上的發(fā)言內(nèi)容,區(qū)塊鏈大本營在不改變原意的情況下作了精心整理。

黑客來襲,手把手帶你深挖區(qū)塊鏈安全漏洞

我先自我介紹一下,我叫吳家志,目前在PeckShield擔任研發(fā)副總。我們是今年年初轉到區(qū)塊鏈領域的,其實創(chuàng)業(yè)初期我們有做過一些其他的嘗試,之前我的工作比較偏向操作系統(tǒng)安全方面,主要在安卓方向,像360 C0RE Team、360超級ROOT都是我在 360期間開發(fā)出來的產(chǎn)品。

黑客來襲,手把手帶你深挖區(qū)塊鏈安全漏洞

目前,區(qū)塊鏈發(fā)展的趨勢是怎樣的?可以看一下數(shù)據(jù),藍線代表創(chuàng)建智能合約數(shù)量的趨勢。

可以看出,去年9月份,智能合約數(shù)量出現(xiàn)了大幅下滑,年底各種ICO的出現(xiàn),使智能合約數(shù)量有了很大的上升,今年2月份又出現(xiàn)了明顯的下降,過去的兩到三個月也都在下降,不過7月份開始又往上漲了,這其中的原因,在場的大家都知道,我就不說了。

而且,至少2017年下半年開始到今年年初,由于區(qū)塊鏈各行業(yè)DApp不斷落地,行業(yè)形勢看起來一片大好

區(qū)塊鏈這么火,投資人會投入大量資金去買幣、炒幣...

但在我們安全研究人員眼里來看,它其實是黑客非常感興趣的目標。

黑客來襲,手把手帶你深挖區(qū)塊鏈安全漏洞

2014年的Mt.Gox的事件開始,一直到今年這個時間,出現(xiàn)了很多區(qū)塊鏈安全事件。比如今年4月份有關智能合約漏洞的美鏈(BEC)事件,5月份的EDU,到近期的交易所被黑,各類安全事件很多很多。

這種安全問題,它造成的結果是非常嚴重的,你的錢是真的不見了。不像是手機里面的照片、隱私被竊這種,這根本不是一個級別的。

今天我主要講兩個主題,智能合約安全公鏈安全。

黑客來襲,手把手帶你深挖區(qū)塊鏈安全漏洞

深入淺出:Fomo 3D漏洞

先講一下智能合約相關的安全問題,近期F3D十分火爆,它有很多有趣的東西,就在6天前,我們就有一個比較新的研究……

微博:https://weibo.com/ttarticle/p/show?id=2309404265433178991610

這個故事是這樣的,大概7月 23日晚上 8點多,我在微博上發(fā)現(xiàn)了一條關于F3D的信息,Geth客戶端開發(fā)團隊的 team leader、以太坊核心成員 Peter 發(fā)現(xiàn)了一個F3D的airdrop()問題,這引起了我的興趣,然后我們就去分析。

黑客來襲,手把手帶你深挖區(qū)塊鏈安全漏洞

黑客來襲,手把手帶你深挖區(qū)塊鏈安全漏洞

這個事情很有趣,先看右邊藍色框內(nèi),它就是F3D的智能合約之一,它其實有很多合約,今天我只講其中一個。

其中有一個環(huán)節(jié)做airdrop(),你可以理解為它利用了彩票抽獎的機制,假設你投注F3D,不管你買了多少Key,買完之后它就有一個小概率事件,會讓你中獎,然后你就會有一個額外的激勵。我覺得這個設計也挺合理的,它可以活躍用戶參與。

0.1個ETH是F3D最低的獎金,有人刻意用最低的投入去薅羊毛,他只要操作個錢,就有機會中獎。最后智能合約里面的withdraw()函數(shù)把錢取出來。

黑客來襲,手把手帶你深挖區(qū)塊鏈安全漏洞

先看一下function airdrop()這個函數(shù),有個名為seed的變量,seed是隨機數(shù)中很重要的一個概念,計算機世界中不存在一個絕對的隨機數(shù),你只能通過seed去生成一個相對的隨機數(shù)。

一旦你可以通過某種方法預測seed值,這個隨機其實就會從小概率事件可能變成一個大概率事件

比如說我剛開始學編程的時候,一開始學C,我用random()函數(shù)獲取隨機數(shù),我那時候還不知道seed,我就會傳空值或者傳零進去,然后我發(fā)現(xiàn)每次跑都會是同一個結果。

這個黑客找到了一個方式,在每次投注的時候,預測說這里一定會開獎,百分之百會開獎。確定之后他再投這個錢,所以他每次都可以從里面拿錢出來。

說一下這個東西是怎么被預測的?其實它的實現(xiàn)是這樣的,可以看到seed運算里面有這么幾個關鍵點,比如說timestamp、difficulty、coinbase、gaslimit和number。

還有一個比較特別的,就是airDropTracker_,事實上這些都是合約里面的一個值,你可以隨時把它讀出來,所以你可以認為前面提到的全部都是已知的,唯一你不能預測的,就是msg.sender。

當時Peter認為F3D團隊假設認為msg.sender的隨機性是足夠的,其實 msg.sender就是你進到合約時的錢包地址,F(xiàn)3D團隊認為你不可能生成大量的錢包去嘗試,然后讓seed變成可預測的,但并不是只能從錢包進來,也可以從另外一個合約進來,這個其實就是關鍵。

黑客來襲,手把手帶你深挖區(qū)塊鏈安全漏洞

這就又涉及到一個算法,有一個叫isHuman()的函數(shù)判斷,判斷是真人錢包還是其他合約,但問題是這個判斷有一個錯誤,就是Extcodesize()。

你可以用智能合約不停地刷airdrop(),這很像一個挖礦的過程,因為智能合約生成的新合約地址是可預測的,所以你就可以一直不停的算,直到算出一個seed結果滿足return(true) 時,就可以保證開獎。

一旦智能合約在constructor()里面去調(diào)isHuman()判斷時,它就會誤判,然后造成人為開獎的結果。

黑客來襲,手把手帶你深挖區(qū)塊鏈安全漏洞

所以,就會出現(xiàn)這樣一個的攻擊模式——首先可以生成多個合約,然后就一直算,直到算到某一個可以搭配當下airDropTracker_的合約X時,就可以保證開獎,然后再根據(jù)合約X去投注,就可以不斷把財經(jīng)池里面的財經(jīng)全部都拿走。

但其實對F3D來說,這也不是一個太大的問題。因為被攻擊的財經(jīng)池只是F3D整個獎金環(huán)節(jié)中的很小一塊。

所以,它就好比你玩某一個游戲,有一個外掛,你的攻擊力每次都加9,保證你可以把人砍死,大概是這樣,有點類似破壞游戲平衡吧,但其實對整個游戲的影響不會太大,比如說把所有人的個人資產(chǎn)都拿走。

其他智能合約相關漏洞

接下來講一些其他有關智能合約安全的問題。

黑客來襲,手把手帶你深挖區(qū)塊鏈安全漏洞

有一類問題是跟allowance有關的,比如ERC20里面有一個標準的API叫transferFrom(),它允許某一個人把你的錢轉走,但前提是事先已經(jīng)聲明好的,在哪里去聲明?就是在allowed[]這個數(shù)組里。

黑客來襲,手把手帶你深挖區(qū)塊鏈安全漏洞

這里有一個問題,雖然它可以允許你把錢轉走,但是卻無法判斷你要轉走多少錢,它其實是僅僅把這個allowance剪掉了,這是代碼上的一個bug,EDU問題就屬于這種類型。

這是我做的一個實驗,我隱去了一些信息

黑客來襲,手把手帶你深挖區(qū)塊鏈安全漏洞

最上面那個0xd開頭的值是我的一個錢包地址,然后To指向是受我攻擊的合約的地址,攻擊完成后,我把0xa地址其中的一個EDU,就是好多0后面有1個的那個,轉到了0x6這個地址,其實0x6也是我的錢包地址。

Input Data這一塊是一些攻擊的細節(jié),其實這個構造起來非常簡單,你只要去調(diào)transferFrom()函數(shù),然后你就傳入from、to和value。所以,我偷了一個EDU到我的錢包,這個攻擊就是這樣的。

黑客來襲,手把手帶你深挖區(qū)塊鏈安全漏洞

接下來,以batchTransfer()為例,講一下overflow相關的漏洞,它的攻擊是這樣完成的。

黑客來襲,手把手帶你深挖區(qū)塊鏈安全漏洞

在調(diào)用batchTransfer()函數(shù)時,有兩個可以傳入的參數(shù),一個是receivers,一個是value。

receivers是一個數(shù)組,它傳入了40這個數(shù),這個數(shù)值表示偏移量,是需要傳給智能合約的。然后下面還有2或者8開頭的。

這個邏輯是這樣的,在batchTransfer()的實現(xiàn)上面,就是把8開頭后面全部都是0的這個值,同時轉給兩個人

如果按一般的邏輯去理解,賬號里必須有足夠的錢才能夠轉過去。但問題是,在它實現(xiàn)檢查時,它的實現(xiàn)方法是直接算兩個數(shù)的乘積。

用0去乘,結果是很明顯的,就算用最大的字節(jié)去乘,乘完之后它也會變成0。

所以,你可以在沒有任何錢的情況下把這么多錢轉給那兩個人,也就是上面紅色框部分,你會看到這個地方兩個transfer都是這么大量的Token,美鏈事件就是這樣,通過這種方式可以無中生有造出大量的假幣,然后再把假幣充到OKEx里面,然后就可以進行砸盤等各種操作。

黑客來襲,手把手帶你深挖區(qū)塊鏈安全漏洞

另外一個案例和transfer還蠻像的,但稍微復雜一點,兩個address跟value都是數(shù)組。

它們溢出的方式一樣,就是說把這些值加起來或者乘起來,然后造成的結果也是一樣的,就是很大量的假幣就充進你錢包地址。

到這里,我大概簡單講了講智能合約方面的安全問題,其中一個是F3D薅羊毛的最新研究,還有一些過去我們發(fā)現(xiàn)的其他問題。

公鏈安全

今天的第二個主題,我講一下關于Infrastructure方面的安全問題,就是所謂的公鏈安全。

黑客來襲,手把手帶你深挖區(qū)塊鏈安全漏洞

PeckShield在以太坊公鏈上做了很多研究,EOS相關的也有一些

講到公鏈問題其實你可以這樣理解,比如說你用一個360手機衛(wèi)士,可以理解為有一個客戶端在手機上運行,然后還有各種服務端,你要發(fā)送各種請求,然后它會推送一些信息給你。

而在區(qū)塊鏈里面,你可以理解為只有客戶端沒有服務端,至少以太坊上是這樣子的,每一個節(jié)點基本上長的都是一模一樣的。

所以,那時候我們開始進入?yún)^(qū)塊鏈行業(yè)、研究主鏈安全時,我們其實就是去看所有客戶端的代碼,看它實現(xiàn)的邏輯有沒有什么錯誤。

黑客來襲,手把手帶你深挖區(qū)塊鏈安全漏洞

這邊是一個統(tǒng)計,Ethereum Nodes這個網(wǎng)站可以統(tǒng)計以太坊上都運行了哪些客戶端,比如說有Geth、C 和Parity,還有Python。所以,用的比較多的是Geth和Parity,今天的研究主要在Geth,因為它是官方的且用戶量大,對Parity也有一些研究。

黑客來襲,手把手帶你深挖區(qū)塊鏈安全漏洞

首先講Geth這一塊,其實談到任何的安全問題,我們都需要先理解這樣一個事情,就比如說Geth是一個盒子,我們用什么方式可以攻破它?就是所謂的Attack Surface(攻擊面)的問題。

比如說可以通過一個智能合約去攻擊它,那它可能就是EVM方面的問題。

還可以通過一個RPC接口,它就可以類比成以前那種Web安全相關的這種問題。

還有一種,通過協(xié)議棧攻擊,這兩個其實是有點不一樣的。因為區(qū)塊鏈里面的每一個客戶端之間,它們會互相去同步,或者互相分享信息,所以協(xié)議棧的問題是最底層、也比較關鍵的問題,一旦出問題的話,整個系統(tǒng)可能就不運行了。所以,接下來我主要在協(xié)議棧這一方面進行一些探討。

黑客來襲,手把手帶你深挖區(qū)塊鏈安全漏洞

這是以太坊的協(xié)議棧,大概是這樣,很多部分可能你們以前沒有聽到,像ETH、LES和Whisper是你們比較熟知的,就是以太坊的協(xié)議。然后跟它并列的還有一些其他的,它的底層其實是包含RLPx、DΞVp2p的。

假設說你運行過Parity或者Geth,你要同步一個full node其,實很花時間,我那時候剛開始弄花了可能有小一個月,就看你的帶寬怎么樣了;還有就是硬盤,我發(fā)現(xiàn)機械式硬盤基本沒戲,一定要SSD才有可能進行同步。

與ETH并列的協(xié)議LES,它是一個比較輕的協(xié)議,你在同步時,你不需要將所有的信息都同步,你可能只會同步一些metadata。

所以,在運行Geth時,你可以去指定運行LES mode這種模式

黑客來襲,手把手帶你深挖區(qū)塊鏈安全漏洞

接下來,詳細介紹一下我們之前發(fā)現(xiàn)的關于LES的安全問題。

簡單的說,就是一個越界讀的問題,問題出在上面這一行代碼,就在query.Skip這里。

我們可以自己去寫一個類似于Geth的客戶端,我只要知道你Geth的IP就ok。比如說有一個礦池,礦池總要有一個節(jié)點去同步到鏈上,我一旦知道這個IP是什么,我就可以偽造這個東西,然后讓你崩潰。

黑客來襲,手把手帶你深挖區(qū)塊鏈安全漏洞

那么,如何讓它崩潰的?我把Skip值設成-1(在協(xié)議棧上你可以自由設置),-1 1就是0,就等于說我可以嘗試讓你去分配一個長度為0的數(shù)組,然后我又可以去讀這個數(shù)組的Skip值為-1的位置,那一定不再是你的位置了,它已經(jīng)超過了你可以控制的內(nèi)存范圍,所以它就必然會崩潰。

黑客來襲,手把手帶你深挖區(qū)塊鏈安全漏洞

接下來,演示一下這個EPoD Demo,問題出現(xiàn)在1810版本之前,也包括1810這個版本。

在拍攝視頻時,我用的是官網(wǎng)上面的1810版本,對比過MD5,它是沒有經(jīng)過任何修改的;還需要處于離線環(huán)境,避免遭受外界攻擊,保證所受攻擊都來自本機;運行Geth的LES mode

然后監(jiān)聽從本機發(fā)出來的30303端口,在運行攻擊代碼后, EXP后面的地址(即本機地址)是127.0.0.1,端口是30303,此時的Geth差不多就已經(jīng)崩了。

index out of range,崩的理由就是這樣,一個越界讀。它在處理某一個這種LESMessages的時候,造成了一個越界讀。TCpdump就是我攻擊的錢包,我們把這個漏洞叫EPoD,我只要知道你的IP,發(fā)一個包,Geth就會崩潰,大概就是這樣。

還有一些攻擊,我應該會在9月份舉辦的ISC上講到。

比如說你新成立一個X交易所,然后有一個成立很久的Y交易所,你覺得它的交易量很大,想讓它變小,你就可以去攻擊Y交易所。

一旦你知道了Y交易所的IP以及它同步的node,就可以把信息擴散出去,就會忙死一片了。

像剛剛講的礦池,礦池最基本的一個事情就是算力,每個礦池之間都在競爭算力,那我一旦可以讓某些礦池癱瘓,這個礦池后面的算力也就沒了,這也是非常嚴重的。

但是通常我知道,礦池在使用Geth的同時,也會使用Parity,兩個客戶端會實時進行同步。一旦我們發(fā)現(xiàn)Geth和Parity同時存在問題的時候,就十分有趣了。

還有就是所謂的Boot Node,這個玩過的人可能會知道,一開始同步的時候你需要知道從哪邊開始同步,從哪邊開始就是所謂的Boot Node。

所以,當你癱瘓掉以太坊所有的Boot Node時,新的Geth就沒有辦法去同步,因為它根本沒有辦法啟動。

一旦找到這種涉及公鏈安全而且又是協(xié)議棧的問題,就可能會遭受這些攻擊的影響。

所以,如果Geth低于1810版本就趕緊升級吧。

問題 合約 其實 攻擊 Geth
分享到:

1.TMT觀察網(wǎng)遵循行業(yè)規(guī)范,任何轉載的稿件都會明確標注作者和來源;
2.TMT觀察網(wǎng)的原創(chuàng)文章,請轉載時務必注明文章作者和"來源:TMT觀察網(wǎng)",不尊重原創(chuàng)的行為TMT觀察網(wǎng)或?qū)⒆肪控熑危?br> 3.作者投稿可能會經(jīng)TMT觀察網(wǎng)編輯修改或補充。


專題報道