曲速未來 :智能合約攻擊分析之SafeMath使用不當區塊鏈
智能合約安全咨詢公司曲速未來提醒:在編寫智能合約的時候需要注意的一個主要的安全特性:防止溢出和下溢。為了防止這些情況,OpenZeppelin建立了一個叫做SafeMath的庫(library),默認情況下可以防止這些問題。
智能合約安全咨詢公司 曲速未來 提醒:在編寫智能合約的時候需要注意的一個主要的安全特性:防止溢出和下溢。為了防止這些情況,OpenZeppelin建立了一個叫做SafeMath的庫(library),默認情況下可以防止這些問題。
什么是溢出(overflow)?
假設我們有一個uint8, 只能存儲8 bit數據。這意味著我們能存儲的最大數字就是二進制11111111(或者說十進制的2^8-1 =255).
來看看下面的代碼。最后 number 將會是什么值?
在這個例子中,我們導致了溢出—雖然我們加了1,但是number出乎意料地等于0了。
下溢(underflow)也類似,如果你從一個等于0的uint8減去1, 它將變成255 (因為uint是無符號的,其不能等于負數)。
使用 SafeMath
不過在我們使用之前……什么叫做庫?
一個庫是Solidity中一種特殊的合約。其中一個有用的功能是給原始數據類型增加一些方法。
比如,使用SafeMath庫的時候,我們將使用using SafeMath for uint256這樣的語法。SafeMath庫有四個方法—add,sub,mul,以及 div。
以太坊虛擬機EVM定義無符號整數為uint256,可以表示一個256位的大整數,但并沒有提供溢出的檢測機制。OpenZeppline是一個第三方智能合約庫,實現了一套SafeMath庫來檢測溢出。其代碼如下:
SafeMath使用內建的require或assert來檢查運算是否發生溢出,如果發生了溢出,require和assert中包含的代碼會使該事務回滾。但有些開發者不能完全理解SafeMath模版代碼,導致合約代碼中仍然存在漏洞。
1.攻擊案例:UCN (0x6EF5B9ae723Fe059Cac71aD620495575d19dAc42)
UCN是一個智能合約DApp應用。合約代碼在SafeMath庫中注釋assert語句,因此SafeMath函數等同于直接進行算術運算,沒有任何安全檢查。并且在transferFrom函數中,注釋中聲明sub函數是安全的,不知道這是開發人員的疏忽還是故意留下的后門。
由于sub函數等同于算術運算,balances[_from] = balances[_from].sub(_value); 存在整數下溢漏洞,可以使得賬戶余額變成一個極大值。
2.攻擊案例:EMVC(0xd3F5056D9a112cA81B0e6f9f47F3285AA44c6AAA)
EMVC合約代碼在SafeMath庫中使用了一個自定義的assert來代替內建的assert。在assert函數中,如果參數assertion為false則直接return,并沒有進行異常處理。因此SafeMath函數等同于直接進行算術運算,沒有任何安全檢查。
攻擊者可以使用transfer函數設置任意賬戶余額為任意值。
總結
智能合約安全咨詢公司 曲速未來 提醒:當智能合約要實現更多功能時,代碼會相應變得更加復雜,與ERC20標準代碼的差異也越來越大,因而潛在的漏洞面貌更加多樣。為了保證智能合約的安全,除遵循安全開發原則、按照“Check Lists”進行基線檢查外,還需要實施更深入細致的審計。
1.TMT觀察網遵循行業規范,任何轉載的稿件都會明確標注作者和來源;
2.TMT觀察網的原創文章,請轉載時務必注明文章作者和"來源:TMT觀察網",不尊重原創的行為TMT觀察網或將追究責任;
3.作者投稿可能會經TMT觀察網編輯修改或補充。