【論文閱讀】ContractFuzzer:fuzzing方法挖掘智能合約漏洞
論文簡介
論文標題:ContractFuzzer: Fuzzing Smart Contracts for Vulnerability Detection
論文鏈接:ContractFuzzer: Fuzzing Smart Contracts for Vulnerability Detection
開源地址:gongbell/ContractFuzzer: The Ethereum Smart Contract Fuzzer for Security Vulnerability Detection (ASE 2018)
本篇論文提出了一個采用fuzzing技術對智能合約漏洞進行分類挖掘的工具,取名為ContractFuzzer。這篇論文是這該領域的開山之作。
可檢測的漏洞分類與對應的檢測方法
send函數gas不足
漏洞定義:
在調用send函數的時候gas默認為2300,這只足夠調用空的fallback函數。若目標合約的fallback函數不為空(還有其他操作),則會導致gas不足進行回滾。若調用了send函數卻沒有檢查返回值是否成功(默認成功),則可能發生意外的錯誤。
檢測方法:
- 調用了
send()函數 send()函數在運行過程中拋出了ErrOutOfGas錯誤
異?;貍鱽G失
漏洞定義:
若調用鏈中的每個調用都是對合約功能的直接調用,當發生異常時,所有交易都將被回滾(包括以太幣轉賬)。 但是,對于至少一個通過低級調用方法(address.call()、address.delegatecall() 、address.send())對地址進行調用的嵌套調用鏈,事務的回滾將 只停在調用函數處并返回false。
檢測方法:
- 若其嵌套調用中至少有一個拋出了異常,但根調用沒有拋出異常。
重入漏洞
漏洞定義:
當“轉賬函數”先進行轉賬,在清空賬戶余額的時候,重入漏洞就會發生。攻擊者在fallback函數中再次調用“轉賬函數”,進行重復多次的取款。
檢測方法:
- 遞歸調用檢測
- 在以調用
A函數為開始的調用鏈中,A函數是否被多次調用。
- 在以調用
- 轉賬檢測
- 調用函數
call()的轉賬數目大于0 - 有足夠的
gas讓被調用函數執行復雜的代碼 call()函數所調用的合約是ContractFuzzer提供的攻擊合約,而不是被測試合約所指定的合約。
- 調用函數
時間戳依賴
漏洞定義:
如果智能合約采用區塊產生的時間來進行一個隨機數的構建,則可能遭到攻擊。因為區塊產生的時間值可以由礦工在一定的時間范圍內自行定義。
檢測方法:
- 函數執行期間是否調用了
TIMESTAMP操作碼 - 是否通過
send()函數或call()函數發送以太
區塊號依賴
漏洞定義:
區塊號依賴的弱點和時間戳依賴的原因相似,如果智能合約采用區塊產生的編號來進行一個隨機數的構建,則可能遭到攻擊。因為區塊產生的編號可以由礦工進行操控。
檢測方法:
- 函數執行期間是否調用了
NUMBER操作碼 - 是否通過
send()函數或call()函數發送以太
delegatecall使用
漏洞定義:
采用delegatecall調用目標函數,目標函數將會在發起調用的合約環境中執行,從而可能導致發起調用的合約參數被修改。
檢測方法:
- 函數執行期間是否調用了
delegatecall()函數 - 被
delegatecall()所調用的函數是從原始的輸入(msg.data)中獲得的
余額凍結
漏洞定義:
當一個合約的轉賬功能完全依賴于調用外部合約的函數或外部Library時,一旦外部合約或Library自毀,則該合約的全部余額將無法取出。
檢測方法:
- 該合約能夠接收以太
- 本身沒有
transfer/send/call/suicide等功能,而是通過delegatecall()函數調用外部函數進行轉賬
ContractFuzzer流程圖

0-在本地部署離線的私有鏈
1-分析合約的ABI接口和字節碼,提取處參數類型以及函數簽名
2-對合約池中的所有合約進行函數簽名分析,并建立{合約,函數}的索引
3- 生成符合ABI規范的fuzzing輸入以及變異輸入
4-該工具將啟動fuzzing過程,將生成輸入數據輸入的相應的ABI接口中
5-根據執行日志檢測安全漏洞
智能合約靜態分析
首先基于每個智能合約導出的JSON格式ABI,提取ABI中聲明的所有函數簽名、參數描述和數據類型。目的是建立{函數選擇器,所有合約地址}的映射。
流程如下:

后記
這篇文章還有很多實驗的過程以及細節沒有整理進來,感興趣的讀者可以去翻翻論文看一下??偟膩碚f這篇文章講了一個大概的框架,沒有提到具體的技術實現,不過ContractFuzzer是開源的(在本文的開頭)。
接下來打算看一下fuzzing具體是一個什么樣的過程,輸入生成函數是怎么樣的,插樁又是什么東東。倒是想看一下ContractFuzzer是怎么實現的,但是他是用go寫的,要看的話我還得先go一下。
好,這次的論文就讀到這里,下期見~

浙公網安備 33010602011771號