以太坊智能合约安全 Dasp Top10
譯者:愛上平頂?
來源:慢霧區(qū)
原文鏈接:https://www.dasp.co/
這是分布式應(yīng)?安全項?(或DASP)2018 年排名前10的漏洞第?次迭代
該項?是NCC集團的?項舉措。這是?個開放的合作項?,致?于發(fā)現(xiàn)安全社區(qū)內(nèi)的智能合約漏洞。要參與,請加?github??。
1.重?漏洞
也被稱為 或與空?競爭,遞歸調(diào)?漏洞,未知調(diào)?
這種漏洞在很多時候被很多不同的?忽略:審閱者傾向于?次?個地審查函數(shù),并且假定保護?例程的調(diào)?將安全并按預(yù)期運?。 Phil Daian
重?攻擊,可能是最著名的以太坊漏洞,第?次被發(fā)現(xiàn)時,每個?都感到驚訝。它在數(shù)百萬美元的搶劫案中?次亮相,導(dǎo)致了以太坊的分叉。當初始執(zhí)?完成之前,外部合同調(diào)?被允許對調(diào)?合同進?新的調(diào)?時,就會發(fā)?重新進?。對于函數(shù)來說,這意味著合同狀態(tài)可能會在執(zhí)?過程中因為調(diào)?不可信合同或使?具有外部地址的低級函數(shù)?發(fā)?變化。
損失:估計為350萬ETH(當時約為5000萬美元)
發(fā)現(xiàn)時間表:
2016年6?5??Christian Reitwiessner發(fā)現(xiàn)了?個堅定的反模式
2016年6?9??更多以太坊攻擊:Race-To-Empty是真正的交易(vessenes.com)
2016年6?12??在以太坊智能合約'遞歸調(diào)?'錯誤發(fā)現(xiàn)(blog.slock.it)之后,沒有DAO資??臨?險。
2016年6?17??我認為TheDAO現(xiàn)在正在流失(reddit.com)
2016年8?24??DAO的歷史和經(jīng)驗教訓(xùn)(blog.sock.it)
真實世界影響:
- DAO
示例:
代碼示例:
以下函數(shù)包含易受重?攻擊影響的函數(shù)。當?shù)图墑ecall()函數(shù)向msg.sender地址發(fā)送ether時,它變得易受攻擊; 如果地址是智能合約,則付款將觸發(fā)其備?功能以及剩余的交易?體:
function withdraw(uint _amount) { require(balances[msg.sender] >= _amount);msg.sender.call.value(_amount)();balances[msg.sender] -= _amount; }其他資源:
- DAO智能合約
- 分析DAO的利?
- 簡單的DAO代碼示例
- 重?代碼示例
- 有?試圖利?我們的智能合約中的?個缺陷,盜取它的?切
2.訪問控制
通過調(diào)?initWallet函數(shù),可以將Parity Wallet庫合約變?yōu)槌R?guī)多sig錢包并成為它的所有者。 Parity
訪問控制問題在所有程序中都很常?,?不僅僅是智能合同。事實上,這是OWASP排名前10位的第5位。?們通常通過其公共或外部功能訪問合同的功能。盡管不安全的可視性設(shè)置會給攻擊者直接訪問合同的私有價值或邏輯的?式,但訪問控制旁路有時更加微妙。這些漏洞可能發(fā)?在合約使?已棄?tx.origin的驗證調(diào)?者時,?時間處理?型授權(quán)邏輯require并delegatecall在代理庫或代理合約中魯莽使?。
損失:估計為150,000 ETH(當時約3000萬美元)
真實世界影響:
- 奇偶校驗錯誤1
- 奇偶校驗錯誤2
- Rubixi
示例:
代碼示例:
在下?的例?中,契約的初始化函數(shù)將函數(shù)的調(diào)?者設(shè)置為它的所有者。然?,邏輯與合約的構(gòu)造函數(shù)分離,并且不記錄它已經(jīng)被調(diào)?的事實。
function initContract() public {owner = msg.sender; }在Parity multi-sig錢包中,這個初始化函數(shù)與錢包本身分離并在“庫”合同中定義。?戶需要通過調(diào)?庫的函數(shù)來初始化??的錢包delegateCall。不幸的是,在我們的例?中,函數(shù)沒有檢查錢包是否已經(jīng)被初始化。更糟糕的是,由于圖書館是?個聰明的合同,任何?都可以??初始化圖書館并要求銷毀。
其他資源:
- 修復(fù)Parity多信號錢包bug 1
- 奇偶校驗安全警報2
- 在奇偶錢包multi-sig hack上
- 不受保護的功能
- Rubixi的智能合約
3.算術(shù)問題
也被稱為 整數(shù)溢出和整數(shù)下溢
溢出情況會導(dǎo)致不正確的結(jié)果,特別是如果可能性未被預(yù)期,可能會影響程序的可靠性和安全性。 Jules Dourlens
整數(shù)溢出和下溢不是?類新的漏洞,但它們在智能合約中尤其危險,其中?符號整數(shù)很普遍,?多數(shù)開發(fā)?員習慣于簡單int類型(通常是有符號整數(shù))。如果發(fā)?溢出,許多良性代碼路徑成為盜竊或拒絕服務(wù)的載體。
真實世界影響:
- DAO
- BatchOverflow(多個令牌)
- ProxyOverflow(多個令牌)
示例:
代碼示例:
最直接的例?是?個不檢查整數(shù)下溢的函數(shù),允許您撤銷?限量的標記:
function withdraw(uint _amount) { require(balances[msg.sender] - _amount > 0);msg.sender.transfer(_amount);balances[msg.sender] -= _amount; }第?個例?(在?益的Solidity編碼競賽期間被發(fā)現(xiàn))是由于數(shù)組的?度由?符號整數(shù)表示的事實促成的錯誤的錯誤:
function popArrayOfThings() { require(arrayOfThings.length >= 0);arrayOfThings.length--; }第三個例?是第?個例?的變體,其中兩個?符號整數(shù)的算術(shù)結(jié)果是?個?符號整數(shù):
function votes(uint postId, uint upvote, uint downvotes) { if (upvote - downvote < 0) {deletePost(postId)} }第四個示例提供了即將棄?的var關(guān)鍵字。由于var將?身改變?yōu)榘付ㄖ邓璧淖?類型,因此它將成為uint8保持值0.如果循環(huán)的迭代次數(shù)超過255次,它將永遠達不到該數(shù)字,并且在執(zhí)?運?時停?出?:
for (var i = 0; i < somethingLarge; i ++) { // ... }其他資源:
- SafeMath防?溢出
- 整數(shù)溢出代碼示例
4.未檢查返回值的低級別調(diào)?
也稱為 或與靜默失敗發(fā)送,未經(jīng)檢查發(fā)送
盡可能避免使?低級別的“調(diào)?”。如果返回值處理不當,它可能會導(dǎo)致意外的?為。Remix
其中的密實度的更深層次的特點是低級別的功能call(),callcode(),delegatecall()和send()。他們在計算錯誤??的?為與其他Solidity函數(shù)完全不同,因為他們不會傳播(或冒泡),并且不會導(dǎo)致當前執(zhí)?的全部回復(fù)。相反,他們會返回?個布爾值設(shè)置為false,并且代碼將繼續(xù)運?。這可能會讓開發(fā)?員感到意外,如果未檢查到這種低級別調(diào)?的返回值,則可能導(dǎo)致失敗打開和其他不想要的結(jié)果。請記住,發(fā)送可能會失敗!
真實世界影響:
- 以太之王
- Etherpot
代碼示例:
下?的代碼是?個當忘記檢查返回值時會出錯的例?send()。如果調(diào)??于將ether發(fā)送給不接受它們的智能合約(例如,因為它沒有應(yīng)付回退功能),則EVM將?其替換其返回值false。由于在我們的例?中沒有檢查返回值,因此函數(shù)對合同狀態(tài)的更改不會被恢復(fù),并且etherLeft變量最終會跟蹤?個不正確的值:
function withdraw(uint256 _amount) public { require(balances[msg.sender] >= _amount);balances[msg.sender] -= _amount;etherLeft -= _amount;msg.sender.send(_amount); }其他資源:
- 未經(jīng)檢查的外部寫?
- 掃描“未經(jīng)檢查 - 發(fā)送”錯誤的現(xiàn)場以太坊合同
5.拒絕服務(wù)
包括達到gas上限,意外拋出,意外殺死,訪問控制違規(guī)
我不??殺了它。 devops199 on the Parity multi-sig wallet
在以太坊的世界中,拒絕服務(wù)是致命的:盡管其他類型的應(yīng)?程序最終可以恢復(fù),但智能合同可以通過 其中?種攻擊永遠脫機。許多??導(dǎo)致拒絕服務(wù),包括在作為交易接受?時惡意?為,?為地增加計算 功能所需的?體,濫?訪問控制訪問智能合約的私?組件,利?混淆和疏忽,...這類攻擊包括許多不同的變體,并可能在未來?年看到很多發(fā)展。
損失:估計為514,874 ETH(當時約3億美元)
真實世界影響:
- 政府
- 奇偶校驗多信號錢包
示例:
代碼示例:
在下?的例?中(受以太王的啟發(fā)),游戲合同的功能可以讓你成為總統(tǒng),如果你公開賄賂前?個。不 幸的是,如果前總統(tǒng)是?個聰明的合同,并導(dǎo)致?付逆轉(zhuǎn),權(quán)?的轉(zhuǎn)移將失敗,惡意智能合同將永遠保 持總統(tǒng)。聽起來像是對我的獨裁:
function becomePresident() payable {require(msg.value >= price); // must pay the price to become presidentpresident.transfer(price); // we pay the previous presidentpresident = msg.sender; // we crown the new presidentprice = price * 2; // we double the price to become president }在第?個例?中,調(diào)?者可以決定下?個函數(shù)調(diào)?將獎勵誰。由于for循環(huán)中有昂貴的指令,攻擊者可 能會引?太?的數(shù)字來迭代(由于以太坊中的?體阻塞限制),這將有效地阻?函數(shù)的功能。
function selectNextWinners(uint256 _largestWinner) { for(uint256 i = 0; i < largestWinner, i++) { // heavy code}largestWinner = _largestWinner; }其他資源:
- 奇偶Multisig被?客?侵。再次
- 關(guān)于Parity multi-sig錢包漏洞和Cappasity令牌眾包的聲明
6.錯誤隨機性
也被稱為 沒有什么是秘密的
合同對block.number年齡沒有?夠的驗證,導(dǎo)致400個ETH輸給?個未知的玩家,他在等待256個街區(qū)之前揭示了可預(yù)測的中獎號碼。 Arseny Reutov
以太坊的隨機性很難找到。雖然Solidity提供的功能和變量可以訪問明顯難以預(yù)測的值,但它們通常要么?看起來更公開,要么受到礦?影響。由于這些隨機性的來源在?定程度上是可預(yù)測的,所以惡意?戶通常可以復(fù)制它并依靠其不可預(yù)知性來攻擊該功能。
損失:超過400 ETH
真實世界影響:
- SmartBillions彩票
- 運?
示例:
代碼示例:
在第?個例?中,a private seed與iteration數(shù)字和keccak256散列函數(shù)結(jié)合使?來確定主叫?是否獲勝。Eventhough的seed是private,它必須是通過交易在某個時間點設(shè)置,并因此在blockchain可?。
uint256 private seed; function play() public payable {require(msg.value >= 1 ether);iteration++; uint randomNumber = uint(keccak256(seed + iteration)); if (randomNumber % 2 == 0) {msg.sender.transfer(this.balance); } }在這第?個例?中,block.blockhash正被?來?成?個隨機數(shù)。如果將該哈希值blockNumber設(shè)置為當前值block.number(出于顯?易?的原因)并且因此設(shè)置為,則該哈希值未知0。在blockNumber過去設(shè)置為超過256個塊的情況下,它將始終為零。最后,如果它被設(shè)置為?個以前的不太舊的區(qū)塊號碼,另?個智能合約可以訪問相同的號碼并將游戲合同作為同?交易的?部分進?調(diào)?。
function play() public payable { require(msg.value >= 1 ether); if (block.blockhash(blockNumber) % 2 == 0) {msg.sender.transfer(this.balance);} }其他資源: -?在以太坊智能合約中預(yù)測隨機數(shù)?-?在以太坊隨機
7.前臺運?
也被稱為 檢查時間與使?時間(TOCTOU),競爭條件,事務(wù)順序依賴性(TOD)
事實證明,只需要150?左右的Python就可以獲得?個正常運?的算法。 Ivan Bogatyy
由于礦?總是通過代表外部擁有地址(EOA)的代碼獲得燃?費?,因此?戶可以指定更?的費?以便 更快地開展交易。由于以太坊區(qū)塊鏈是公開的,每個?都可以看到其他?未決交易的內(nèi)容。這意味著, 如果某個?戶正在揭示拼圖或其他有價值的秘密的解決?案,惡意?戶可以竊取解決?案并以較?的費 ?復(fù)制其交易,以搶占原始解決?案。如果智能合約的開發(fā)者不??,這種情況會導(dǎo)致實際的和毀滅性 的前端攻擊。
真實世界影響:
- 班柯
- ERC-20
- 運?
示例:
其他資源:
- 在以太坊智能合約中預(yù)測隨機數(shù)
- 虛擬和解的前衛(wèi),悲痛和危險
- Frontrunning Bancor
8.時間篡改
也被稱為 時間戳依賴
如果?位礦?持有合同的股份,他可以通過為他正在挖掘的礦區(qū)選擇合適的時間戳來獲得優(yōu)勢。 Nicola Atzei,Massimo Bartoletti和Tiziana Cimoli
從鎖定令牌銷售到在特定時間為游戲解鎖資?,合同有時需要依賴當前時間。這通常通過Solidity中的 block.timestamp別名或其別名完成now。但是,這個價值從哪?來?來?礦?!由于交易的礦?在報告采礦發(fā)?的時間??具有回旋余地,所以良好的智能合約將避免強烈依賴所宣傳的時間。請注意, block.timestamp有時(錯誤)也會在隨機數(shù)的?成中使?,如#6所述。錯誤的隨機性。
真實世界影響:
政府
示例:
代碼示例:
以下功能只接受特定?期之后的呼叫。由于礦?可以影響他們區(qū)塊的時間戳(在?定程度上),他們可以嘗試挖掘?個包含他們交易的區(qū)塊,并在未來設(shè)定?個區(qū)塊時間戳。如果?夠接近,它將在?絡(luò)上被接受,交易將在任何其他玩家試圖贏得?賽之前給予礦?以太:
function play() public { require(now > 1521763200 && neverPlayed == true);neverPlayed = false;msg.sender.transfer(1500 ether); }其他資源:
- 對以太坊智能合約的攻擊調(diào)查
- 在以太坊智能合約中預(yù)測隨機數(shù)
- 讓智能合約變得更聰明
9.短地址攻擊
也被稱為 涉及?連鎖問題,客戶端漏洞
為令牌傳輸準備數(shù)據(jù)的服務(wù)假定?戶將輸?20字節(jié)?的地址,但實際上并未檢查地址的?度。 Pawe?Bylica
短地址攻擊是EVM本身接受不正確填充參數(shù)的副作?。攻擊者可以通過使?專?制作的地址來利?這?點,使編碼錯誤的客戶端在將它們包含在事務(wù)中之前不正確地對參數(shù)進?編碼。這是EVM問題還是客戶問題?是否應(yīng)該在智能合約中修復(fù)?盡管每個?都有不同的觀點,但事實是,這個問題可能會直接影響很多以太?。雖然這個漏洞還沒有被?規(guī)模利?,但它很好地證明了客戶和以太坊區(qū)塊鏈之間的交互帶來的問題。其他脫鏈問題存在:重要的是以太坊?態(tài)系統(tǒng)對特定的javascript前端,瀏覽器插件和公共節(jié)點的深度信任。臭名昭著的鏈外利?被?于Coindash ICO的?客在他們的??上修改了公司的以太坊地址,誘騙參與者將ethers發(fā)送到攻擊者的地址。
發(fā)現(xiàn)時間表: 2017年4?6??如何通過閱讀區(qū)塊鏈來找到1000萬美元
真實世界影響:
未知交換(s)
示例:
其他資源:
- ERC20短地址攻擊說明
- 分析ERC20短地址攻擊
- 智能合同短地址攻擊緩解失敗
- 從標記中刪除短地址攻擊檢查
10.未知的 未知物
我們相信更多的安全審計或更多的測試將沒有什么區(qū)別。主要問題是評審?員不知道要尋找什么。 Christoph Jentzsch
以太坊仍處于起步階段。?于開發(fā)智能合同的主要語?Solidity尚未達到穩(wěn)定版本,??態(tài)系統(tǒng)的?具仍處于試驗階段。?些最具破壞性的智能合約漏洞使每個?都感到驚訝,并且沒有理由相信不會有另?個同樣出乎意料或同樣具有破壞性的漏洞。只要投資者決定將?量資??于復(fù)雜?輕微審計的代碼,我們將繼續(xù)看到新的發(fā)現(xiàn)導(dǎo)致可怕的后果。對智能合約進?正式驗證的?法尚不成熟,但它們似乎有望成為今?搖搖欲墜的現(xiàn)狀。隨著新類型的漏洞不斷被發(fā)現(xiàn),開發(fā)?員需要繼續(xù)努?,并且需要開發(fā)新?具來在壞?之前找到它們。這個前10名可能會迅速發(fā)展,直到智能合約開發(fā)達到穩(wěn)定和成熟的狀態(tài)。
總結(jié)
以上是生活随笔為你收集整理的以太坊智能合约安全 Dasp Top10的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 以太坊智能合约 Hexagon 存在溢出
- 下一篇: 【译】Economics of Fees