當前位置:
首頁 > 最新 > 淺談以太坊智能合約的安全漏洞

淺談以太坊智能合約的安全漏洞

本文作者:Evi1ran

贈送書籍:《Kali Linux高級滲透測試(原書第2版)》

智能合約的安全是區塊鏈安全中的熱議話題,但其實 89% 的智能合約都存在漏洞,本文將淺談以太坊智能合約出現過的一些安全漏洞。


智能合約(Smart contract)是在 1994 年由 Nick Szabo 首次提出的,目的是提供優於傳統合約的安全方法,並減少與合約相關的其他交易成本。智能合約允許在沒有第三方的情況下進行可信交易,這些交易可追蹤且不可逆轉。

簡單的來說,智能合約就是一個「執行合約條款的計算機交易協議」。 我們可以把它想像成一個絕對可信的人,我們讓它臨時保管我們的資產,並且嚴格按照事先交易雙方商定好的規則執行操作。

以太坊是一個開源的區塊鏈底層系統,就像安卓一樣,提供了非常豐富的 API 和介面,讓許多人在上面能夠快速開發出各種區塊鏈應用。目前已經有超過 200 多個應用在以太坊上開發。

以太坊主要使用 Solidity (本文所引用代碼)編寫智能合約,並在微軟雲服務上提供了智能合約工具箱,運行在以太坊區塊鏈上,保證交易公平進行。

舉個簡單的例子:

在傳統的合約中,A 和 B 打賭 10 元今晚會不會下雨,結果 A 贏了,但是 B 耍賴,不願意給 A 10 元,A 沒有辦法,只好做罷。

第二天,B 找到 A 繼續打賭今晚會不會下雨,A 學聰明了,他找了互相都認識的 C 做見證人,自己和 B 分別押了 10 元給 C。晚上 A 抬頭看見天下雨了,心想這次肯定贏了。結果 B 和 A 不在同一個區,A 居住的區下雨了,B 住的卻沒下,C 也不知道該判誰贏。最後一番爭吵後,儘管 B 不滿意,C 覺得在這個城市裡任何地方下雨都算下雨,正準備給 A 錢,卻發現走得太匆忙,忘了帶錢。

所以,傳統的合約會受到各種維度的影響,自動化維度,主客觀維度,成本維度,執行時間維度,違約懲罰維度,適用範圍維度等。

而智能合約便是在打賭之前便考慮並規定好了所有可能出現的情況,事件發生後程序就會按照預先設定好的合約內容自動嚴格執行。因此可以解決傳統的合約出現的問題。


我相信關注區塊鏈的都知道 The DAO 攻擊事件,

事件回顧:

2016 年 5 月,The DAO 正式發布。該項目使用了由德國以太坊創業公司 Slock.it 編寫的開源代碼。The DAO 的設計職能類似於一項風險投資基金,可以授權為以太坊項目提供資金。這個眾籌超過 1.5 億美元的分散式自治組織,遭受到了黑客利用遞歸調用以太坊發送漏洞的攻擊,引發了廣泛的市場拋售。

那麼黑客到底是怎麼利用這個漏洞的呢?我們先了解下智能合約 fallback 函數漏洞利用的原理。

當智能合約執行時,如果沒有找到指定的函數,或者根本就沒有指定哪個函數(如發送 ether)時,就會調用 fallback 函數。

我們先來看一下 和 的區別。兩者都是向某個地址發送以太幣,不同的是這兩個調用的 gaslimit 不一樣。 基於 (相當於 ),而 基於當前剩餘的所有 。

所以當你通過 發送 ether 時,沒有指定哪個函數,fallback 函數就會被調用,並附帶上當前剩餘的所有 gas。

根據這一點,黑客可以通過 fallback 函數構造出一個遞歸調用直到 trasnfer 把所有幣轉完。

function() {

addressaddr=0x6c8f2a135f6ed072de4503bd7c4999a1a17f824b;

if(COUNT

addr.call(「withdrawBalance」);

COUNT++;

}

}

在這段 fallback 代碼中,當計數器小於 100 時,遞歸調用 withdrawBalance 函數。在這種情況下:

將被調用 100 次,從而取走 100 * 10 ether。

簡單地來說,Call.value() 存在漏洞,可以被黑客構造 while 循環漏洞直到 trasnfer 把所有幣轉完。

因為智能合約的開放性,也存在著 token 信息泄露漏洞。


在 The DAO 攻擊事件中,黑客就是通過上文所說的原理利用 fallback 函數存在的漏洞進行遞歸調用攻擊。黑客分析了 DAO.sol,並且注意到了 splitDAO 功能,這個功能最後會更新用戶的餘額和總額,所以如果我們能在它訪問 splitDAO 之前再調用這項功能,我們就可以無限遞歸調用來 transfer 我們想要數量的代幣。

漏洞代碼(DAO.sol):

functionsplitDAO(

uint_proposalID,

address_newCurator)noEtheronlyTokenholdersreturns(bool_success){

uintfundsToBeMoved=

(balances[msg.sender]*p.splitData[].splitBalance)/

p.splitData[].totalSupply;

if(p.splitData[].newDAO.createTokenProxy.value(fundsToBeMoved)(msg.sender)

==false)throw;

withdrawRewardFor(msg.sender);

totalSupply-=balances[msg.sender];

balances[msg.sender]=;

paidOut[msg.sender]=;

returntrue;

}

當合約執行到:

會進入相應的函數:

functionwithdrawRewardFor(address_account)

noEtherinternalreturns(bool_success){

if(!rewardAccount.payOut(_account,reward))//漏洞代碼

throw;

}

函數定義如下:

functionpayOut(address_recipient,uint_amount)returns(bool){

if(_recipient.call.value(_amount))//漏洞代碼

PayOut(_recipient,_amount);

returntrue;

}else{

returnfalse;

}

}

黑客通過將下面的代碼調用多次,以轉移多份以太幣:

智能合約一旦發布便不能修改,只能通過硬分叉解決。

The DAO 已經丟失了 360 萬以太幣,這些以太幣在被分離到一個獨立的團組 child DAO 後,目前正被保存在一個獨立的錢包內。 在攻擊事件發生之後,Slock.it 制定了一個解決方案並把它上傳到了 GitHub:

https://github.com/slockit/smart-contract/blob/master/DAOSecurity.sol


事件回顧:

2017 年 7 月 19 日,用作 Parity Wallet 的多重簽名錢包(「multi-sig」)代碼中存在的漏洞被黑客所利用。持有 ETH 大額餘額的三個錢包賬戶已被入侵,餘額轉入攻擊者持有的賬戶。攻擊者從三個高安全的多重簽名合約中竊取到超過 15 萬以太坊(約 3000 萬美元)。原始報告:

https://paritytech.io/the-multi-sig-hack-a-postmortem/

我們可以看到黑客的資金賬戶:

https://etherscan.io/address/0xb3764761e297d6f121e79c32a65829cd1ddb4d32#internaltx

一共盜取了 153,037 個 ETH。

漏洞代碼:

// constructor - just pass on the owner array to the multiowned and

// the limit to daylimit

functioninitWallet(address[]_owners,uint_required,uint_daylimit) {

initDaylimit(_daylimit);

initMultiowned(_owners,_required);

}

源碼地址:

https://github.com/paritytech/parity/blob/4d08e7b0aec46443bf26547b17d10cb302672835/js/src/contracts/snippets/enhanced-wallet.sol

當轉賬交易執行到 的分支時,因為該函數能無條件地調用合約內的任何一個函數,黑客通過調用 函數,初始化錢包,重新調用了 函數。將 直接分配給 library 後,可以把這個 library 轉換為一個常規的多重簽名錢包。再取得 許可權後,黑客還可以調用 指令,導致所有依賴於第三方 party 庫的錢包癱瘓。


近日,慢霧安全團隊觀測到一起自動化盜幣的攻擊行為,攻擊者利用以太坊節點 Geth/Parity RPC API 鑒權缺陷,惡意調用 盜取代幣,持續時間長達兩年,單被盜的且還未轉出的以太幣價值就高達現價 2 千萬美金,還有代幣種類 164 種,總價值難以估計(很多代幣還未上交易所正式發行)。 原始報告

黑客通過全球掃描 8545 埠(HTTP JSON RPC API)、8546 埠(WebSocket JSON RPC API)等開放的以太坊節點,發送 、、 遍歷區塊高度、錢包地址及餘額並不斷重複調用 嘗試將餘額轉賬到攻擊者的錢包。當正好碰上節點用戶對自己的錢包執行 時,在 duration 期間內無需再次輸入密碼為交易簽名,此時攻擊者的 調用將被正確執行,餘額就進入攻擊者的錢包里了。

函數將使用密碼從本地的 keystore 里提取 private key 並存儲在內存中,函數第三個參數 duration 表示解密後 private key 在內存中保存的時間,默認是 300 秒;如果設置為 0,則表示永久存留在內存,直至 Geth/Parity 退出。詳見:

https://github.com/ethereum/go-ethereum/wiki/Management-APIs#personal_unlockaccount


事件回顧:

BEC 智能合約批量轉賬函數中有一行代碼存在 bug,導致了溢出漏洞。被黑客所利用,出現一筆高達 57,896,044,618,658,100,000,000,000,000,000,000,000,000,000,000,000,000,000,000 的 BEC 代幣轉賬。瞬間套現拋售大額 BEC,6 億在瞬間歸零。

交易地址:

https://etherscan.io/tx/0xad89ff16fd1ebe3a0a7cf4ed282302c06626c1af33221ebe0d3a470aba4a660f

漏洞代碼:

functionbatchTransfer(address[]_receivers,uint256_value)publicwhenNotPausedreturns(bool) {

uintcnt=_receivers.length;

uint256amount=uint256(cnt)*_value;

require(cnt>&&cnt

require(_value>&&balances[msg.sender]>=amount);

balances[msg.sender]=balances[msg.sender].sub(amount);

for(uinti=;i

balances[_receivers[i]]=balances[_receivers[i]].add(_value);

Transfer(msg.sender,_receivers[i],_value);

}

returntrue;

}

我們看到這一行代碼:

這行代碼沒有對 amount 做溢出的檢測, 把 cnt 轉成了 uint256 類型,它的取值範圍是 0 到 2 的 256 次方 -1 , 傳入的 _value 值在第一張圖中是 8000000000000000000000000000000000000000000000000000000000000000,而轉賬地址有兩個,所以 cnt 為 2, amout 已經超過了最大值,從而導致了溢出。

合約地址:

其實開發者已經考慮了溢出問題,除了 amount 的計算外, 其他轉賬都用了 safeMath 的方法(sub,add) 。唯獨 amount 的計算用了 require 而不是 assert 來驗證。兩者都是干同一件事,他們有什麼區別呢?原來 assert 會讓程序的 gas limit 消耗完畢,而 require 只會消耗掉當前執行的gas。正式這一行代碼,蒸發了 ¥6,447,277,680 人民幣!


如上所說,本文只列舉了一部分以太坊智能合約中出現過的安全漏洞。

在倫敦大學學院 (University College London,UCL) 計算機科學系副教授伊利亞·謝爾蓋最新的研究論文 《Finding The Greedy , Prodigal , and Suicidal Contractsat Scale》 中,通過對將近 100 萬份智能合約進行每份合約 10 秒分析時間的分析後發現,這其中有 34200 份智能合約很容易受到黑客攻擊。同時他們又對 3759 份智能合約抽樣調查,在這之中,3686 份智能合約有 89% 的概率含有漏洞。

除此之外,許多交易所也沒有設置過濾器,可以通過簡單的字元串拼接構造 POC 取走交易所虛擬賬戶中的所有代幣。


談談區塊鏈:以太坊智能合約的安全漏洞

http://geek.csdn.net/news/detail/139516

關於昨天蔡文勝的 BEC 智能合約出現漏洞,又一個要歸零的幣

https://www.v2ex.com/t/448992

以太坊生態缺陷導致的一起億級代幣盜竊大案


喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 全球大搜羅 的精彩文章:

從《時間規劃局》到《北京摺疊》
傳承國粹,追逐潮流——新中式風格

TAG:全球大搜羅 |