區塊鏈智能合約的漏洞特別容易造成大量的代幣被Web3的攻擊者盜取。這也是我們SINE安全技術對有關區塊鏈智能合約安全寫的第二部分的文章,這篇文章依然是具體的去寫區塊鏈智能合約里的比較常見漏洞。
0x02漏洞詳細介紹與基本原理
算術外溢(arithmeticoverflow)或稱之為外溢(overflow)指的是在計算機界里發生的事。運轉單一數據處理時,當計算生成出來的結果超過寄存器或儲存器能夠存儲或顯示的能力限制的狀況就叫做算術上溢。相反,叫做算術下溢。在solidity中,uint8能夠顯示的范疇是0-255這256個數,當使用uint8類別在具體運算中計算255+1是會存在上溢的,這種計算出來結果顯示0可能就是uint8類別可顯示的最低值。相同的,下溢可能就是計算生成出來的結果特別小,低于寄存器或儲存器能夠存儲或顯示的能力限制就會形成下溢。比如在Solidity中,當使用uint8類別計算0-1時就會形成下溢,這種計算出來值為255可能就是uint8類別可顯示的最高值。
針對于區塊鏈里的智能合約溢出漏洞是存在著版本的一些差別的:
Solidity 小于0.8版本的 該漏洞不會報錯
Solidity 大于等于 0.8版本 該溢出漏洞會報錯
因此,當看到Solidity版本小于0.8的時候,就要注意該區塊鏈智能合約是不是有溢出漏洞。
智能合約溢出漏洞復現
在TimeLock區塊鏈智能合約中客戶可以根據deposit()變量存到自己的代幣并且給代幣加鎖(block.timestamp+1weeks)鎖住幾天時間,其實客戶也可以使用increaseLockTime()變量來提高儲存時長。不過在儲存時間達到以前,代幣還會繼續鎖在TimeLock區塊鏈智能合約里邊,不管客戶怎么操作都難以拿出。
那如何造成溢出漏洞呢?在deposit()變量之中能夠存入代幣同時通過Balance來查詢自個的存款,假如攻擊者存入2^256個代幣造成區塊鏈智能合約溢出并且清空自己的存款,我覺得沒有誰那么愚笨做出這種事兒,這件事成本費用太高。那么我們就只能依靠別的漏洞點來開啟這一溢出漏洞!
increaseLockTime(uint_secondsToIncrease)之中_secondsToIncrease直接跟賬戶所對應的鎖住時長lockTime開展運算,因此我們能夠操控_secondsToIncrease參數使它在和LockTime開展運算是溢出,就可以造成溢出漏洞,進而在未達到取款時長拿出咱們存入的代幣。
SINE安全對智能合約溢出漏洞修復的一些建議:
1.應用SafeMath來避免外溢;
2.應用Solidity0.8或以上版本來開發設計合約并慎用unchecked因為在unchecked處理過的代碼塊里邊并沒有對參數采取溢出檢查的;
3.須要謹慎使用變量的類型強制類型轉換,比如將uint256類型的參數強轉為uint8類型因為兩種形式的取值不一樣也可能會致使外溢。