事件回顧
根據目前網上公開資料,包括博客、代碼記錄等,我們對本次安全事件的技術過程進行一個簡要梳理:
北京時間5月28日 360公司Vulcan(伏爾甘)團隊聯系主導EOSIO開發的Daniel Larimer(即bytemaster,以下簡稱BM)并報告了發現的高危安全漏洞情況
5月28日 BM在github的eos項目上新建了一個需要跟蹤的問題(Issue)。同天,該問題所描述的bug被修復;該問題關閉
5月29日中午,360公司在其官方微信公眾號上公布了區塊鏈平臺EOSIO的高危安全漏洞的消息
同天晚些時候,360公司在其公司博客“奇虎360技術博客”上公布了該漏洞的細節內容
技術分析
我們首先從奇虎360技術博客的報告“EOS節點遠程代碼執行漏洞 — EOS智能合約WASM函數表數組越界”[1]中來查看本次漏洞的詳細技術內容。
根據報告所述,在修復該漏洞的提交
ea89dce21d13d41a22b3512a27be97b4be9df755之前的代碼版本上,我們可以看到在libraries/chain/webassembly/binaryen.cpp文件的76行,有assert用于檢查變量取值情況。但assert一般僅適用于程序編譯構建的Debug模式,對于正式發布的Release模式通常并不起作用,因此相當于沒有做檢查,導致78行對數組的訪問存在隱患。
因此在發現該漏洞后,開發團隊已將assert改為可正常調用的名為FC_ASSERT的宏定義。
知道了問題所在后,我們再來看一下編寫EOSIO所使用的C++程序的內存結構及語言特性。
C++程序的內存區域包括棧區、堆區、自由存儲區、靜態全局存儲區、常量區及代碼區等。每個區域均有其獨特的作用。同時,C/C++允許程序員通過指針等方式,對內存進行極為自主的控制及使用,并不強制檢查數組邊界等條件。因為包括內存管理在內的種種極為靈活、可控制底層的語言特性,C/C++憑借其高性能被廣泛使用于對程序執行速度有嚴格要求的工業界。但也正是因為這種靈活性,C/C++程序常會因為內存管理的復雜性而出現內存泄露、宕機或內存越界等問題。這點在大型工程上尤其常見。
圖 1 內存問題引起程序崩潰示例
原因在于,C++程序指針訪問到相應內存區域,即有可能對其進行相應的操作,所以如果控制不當,訪問到原本的“界限”之外,就會產生越界的問題:如果訪問到數據區域,則可能會引起程序崩潰或讀取、修改到原本不應訪問到的信息;如果訪問到代碼區域,則可能注入或改變原有正常代碼。這就是緩沖區溢出的基本原理。
作為計算機及互聯網上十分常見且潛在影響巨大的攻擊手段,利用緩沖區溢出進行攻擊有記錄的最早一次是發生在1988年的Morris蠕蟲攻擊。據估計,它一經出現便影響了互聯網上10%的計算機,造成約10萬至100萬美元的損失。從其首次出現到今天的30年間,很多著名的攻擊事件都采取了緩沖區溢出的方式進行,其影響也隨著互聯網的發展而擴大。
回到本次EOSIO的這個漏洞,根據360的報告我們可以看到:當檢查代碼失效后,如果offset變量被任意設置一個地址,例如0xfffffff,則會引起segmentation fault的錯誤而導致程序崩潰;而如果對合約進行精心設計,攻擊者可通過對內存越界寫入的方式來執行惡意代碼,正如360報告中附加的視頻所示。
同時,如果能將風險控制在單機范圍內,那對全局來說影響還是相對可接受的。但正是由于惡意代碼可以是一個區塊鏈上的合約,因此EOSIO將合約打包成區塊后會在整個網絡中傳播,使得所有節點均可被此惡意代碼控制,即整個網絡都受到致命影響。
構建區塊鏈安全生態
從本次漏洞結合近期以太坊ERC20漏洞等安全事件,我們應更加認識到《【火線視點3】從ERC20漏洞事件看區塊鏈安全生態建設》中的觀點:區塊鏈安全生態不僅僅需要項目團隊、開發人員,更需要多方的通力合作。下面主要從項目團隊內控、項目生態激勵和投資者自我防范這三個方面去探討區塊鏈安全生態的建設。
1 完善代碼安全審查機制
回顧ERC20漏洞事件和EOSIO的緩沖區溢出事件,他們完全都可以通過有效的代碼安全審查機制來避免。以ERC20漏洞為例,經過核查,使用ERC20協議的項目竟然有20余個都存在類似的問題。
瞬息萬變的幣圈確實發展的太快,每一個人都是飛奔著前進,都趕著寫白皮書、趕著募資、趕著上項目,自然而然就很少有人沉下心來好好做測試,好好做安全審查,導致漏洞頻出、安全事件頻發。
區塊鏈作為一個分布式的去中心化系統,代碼一旦部署將很難更新,需通過硬分叉或者軟分叉來對代碼進行升級,成本不可謂不高。THE DAO事件則直接將以太坊分裂成為ETH和ETC,是對以太坊生態的重大破壞。所以在項目發布之前,充足的測試和代碼審核變得十分關鍵和必要。比如多人代碼審核、內部測評小組、外部專家評測等。
多人代碼審核
由于一個人的能力和認知總是有限的,所以對于同一段代碼,不同的人將會發現不同的問題,多人代碼審核機制能使得代碼的BUG率和漏洞率大大降低。這種方式也是軟件行業降低錯誤率最為通用和有效的方式之一。
內部測評小組
項目組建立內部安全測評小組,梳理業界常見的安全問題清單,并逐一對發布的項目進行安全審計,通過簡單的梳理和測評便能將常見的基本漏洞一掃而空,大大增加了系統的可靠性。
外部專家評測
對于某些新型的,特殊性的漏洞,項目組可以借助于例如第三方評測機構等外部安全專家的幫助進行梳理和測評,爭取在項目發布前將安全隱患降到最低程度。
2 發展白帽黑客激勵機制
世界無非兩極,一陰一陽、一黑一白、一正一邪,有黑客肆意破壞,就有白帽黑客維護世界正義。隨著各類數字資產的市值越來越高,黑客們從中套取的收益也越來越客觀,相比之下,白帽黑客們卻窮酸的多。
這種巨大的收入差導致越來越多人加入的黑客的陣營,而白帽黑客們則為數稀少。通過激勵白帽黑客來抑制或者是平衡黑客越來越肆無忌憚的破壞行為或許將成為一種有效的手段。
那么如何激勵白帽黑客們為平臺做出貢獻呢?我想主要可以從兩方面入手,一是物質激勵,二是精神激勵。
物質激勵
對于發行通證的公鏈來說,最實在的物質激勵自然就是通證。它既是區塊鏈平臺的價值載體,也是平臺生態治理的重要手段。比如COSMOS,為了鼓勵發現并及時報告缺陷,Cosmos Hub允許黑客通過ReportHackTx 交易來“邀功”,主要就是說明,“這個節點已被攻擊,請將獎金發到這個地址”。黑客可以收到擊中資產的5%作為賞金。
除此之外我們也可以通過設立黑客獎金池、黑客基金或者項目特別顧問等方式來激勵白帽黑客主動挖掘漏洞,幫助平臺持久安全地運行。
精神激勵
除了物質獎勵,對于Hacker這一非常另類、有性格的群體來說,精神上的激勵或許是更持久有效的方式。對于每一個為平臺或者項目作出貢獻的黑客來說,項目組、基金會或者社區都應將給與其相應的榮譽獎勵。可以是排行榜、貢獻值亦或是某種稀缺頭銜等等,使其不僅能被社區其它成員知曉,更能明顯區別于普通會員,增強其在社區的存在感、參與感和榮譽感。更可考慮用較為“極客”的方式進行精神激勵,例如將白帽黑客對平臺、社區的貢獻記錄在區塊鏈上,形成更有針對性的生態系統良性循環。