目前,出現了多種智慧型合約審計工具,筆者整理了最常見的檢測內容,可分為五大項、二十七小項。下面按分類對已有結果進行說明。
1、**規範檢測
此大項主要針對合約編寫時的一些**規範進行檢測,共有十一小項。
1.1 erc規範
包含了eth常見的erc20、erc721、erc1400、erc1404、erc223、erc777等常見的合約標準檢測,確保了開發人員能正確實現這些標準。
1.2 transfer to zero address
在transfer、transferfrom、transferownership等敏感函式中,使用者操作不可逆,所以建議開發者在這些函式實現中增加目標位址非零檢查,避免使用者誤操作導致使用者許可權丟失和財產損失
1.3 tx origin authentication
tx.origin是solidity的乙個狀態變數,它遍歷整個呼叫棧並返回最初傳送呼叫(或事務)的帳戶的位址。在智慧型合約中使用此變數進行身份驗證會使合約容易受到類似網路釣魚的攻擊。
1.4 constructor mistyping
建構函式僅在合約部署的時候被呼叫,合約owner的設定一般放在建構函式中,合約的建構函式還會執行初始化的操作。在使用function的方式定義建構函式時,如果函式名與合約名失配,就變成了乙個普通函式。那麼,合約將存在重大安全風險。
1.5 complex code in fallback function
合約的fallback函式通常用以接收一筆eth轉賬,但如果在fallback裡實現過於複雜的邏輯,可能會將gas耗盡,導致轉賬不成功。
1.6 unary operation
當定義的操作的意圖是將數字與變數+=相加但卻意外地以錯誤的方式定義=+時,會出現錯誤。它不是計算總和,而是再次初始化變數。
1.7 redefine variable from base contracts
solidity中同一合約或不同合約允許有相同的狀態變數,他們不會構成直接威脅,在單個相當於重新定義了這個變數,在多個合約中繼承使用時會出現先後關係和使用錯誤的情況,所以盡量避免出現相同的狀態變數。
1.8 unused variables
solidity中允許有未使用的變數,它們不會構成直接的安全問題,但會降低**的可讀性並且額外占用儲存空間導致部署時的資源消耗增加。
1.9 no return
如果宣告乙個函式有返回值,而最後沒給它返回值,就會產生乙個預設的返回值,而預設返回值和實際執行後的返回值可能存在差異。
1.10 overload syscall
對於solidity已內建函式如assert,如果在合約中進行了重定義,可能會出現異常。
1.11 fake recharge vulnerability
erc20合約在transfer函式中可能失敗,這時函式並沒有異常退出,而是return false;如果交易所根據呼叫狀態來判斷轉賬是否成功,將會導致錯誤的判斷。
2、函式呼叫檢測
此大項用於檢查合約中在進行函式呼叫時可能出現的問題,共有五小項。
2.1 invoke low level calls
call是以太坊智慧型合約編寫語言solidity提供的底層函式,用來與外部合約或者庫進行互動。此類函式使用時需要對呼叫引數的安全性進行判定;delegatecall會保持呼叫環境不變的屬性表明,構建無漏洞的定製庫並不像人們想象的那麼容易。庫中的**本身可以是安全的,無漏洞的,但是當在另乙個應用的環境中執行時,可能會出現新的漏洞;selfdestruct自殺函式的呼叫會銷毀合約。
2.2 invoke extcodesize
extcodesize在合約部署的時候為零,攻擊者可以在自己的建構函式中呼叫受害合約,這個時候使用extcodesize驗證是無效的。
2.3 invoke ecrecover
keccak256()和ecrecover()都是內嵌的函式,keccak256()可以用於計算公鑰的簽名,ecrecover()可以用來恢復簽名公鑰。傳值正確的情況下,可以利用這兩個函式來驗證位址。但當ecrecover()的引數錯誤時候,返回0x0位址,如果_from也傳入0x0位址,就能通過校驗。也就是說,任何人都可以將0x0位址的餘額轉出
2.4 unchecked call or send return values
在呼叫call/send函式後無論執行成功還是失敗都不會直接拋異常,如果不對呼叫返回值進行檢查,函式會繼續執行。
2.5 re entrancy
合約內錯誤的邏輯實現可能導致重入呼叫,使用者能重複轉走token。
3、業務邏輯安全檢測
此大項主要用於檢查可能導致業務邏輯出現安全風險的問題,共有六個檢查項。
3.1 block members manipulation
區塊引數依賴風險主要有時間戳依賴和區塊雜湊依賴,這種風險主要來自於使用他們生成隨機數,因為它們可以被操縱或者被攻擊者獲取,所以不應該用於隨機種子。
3.2 arbitrary jump with function type variable
由於solidity不支援指標算術,因此無法將此變數更改為任意值。但是,如果開發人員在最壞的情況下使用彙編指令(例如或賦值運算子),則攻擊者可以將函式型別變數指向任何**指令,從而違反所需的驗證和所需的狀態更改。
3.3 check this balance
合約**中嚴格限制了合約的資金,而大多數情況下合約資金都是可變的,因此使用者能輕鬆利用這個特性使得合約的功能邏輯無法正常執行。
3.4 function problem
函式永遠只會以revert()等異常狀態結束,無法正常執行完後return,說明函式設計出現了問題。
3.5 call problem
call呼叫永遠失敗,說明函式設計出現了問題。
3.6 denial of service
合約可能在惡意呼叫之後,造成合約拒絕服務,其他使用者無法正常呼叫合約。
4、溢位檢測。
溢位是典型的合約漏洞,可能導致檢查被繞過,合約執行邏輯出錯。在此大項中,vaas主要進行了三小項的檢測。
4.1 exponent arithmetic overflow
4.2 integer overflow
4.3 integer underflow
5、異常可達狀態檢測
用於檢測合約在執行過程中可能出現的異常狀態,共有兩個檢查項。
5.1 assert fail
assert的限制條件是必須滿足的,在條件可能不滿足的情況下會報錯,說明合約執行狀態異常。
5.2 require fail
與assert類似,預設reqiure條件是可能滿足的,當條件在任何情況下都無法滿足會報錯,說明合約執行狀態異常
現在我們進行乙個測試,以最近曝出的以太坊遊戲合約cheeze wizards的漏洞為例,測試工具是一鍵式智慧型合約自動形式化驗證工具beosin-vaas,這也是目前唯一能夠檢測以上五大項、二十七小項常規安全漏洞的「一鍵式」自動檢測工具。
檢測方法:2.業務邏輯測試方法:
因為vaas支援異常可達狀態檢測,所以在使用vaas時可以通過新增require和assert來測試函式的業務邏輯是否有問題。
上圖為合約中問題函式resolvetimeoutduel的簡單實現,若直接由vaas進行檢測不會發現任何問題。
根據函式的說明可以知道,resolvetimeoutduel是在決鬥超時的情況下被呼叫,當滿足一定的條件後,會將wiz2的power轉移到wiz1上。根據這個邏輯我們很容易可以得到乙個結論,那就是無論條件是否滿足,函式執行前wiz1.power+wiz2.power和執行後的wiz1.power+wiz2.power應該相等。所以可以在函式起始和結束新增**來描述這個邏輯:
這樣再通過vaas進行檢測時35行就會報告assert fail:
CIO的管理智慧型
cio既要有治理意識,能夠參悟資訊的權力本質,放棄技術人員的傲慢和天真,不再寄希望於構建it的烏托邦,而是與ceo換位思考,理解戰略願意,與業務協作,獲得其支援和參與,it要去影響公司而不是簡單地運營it.cio不是一味地追求資訊平台的公升級,而是洞悉it的價值主張,找到應用上的解決方案,it應解決...
編寫智慧型合約
1.安裝node.js 2.安裝truffle npm install g truffle 3.啟動testrpc以太坊環境 testrpc 4.另開終端視窗新建專案 mkdir demo cd demo 5.初始化專案目錄 truffle init 6.建立合約檔案 truffle create ...
積分智慧型合約
pragma solidity 0.4.22 title safemath dev math operations with safety checks that throw on error library safemath function div uint256 a,uint256 b int...