成都鏈安智慧合約安全實踐(二)| 練就“火眼金睛”,真假建構函式一眼看清

買賣虛擬貨幣

引子:“真行者珞珈山訴苦,假猴王水簾洞謄文。” ——《西遊記·第五十八回》

在《西遊記》中,六耳獼猴冒充猴王孫悟空,以假亂真,騙過了唐僧,騙過了眾神,縱使是照妖鏡也分不出真假。現在,智慧合約遇上了“六耳獼猴”,又會擦出怎樣的火花?

在智慧合約中,建構函式負責一些資料的初始化工作,owner值一般也會放在建構函式中進行初始化。

owner是智慧合約擁有者的稱呼,也常被用來作為該合約的超級管理員。對代幣合約來說,owner可能被分配的許可權有:鑄造/銷燬代幣、凍結代幣等。

如果開發者以錯誤的語法建立“建構函式”,造成建構函式缺失,致使“六耳獼猴”以假亂真,瞞過了開發者,最後使得攻擊者成為合約的擁有者(owner),那麼攻擊者便可依賴owner的許可權,對代幣進行增發或銷燬等操作,進而可能造成整個代幣的崩盤。

一、建構函式簡介

在Solidity語言中,當函式名和合約名相同時,此函式就是合約的建構函式,在合約物件建立時,會先呼叫建構函式對相關的資料進行初始化。

以太坊Solidity 0.4.22版本中引入了關鍵字constructor,新的建構函式宣告形式:constructor() public { },引入的目的是用以替代低版本中將合約名作為建構函式名的語法形式,從而避免開發者筆誤造成建構函式命名錯誤的問題。

引入的這個關鍵字看似平淡無奇,實則意蘊深刻,且聽我慢慢道來。

二、Fal1out“以假亂真?”

– 漏洞分析

下面以ethernaut靶場的Fallout題目為例進行分析。

一眼看去,這似乎是一個正常沒有漏洞的合約程式碼,但經過仔細觀察發現,該合約存在一個致命錯誤——建構函式名稱與合約名稱不一致,Fallout合約的建構函式被寫錯成了Fal1out(字母l和數字1的差異)。

這樣的錯誤使其成為了一個被public修飾的普通函式,失去了建構函式僅在合約部署時被呼叫的特性,使得任何人都可以呼叫。該題目原始碼如下圖所示:

圖 1

在Fal1out函式中直接指定了函式呼叫者的地址即為owner,所以只需要呼叫Fal1out函式即可實現對合約owner的更改。

如下圖所示:

圖 2

“假猴王”Fal1out想借著一些字型型別的相似字元的視覺差異混淆視聽,可最終還是沒能逃過我們的“火眼金睛”。

三、前車之覆:

MorphToken事件分析

在過去也曾發生過類似的安全事件,包含著假建構函式的合約被成功釋出到主鏈上,其中比較出名的是“MorphToken事件”,其因為一個看似很小的問題而造成了數千萬市值的代幣被增發。

合約程式碼地址:https://etherscan.io/address/0x2ef27bf41236bd859a95209e17a43fbd26851f92#code

在Owned合約中,由於首字母大小寫的錯誤,導致本該成為建構函式的Owned成為了普通函式owned,且被public修飾,可供任何人呼叫。

如下圖所示:

圖 3

MorphToken合約繼承了Owned合約,並在自己的建構函式內進行了owner的初始化,但是父合約Owned的owned函式是可供任何人呼叫的,攻擊者便可透過呼叫owned函式更改合約的所有者owner。

owner的初始化程式碼如下圖所示:

圖 4

由上述可知,任何人都可以透過呼叫合約的owned函式,成為合約的擁有者(owner)。

如下圖所示:

圖 5

失之毫釐,差之千里,一個小小的字母錯誤,卻導致了合約的代幣的崩盤。代幣也被惡意增發。

如下圖所示:

圖 6

四、後車之鑑:

開發者應如何正確使用建構函式

建議更換Solidity 0.4.22及以上版本,並使用正確的constructor()語法。

如下圖所示:

圖 7

切記:constructor()前並無function,function constructor() public { }為錯誤的建構函式形式。

如果要使用低於0.4.22的版本,則一定要著重檢查函式名是否和合約名一致。

如下圖所示:

圖 8

五、安全建議

在智慧合約中因開發者粗心,而造成安全漏洞的事件層出不窮,“千里之堤,潰於蟻穴”,成都鏈安-安全實驗室在此給出如下建議:

1、開發者在編寫智慧合約敏感函式(如建構函式、回退函式fallback)時,應嚴格按照官方要求的程式碼書寫規範,注意不要出現字元錯誤等情況。

2、在某些情況下,編譯器會對constructor的錯誤使用發出警告,開發者應予以正確對待,不可認為其只是警告資訊而忽略不處理。

3、在合約正式上線前一定要找專業可信的機構做好合約程式碼的審計工作。

免責聲明:

  1. 本文版權歸原作者所有,僅代表作者本人觀點,不代表鏈報觀點或立場。
  2. 如發現文章、圖片等侵權行爲,侵權責任將由作者本人承擔。
  3. 鏈報僅提供相關項目信息,不構成任何投資建議

推荐阅读

;