作者:LoRexxar’@知道創宇404區塊鏈安全研究團隊
時間:2018年8月10日
英文版:https://paper.seebug.org/670/
一、 簡介
在知道創宇404區塊鏈安全研究團隊整理輸出的《知道創宇以太坊合約審計CheckList》中,把“未觸發Transfer事件問題”、“未觸發Approval事件問題”、“假充值漏洞”、“構造函數書寫錯誤”等問題統一歸類為“以太坊智能合約規範問題”。
“昊天塔(HaoTian)”是知道創宇404區塊鏈安全研究團隊獨立開發的用於監控、掃描、分析、審計區塊鏈智能合約安全自動化平台。我們利用該平台針對上述提到的《知道創宇以太坊合約審計CheckList》中“以太坊智能合約規範”類問題在全網公開的智能合約代碼做了掃描分析。詳見下文:
二、漏洞詳情
ERC20是一種代幣標準,用於以太坊區塊鏈上的智能合約。ERC20定義了一種以太坊必須執行的通用規則,如果在以太坊發行的代幣符合ERC20的標準,那麼交易所就可以進行集成,在它們的交易所實現代幣的買賣和交易。
ERC20中規定了transfer函數必須觸發Transfer事件,transfer函數必須返回bool值,在進行餘額判斷時,應拋出錯誤而不是簡單的返回錯誤,approve函數必須觸發Approval事件。
1、未觸發Transfer事件
function transfer(address _to, uint256 _value) public returns (bool success) { require(balanceOf[msg.sender] >= _value); require(balanceOf[_to] + _value >= balanceOf[_to]); balanceOf[msg.sender] -= _value; balanceOf[_to] += _value; return true; }
上述代碼在發生交易時未觸發Transfer事件,在發生交易時,未產生event事件,不符合ERC20標準,不便於開發人員對合約交易情況進行監控。
2、未觸發Approval事件
function approve(address _spender, uint256 _value) public returns (bool success) { allowance[msg.sender][_spender] = _value; return true; }
上述代碼在發生交易時未觸發Approval事件,在發生交易時,未產生event事件,不符合ERC20標準,不便於開發人員對合約情況進行監控。
3、假充值漏洞
function transfer(address _to, uint256 _amount) returns (bool success) { initialize(msg.sender); if (balances[msg.sender] >= _amount && _amount > 0) { initialize(_to); if (balances[_to] + _amount > balances[_to]) { balances[msg.sender] -= _amount; balances[_to] += _amount; Transfer(msg.sender, _to, _amount); return true; } else { return false; } } else { return false; } }
上述代碼在判斷餘額時使用了if語句,ERC20標準規定,當餘額不足時,合約應拋出錯誤使交易回滾,而不是簡單的返回false。
這種情況下,會導致即使沒有真正發生交易,但交易仍然成功,這種情況會影響交易平台的判斷結果,可能導致假充值。
2018年7月9日,慢霧安全團隊發布了關於假充值的漏洞預警。
2018年7月9日,知道創宇404區塊鏈安全研究團隊跟進應急該漏洞,並對此漏洞發出了漏洞預警。
4、構造函數書寫錯誤漏洞
Solidity0.4.22版本以前,編譯器要求,構造函數名稱應該和合約名稱保持一致,如果構造函數名字和合約名字大小寫不一致,該函數仍然會被當成普通函數,可以被任意用戶調用。
Solidity0.4.22中引入了關於構造函數constructor使用不當的問題,constructor在使用中錯誤的加上了function定義,從而導致constructor可以被任意用戶調用,會導致可能的更嚴重的危害,如Owner權限被盜。
構造函數大小寫錯誤漏洞
contract own(){ function Own() { owner = msg.sender; } }
上述代碼錯誤的將構造函數名大寫,導致構造函數名和合約名不一致。這種情況下,該函數被設置為一個普通的public函數,任意用戶都可以通過調用該函數來修改自己為合約owner。進一步導致其他嚴重的後果。
2018年6月22日,MorphToken合約代幣宣布更新新的智能合約,其中修復了關於大小寫錯誤導致的構造函數問題。
2018年6月22日,知道創宇404區塊鏈安全研究團隊跟進應急,並輸出了《以太坊智能合約構造函數編碼錯誤導致非法合約所有權轉移報告》。
構造函數編碼錯誤漏洞
function constructor() public { owner = msg.sender; }
上述代碼錯誤的使用function來作為constructor函數裝飾詞,這種情況下,該函數被設置為一個普通的public函數,任意用戶都可以通過調用該函數來修改自己為合約owner。進一步導致其他嚴重的後果。
2018年7月14日,鏈安科技在公眾號公布了關於constructor函數書寫錯誤的問題詳情。
2018年7月15日,知道創宇404區塊鏈安全研究團隊跟進應急,並輸出了《以太坊智能合約構造函數書寫錯誤導致非法合約所有權轉移報告》
三、漏洞影響範圍
使用Haotian平台智能合約審計功能可以準確掃描到該類型問題。
[3] 構造函數書寫問題漏洞詳情
https://mp.weixin.qq.com/s/xPwhanev-cjHhc104Wmpug