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