從以太坊"MorphToken事件"看智慧合約建構函式大小寫編碼錯誤漏洞

FLy_鵬程萬里發表於2018-08-24

一、漏洞概述

以太坊智慧合約的含義就是一組程式碼(函式)和資料(合約的狀態),它們位於以太坊區塊鏈的一個特定地址上。智慧合約一般使用solidity語言編寫。

Morpheus Network與世界上一些大型航運、海關和銀行公司協商,通過利用區塊鏈的智慧合約技術建立一個全面服務的、全球性的、自動化的、開放的供應鏈平臺和一個整合的加密貨幣支付系統 ,釋出基於以太坊的 MorphToken

2018年6月22日,Morpheus Network 發公告稱將釋出新的智慧合約,以更新目前含有漏洞的合約程式碼。新的Token名稱為MRPH,新舊Token以1:1兌換。

隨後,知道創宇404區塊鏈安全研究團隊開始漏洞應急,通過分析MorphToken合約程式碼和交易歷史,確定該漏洞是由於大小寫編碼問題,錯誤的將Owned合約的建構函式Owned的首字母小寫,使之成為了一個普通函式owned,任何以太坊賬戶均可呼叫該函式奪取合約的所有權,進一步實現盜幣等系列非法操作。隨即我們釋出了相關應急報告,同時我們也注意到BCSEC安全團隊釋出了相關的分析文件

在後續的研究中,我們發現早在2017年8月29日,Github上就有人提到了這種因建構函式缺失導致的合約安全漏洞問題。該漏洞目前影響包括MorphToken、B2X、DoubleOrNothingImpl等多個智慧合約。

二、漏洞原理

在MorphToken的合約程式碼裡:https://etherscan.io/address/0x2ef27bf41236bd859a95209e17a43fbd26851f92#code 可以明顯的看到相關大小寫編寫錯誤:

以太坊智慧合約中的建構函式主要用於初始化,如:確定合約的所有者,並且只會在合約部署時執行。在小於0.4.22版本的solidify編譯器語法要求中,建構函式的名稱應該和合約名稱保持一致。如果程式設計師在編寫合約時將建構函式名稱寫錯,那麼原本的建構函式將成為任何人都可以呼叫的普通函式。漏洞示例程式碼及在Remix-ide中的復現結果如下:

0x01 漏洞合約部署

下圖中,Bank合約繼承自Owned合約。在Owned合約中,由於錯誤的編碼,將建構函式名稱寫錯,owned函式成為了一個普通函式。可以看到,Bank合約部署後,由於缺少建構函式,初始化時owner為0x0000000000000000000000000000000000000000。

0x02 漏洞現場還原

任何以太坊賬戶都可以呼叫Bank合約繼承自Owned合約的owned函式,更改Bank合約的owner變數,從而使合約所有權發生轉移。

如下如所示,0x14723a09acff6d2a60dcdf7aa4aff308fddc160c這個賬戶呼叫了Bank合約的owned函式後,可以看到Bank合約的owner變成了0x14723a09acff6d2a60dcdf7aa4aff308fddc160c。同理,攻擊者也可以利用這個漏洞提權,實施一系列惡意操作。

三、漏洞影響評估

我們使用內部的以太坊智慧合約審計系統對以太坊主鏈上所有30000+公開智慧合約進行了自動化審計,確認受該大小寫編碼漏洞影響的共計16個,以下為統計結果:

(受漏洞影響程度取決於合約的邏輯,具體程式碼審計結果可聯絡知道創宇404區塊鏈安全研究團隊)

理論上在合約部署後,由於編碼錯誤引起的建構函式缺失,owner預設值會變為0x0000000000000000000000000000000000000000,這樣合約中涉及到owner的函式呼叫都會異常,合約所有者應該能及時發現漏洞才是。然而MorphToken這種市值幾百萬美金的代幣,因為合約存在這個編碼漏洞而被盜幣。通過分析Morph Token原始碼,我們得到了答案。MorphToken繼承了Owned合約,但是自己實現了建構函式。就是說,是父合約向外留了一個“後門”。

另一種情況,如果合約中沒有涉及owner許可權的函式呼叫,那麼即使攻擊者盜取了合約所有權,也沒有任何用處。上表B2X合約中就是這種情況。

總體來說,受漏洞影響的合約數量不多,屬於被MorphToken帶著“火”了一把的漏洞。

事實上,很多安全漏洞都來源於程式設計師的粗心編碼,智慧合約這種部署後即不可更改的更應加強程式碼審計。

四、防護方案

1、0.4.22版本以後的solidity編譯器引入了constructors關鍵字,以替代低版本的將合約名作為建構函式名的語法,從而避免程式設計師編碼錯誤。強烈建議採用最新版本編譯器。

2、技術業務諮詢

知道創宇404區塊鏈安全研究團隊:http://www.scanv.com/lca/index.html
聯絡電話:(086) 136 8133 5016(沈經理,工作日:10:00-18:00)

相關文章