區塊鏈安全 DAO攻擊事件解析

2021-08-20 14:27:39 字數 3372 閱讀 3349

0x00 前言

最近關注了一下區塊鏈方面的安全,因此翻出來之前的dao攻擊事件研究了一番,形成此文。

之後可能還會發一些其他的安全分析文章。

0x00 基礎知識

1.跨合約呼叫

智慧型合約之間的呼叫本質上是外部呼叫,可以使用message call或者建立智慧型合約物件的形式進行呼叫。

(1)使用message call

比如合約1呼叫合約2的某個方法:

bytes4 methodid = bytes4(keccak256("increaseage(string,uint256)"));  

return addr.call(methodid,"jack", 1);

(2)還原智慧型合約物件 如果已知合約的位址,可以通過如下方式獲取到合約物件:

contract1 c = contract1(addressofcontract1) ;  

c.foo() ; //跨合約呼叫

2.智慧型合約傳送eth

我們可以在智慧型合約中用**向某個位址(這個位址可以是人,也可以是智慧型合約)傳送以太幣,比較常見的兩個方式是:

(1)呼叫send函式

比如:msg.sender.send(100)

(2)使用message call

msg.sender.call.value(100)()

這兩個方式不同的是傳送的gas數量,gas就是執行opcode需要花費的一種幣,稱作為gas也特別形象。當呼叫send方法時,只會傳送一部分gas,準確地來講,是2300gas,一旦gas耗盡就可能丟擲異常。

而使用message call的時候,則是傳送全部的gas,執行完之後剩餘的gas會退還給發起呼叫的合約。

3.fallback函式

智慧型合約中可以有唯一的乙個未命名函式,稱為fallback函式。該函式不能有實參,不能返回任何值。如果其他函式都不能匹配給定的函式識別符號,則執行fallback函式。

當合約接收到以太幣但是不呼叫任何函式的時候,就會執行fallback函式。如果乙個合約接收了以太幣但是內部沒有fallback函式,那麼就會丟擲異常,然後將以太幣退還給傳送方。

下面就是乙個fallback函式的**示例:

contract sample  

}

一般單純使用message call或者send函式傳送以太幣給合約的時候,沒有指明呼叫合約的某個方法,這種情況下就會呼叫合約的fallback函式。

0x01 攻擊事件還原

我們先用簡單的模擬**來了解下整個攻擊過程。

首先是存在漏洞的智慧型合約**,bank:

使用者可以通過addtobalance方法存入一定量的以太幣到這個智慧型合約,通過withdrawbalance方法可以提現以太坊,通過getuserbalance可以獲取到賬戶餘額。

注意到這裡是通過message call的方式來傳送以太幣,所以在呼叫sender的fallback函式的時候我們就會有充足的gas來進行迴圈呼叫。如果是send的方式,gas只有2300,稍微一操作就會耗盡gas丟擲異常,是不夠用來進行巢狀呼叫的。以下是不同操作所需要的gas數量:

出問題的是withdrawbalance方法,特別是在修改儲存在區塊鏈的balances的**是放在了傳送以太幣之後。 攻擊**如下:

這裡的deposit函式是往bank合約中傳送10wei。withdraw是通過呼叫bank合約的withdrawbalance函式把以太幣提取出來。注意看這裡的fallback函式,這裡迴圈呼叫了兩次bank合約的withdrawbalance方法。

攻擊的過程如下:

(1)假設bank合約中有100wei,攻擊者attack合約中有10wei

(2)attack合約先呼叫deposit方法向bank合約傳送10wei

(3)之後attack合約呼叫withdraw方法,從而呼叫了bank的withdrawbalance方法。

(4)bank的withdrawbalance方法傳送給了attack合約10wei

(5)attack收到10wei之後,又會觸發呼叫fallback函式

(6)這時,fallback函式又呼叫了兩次bank合約的withdrawbalance,從而轉走了20wei

(7)之後bank合約才修改attack合約的balance,將其置為0

通過上面的步驟,攻擊者實際上從bank合約轉走了30wei,bank則損失了20wei,如果攻擊者多巢狀呼叫幾次withdrawbalance,完全可以將bank合約中的以太幣全部轉走。

0x02 復現過程

給bank合約100wei,給attack合約10wei。

(1)部署bank,分配100wei

(2)部署attack

分配給attack 10wei。

(3)呼叫attack合約的deposit方法

(4)呼叫attack合約的withdraw方法

(5)檢視attack合約的餘額,變成了30wei,即竊取了20wei

0x03 dao攻擊事件**分析

在dao原始碼中,有withdrawrewardfor函式:

function withdrawrewardfor(address _account) noether internal returns (bool _success)
這裡呼叫了payout函式進行付款。

function payout(address _recipient, uint _amount) returns (bool)  else
而payout中直接使用的是message call的方式傳送以太幣,從而導致了巢狀漏洞。

0x04 總結

在編寫智慧型合約進行以太幣傳送的時候,要使用send或者transfer,不要使用message call的方式,而send其實還是有些小問題,以後有時間再分析。dao事件直接導致了以太坊硬分叉,分為eth和etc。可見,區塊鏈領域的安全不容忽視,因為其修復難度和所造成的影響都很高,畢竟是和錢打交道。

區塊鏈史上著名安全事件

著名安全事件 1.dao事件。dao發布了乙個split dao的智慧型合約,支援使用者從父dao賬戶向子dao賬戶轉賬。其邏輯是完成轉賬後,把使用者在父dao的eth扣除。但是,轉賬確認是需要時間的,在這一段時間裡,黑客發起了200多筆重複轉賬並成功,從中獲利5000多萬美金。2.bitfinex...

區塊鏈安全解釋

鏈客,有問必答!科技專家 企業家謝爾曼 李 sherman lee 最近表示 區塊鏈本身可能是不可信 不可改變和清廉的,但如果我們忽略其中存在的漏洞,它們就相當於使價值數十億美元鎖在有問題的保險箱裡。區塊鏈因其複雜的數 算而自吹自擂為 廉潔 但在現實中,如果在實際場景中實現,生成的軟體可能會有可能導...

能源區塊鏈研究 區塊鏈與核電安全

區塊鏈與核電安全 位元幣因其能夠取代法定貨幣,打破傳統銀行系統的束縛,而廣為人知。然而這並不是位元幣的唯一優勢。從總體上看,位元幣是乙個基於創新技術 區塊鏈 的系統,如今,這一技術的應用範圍越來越廣。最近,阿根廷將位元幣區塊鏈應用於核電站維護,為該技術的應用提供了新範例。什麼是區塊鏈?區塊鏈是一項技...