摘要:隨著智能合約飛速發展,越來越多的項目基於以太坊發行token,鏈上資產的類別和規模呈指數級增長,「虛擬世界」中的數字資產也點燃了黑客們的「熱情」。以太坊區塊鏈被認為是區塊鏈的2.0時代,各種各樣新的數字資產都基於以太坊發行早期代幣甚至實現部分功能,雖然國外區塊鏈社區甚至認為以太坊體量變得太大,已經不可輕易戰勝,但以太坊也是數字貨幣歷史上產生最多安全問題的幣種,從2016年的The DAO事件,到最近的BEC,EDU,SMT的安全漏洞,以太坊的智能合約可以說充滿安全漏洞。大多數的代幣都在自己主網上線前使用以太坊代幣,作為投資者,為了自身資產的安全著想,熟悉智能合約的漏洞概念變得尤為重要。

【黑客利刃砍出的ETH和ETC】

The DAO作為世界上最大的眾籌項目,一度被寄予了厚望,所謂「成也蕭何,敗也蕭何」,智能合約一度被捧上了天,但在這次The DAO事件當中,其遞歸調用(recursive calling)的漏洞卻成為了黑客入侵的大門。此後出現「黑客」現身談攻擊合法性的戲幕,更是讓人大跌眼鏡,這第一次引出了智能合約代碼監管的問題。

2016年6月17日發生了在區塊鏈歷史上留下沉重一筆的攻擊事件。由於其編寫的智能合約存在著重大缺陷,區塊鏈業界最大的眾籌項目TheDAO(被攻擊前 擁有1億美元左右資產)遭到攻擊,導致300多萬以太幣資產被分離出TheDAO 資產池TheDAO編寫的智能合約中有一個splitDAO函數,攻擊者通過此函數中的漏 洞重複利用自己的DAO資產來不斷從TheDAO項目的資產池中分離DAO資產給自己。

攻擊者組合了2個漏洞攻擊,攻擊者利用的第一個漏洞是遞歸調用splitDAO函數,也就是說splitDAO函數被第一次合法調用後會非法的再次調用自己,然後不斷重複這 個自己非法調用自己的過程。這樣的遞歸調用可以使得攻擊者的DAO資產在被清零之 前,數十次的從TheDAO的資產池裡重複分離出來理應被清零的攻擊者的DAO資產。 攻擊者利用的第二個漏洞是DAO資產分離後避免從heDAO資產池中銷毀。正常情況 下,攻擊者的DAO資產被分離後,TheDAO資產池會銷毀這部分DAO資產。但是攻擊 者在遞歸調用結束前把自己的DAO資產轉移到了其他賬戶,這樣就可以避免這部分 DAO資產被銷毀。在利用第一個漏洞進行攻擊完後把安全轉移走的DAO資產再轉回原 賬戶。這樣攻擊者做到了只用2個同樣的賬戶和同樣DAO資產進行了200多次攻擊。

被攻擊後,Vitalik個人支持分叉的提議,也支持軟分叉的開發工作,支持礦工升級客戶端來進行分叉。然而Vitalik也認識到大家對這個提議有激烈的爭論,無論哪一 方的觀點都有強力的反對。因為分叉不需要回滾交易,不會對用戶和交易所造成不便,這更使Vitalik傾向於採取行動的一方。也有許多人,包括在基金會內部,傾向於另外一方反對分叉。Vitalik不會阻止也不會反對另一方在公開場合宣傳他們的觀 點,甚至是遊說礦工來抵制這個分叉。在這件事情上Vitalik會堅決的不與任何站在 相對他的另一方的人爭辯。

簡而言之,他們所做的是更改以太坊區塊鏈來修正DAO,但只有當大部分運行以太坊區塊鏈網路的計算機同意,軟體才能進行更新,擺脫掉漏洞,就好像攻擊從來沒有發生過。這一過程被稱為硬分叉(hard fork),從此以太坊創造了一個平行世界,現在的以太坊其實是分叉出來的「以太坊」並在一年後狂飆突進的漲到了幾百美元,而原來不願意分叉的包含The DAO漏洞的以太坊則成了以太坊經典(ETC)。這一決定引發了強烈的反應,一年後仍然存在爭議,無論是在以太坊社區還是比特幣用戶都堅持區塊鏈的歷史不能被篡改,有些比特幣用戶認為硬分叉在某些方面違反了最基本的價值觀。

【Binance黑客VIA事件】

2018年在 3 月 7 日深夜(北京時間),有不少用戶發現自己幣安賬戶中持有的各種各樣的代幣、數字貨幣被市價即時幣幣交易成了 BTC。據網友反饋,被盜的賬號不在少數,不少人還以為是幣安系統錯誤導致的,還試圖從幣安客服那裡得到解釋。當他們還沒有反應過來的時候,黑客已經開始了他們有組織、有預謀的行動。

黑客啟動了所有盜竊的賬戶的買賣引擎,買賣規則就是賣掉所有山寨幣,用市場價全倉購買VIA。而恰好黑客手裡持有大量VIA,這樣就相當於高價購買了黑客手裡的VIA。於是,VIA的K線出現了驚人的振幅:2分鐘內爆拉了110倍。從交易量和拉昇價格來看,有大約1000個BTC的買單,把VIA的價格從0.000225btc拉到0.025,價格上漲大約110倍。

但是黑客的行動觸發了幣安的預警系統,黑客沒能直接提出高價賣出所得的比特幣。於是他們轉而以超低價格爆砸比特幣現貨的訂單列表,引起其他交易所期貨價格的連鎖反應。於是黑客預先埋伏的巨量空單獲得巨大收益。黑客的攻擊,已經去中心化了。

【數據溢出】

2018年4月22日中午(北京時間),BEC美蜜遭遇黑客的毀滅性攻擊,天量BEC從兩個地址轉出,引發了市場拋售潮。當日,BEC的價值幾乎歸零。

以太坊區塊數據顯示,黑客利用以太坊 ERC-20 智能合約中數據溢出的漏洞,在攻擊中憑空轉出了57,896,044,618,658,100,000,000,000,000,000,000,000,000,000,000,000,000,000,000.792003956564819968 個 BEC。轉出數量遠遠超過了BEC的發行總數70億枚,市場頓時陷入瘋狂拋售,BEC近65億元人民幣的市值也幾乎瞬間歸零。

而攻擊成功的原因,是因為BEC的一段代碼忘記使用safeMath方法,導致系統產生了整數溢出漏洞。據PeckShield 團隊今日凌晨發布的安全報告,黑客利用 in-the-wild(一種從代碼中抓取漏洞的手段)方法,從BEC的程序中抓取到了漏洞,並發動了攻擊。利用這個漏洞,黑客可以通過轉賬的手段生成合約中不存在的代幣, 並將這些無中生有的數字貨幣轉入正常賬戶。這些憑空產生的代幣在使用上與真實代幣沒有差別。

4月25日,SMT爆發了類似的漏洞問題。SMT的智能合約中proxyTransfer函數存在一個經典的整數溢出問題。_fee 和 _value_ 這兩個輸入參數都能被攻擊者控制,如果 _fee + _value 的結果正好為 0(也就是溢出的情況),第206行的檢查將會失效。

這意味著攻擊者不需要任何Token,就可以向一個地址轉入大量的Token(第214行);同時根據第217行的代碼,相當數量的手續費也將發送給 msg.sender。

要理解數據溢出的漏洞,首先要理解任何類型的數值都已自己的表達範圍,計算機中的整數分為兩類:不帶符號位的整數(unsigned integer,也稱為無符號整數),此類整數一定是正整數;帶符號位的整數(signed integer),此類整數可以表示正整數,又可以表示負整數。無符號整數常用於表示地址、索引等正整數,它們可以是8位、16位、32位、64位甚至更多。8個二進位表示的正整數其取值範圍是0~255( -1),16位二進位位表示的正整數其取值範圍是0~65535( -1),32位二進位位表示的正整數其取值範圍是0~ -1。

一個short 型的數值能表示的數值的範圍是:-32768~32767,有負數有正數,這種是有符號數的表達範圍,無符號數的表達範圍是0~65535。你會發現這2種情況下都有65536個數字,這是2的16次方,也就是說short類型的數字是16位比特位表示的。

那麼當一種操作,使得操作結果最終超出了類型能夠表達的範圍,計算機會如何處理呢,如上圖所示,65535加1之後變成了0,加2變成了1,這就是所謂的數值反轉,所謂的溢出就是超出了數值的表達範圍。BEC的數據類型不是無符號的short類型,而是換成了uint256,不管什麼類型,但只要是固定長度都有其表達範圍,

當cnt 與_value的乘法運算超出了uint256的表達範圍,那麼amount得到值會遠遠小於預期的值,就像上面的例子中65535這麼大的數字加上1結果變成了0.那麼當amount的數值很小,但是cnt和_value很大的時候,簽名紅色箭頭表示的檢查就會全部通過,但是,最後轉賬的時候,不是使用的amount,而是使用的_value,於是造成了可以讓黑客攻擊的數據溢出漏洞。

【許可權漏洞與組合套現】

繼BEC和SMT代幣溢出漏洞被曝光後,EDU和BAI代幣也出現重大安全漏洞,不過與之前BEC和SMT的溢出問題不太一樣,這一回是許可權控制產生的漏洞,攻擊者不需要私鑰即可轉走任意地址上的EDU/BAI資產。

此漏洞為遺漏條件判斷的低級漏洞,在 transferFrom 函數中,未校驗 allowed[_from][msg.sender] >= _value 並且函數內 allowed[_from][msg.sender] -= _value; 沒有使用 SafeMath,導致無法拋出異常並回滾交易。通過這個漏洞,攻擊者不需要私鑰即可轉走指定賬戶裏所有的 EDU,並且由於合約沒有 Pause 設計,導致無法止損。漏洞被發現後,產生了大量洗劫行為,攻擊者不需要私鑰即可轉走你賬戶裏所有的 EDU和BAI。智能合約裏的 transferFrom 是批准轉賬流程裏的關鍵函數,這個由於不如 transfer 那麼常用,容易被不小心忽略。這個流程最大的問題是許可權問題。

這一次的EDU攻擊其實也是被迅速發現問題,黑客無法提幣的。但是黑客再次上演了拿著無法提幣的現貨拿來砸穿比特幣價格,再去隔壁交易所做空比特幣的戲碼。黑客花了2個小時,將比特幣砸到 7400 美元,爆掉了近3萬張期貨多單,成功收割期貨和現貨。黑客的攻擊從5月20日開始,當天完成了4筆交易,第一筆交易就是利用Allow函數的漏洞從項目方的地址中偷走了30億枚EDU Token,隨後利用三次交易將Token進行了轉手。

黑客的 Token 得手後,開始往交易所進行充值,並交易了約20億個代幣。火幣 Pro 交易所發現合約漏洞的問題後,隨即暫停了 EDU/BTC 和 EDU/ETH 的交易對,因為全球範圍內只有火幣 Pro 可以交易 EDU Token,所以 EDU Token 的市場交易在此全面停止。按照上面提到的交易數額 20 億枚 EDU Token,黑客的賬戶上已經具備了超過 1000 個以上的比特幣,雖然黑客的賬戶無法進行提幣操作,EDU 已經無法進行交易,但是其賬戶內的比特幣依舊可以進行市場交易。於是黑客發功了和3月7日一樣的方式進行了本地交易所拋售比特幣引發市場波動,同時跨交易所的期貨做空交易。比特幣價格在 23 點 30 分開始暴跌,從 7880 跌到 7400 美元,2 小時內跌幅達到 6%。與此同時,OKEx 的期貨交易中多單開始爆倉,從 23 日 23 點 36 分開始到 24 日 1 點 49 分結束,期間一共爆掉了 28664 張多單,共計 369 枚比特幣。期間 OKEx 期貨市場上做空交易額達到了 1.58 億美元。如果黑客在此期間按照自己砸比特幣價格然後做空的思路,在 OKEx 上下了空單,可以賺到近 2000 萬人民幣離場。

【EKT的安全設計】

由於貨幣需要一個穩定的系統,智能合約設計的越複雜出錯的可能性就越高,所以在早期中本聰認為貨幣系統是不需要圖靈完備的語言的,比特幣之所以不支持智能合約也是覺得貨幣需要極高的穩定性。那麼,如何運行區塊鏈裏保持貨幣穩定的同時又可以開發Dapp呢?有一種比較好的解決辦法就是把Token鏈和DApp鏈分開。

在EKT中Token鏈是一個並行多鏈的結構,多鏈多共識,共享用戶基礎。作為一個DAPP開發者最關心的肯定是三件事:1 開發難度 2 用戶體驗 3 社區生態。那麼Token鏈的設計就是針對不想自己重新開發一條公鏈,但想要發行token和鏈的開發人員。EKT主要面向的對象是開發者,所以在設計token鏈的時候最大的想法是設計一個可以吸引大家都來發幣的平臺(之所以大家過來發幣是因為TPS高,手續費低,可以選擇發鏈用自己的Token做交易費,還可以和其他的鏈共享用戶),這樣可以讓在EKT上開發DAPP的開發者可以獲得更多的用戶資源。

EKT的中心思想是設計一個社區的機制,讓開發者可以輕易的開發一個DAPP,其他的交給EKT來處理,安全問題當然也是EKT在設計之初考慮的重點。即使是早期在以太坊上運行的EKT代幣,我們也認真的考慮到了潛在的安全隱患。

比如這次對很多項目發起攻擊的「transferFrom」函數,EKT token就在 require(balances[_from] >= _value); 下一行增加了require(allowance[_from][msg.sender] >= _value);判斷,確保了合約轉賬不會出現可供黑客利用的漏洞。

我一直堅持的一個觀點就是token不應該是一個智能合約,而應該是一個預先定義好事件的一個「對象」,這個「對象」可以有自己的參數(比如總量、共識機制等等),接受token的地址可以有兩種:普通的用戶地址和合約地址,合約地址收到token之後可以執行非圖靈完備的合約語言,進行簡單的狀態計算和token轉移。EKT把Token鏈和DApp鏈分開,將來在很大程度上能避免之前說到的以太坊合約的漏洞問題。

以上就是我對區塊鏈共識機制的一些思考,和一些在設計EKT的多鏈多共識時的安全考慮,以及Token鏈和DAPP鏈分離的解決思路。

【結語】

公鏈是區塊鏈發展的前提基礎,也是區塊鏈行業未來發展的核心保障。而目前區塊鏈的發展現狀是,底層公鏈的性能尚未發展起來,在其上構建的各類DAPP嚴重受限於性能,各種共識演算法都有不完美之處,安全問題也令人堪憂。由於智能合約一旦上傳,即公開且不可更改,因此大多「區塊鏈2.0」項目有安全性驗證的需求。一些團體也開始致力於應用形式化驗證技術,為智能合約和區塊鏈生態提供安全保護。將智能合約轉化為數學模型,通過邏輯上的推理演算來驗證模型,從而證明智能合約的安全性。

但由於智能合約是「不可變更的」。一旦部署,它們的代碼是不能更改的,導致無法修復任何發現的bug。在潛在的未來裏,整個組織都由智能合約代碼管控,對於適當的安全性需求巨大。過去的黑客如TheDAO或去今年的BEC,SMT,EDU,BAI等漏洞事件提高了開發者們的警惕,可我們還有很長的路要走。

各個公鏈在可擴展性,應用性,共識哲學以及安全建設上的角逐將持續很長一段時間。我們認為既然沒有完美的防止漏洞的方法,把Token鏈和DApp鏈分開,讓Token這個「對象」儘可能的簡潔,是現階段區塊鏈行業裏比較好的解決方案。

參考閱讀:

20180306 3月7日這一夜,黑客耍了所有人

20180423 BEC美蜜現重大漏洞價值幾乎歸零,OKEx暫停BEC提現和交易。

20180423 BEC瞬間歸零:黑客轉移海量幣,黑產大軍開始監控幣漏洞

20180503 智能合約bug是以太坊的缺陷?不用SafeMath就會溢出?別鬧!

20180524 EduCoin(EDU) 智能合約漏洞分析及修復方法

《Ethereum whitepaper》

《EKT whitepaper》


推薦閱讀:
相關文章