主页 > imtoken钱包手机安卓版下载 > Ethereum Contract Audit CheckList《以太坊智能合约规范问题》影响分析报告

Ethereum Contract Audit CheckList《以太坊智能合约规范问题》影响分析报告

Ethereum Contract Audit CheckList 的“以太坊智能合约规范问题”影响分析报告 2018 年 8 月 13 日 2018 年 8 月 13 日

区块链·404专栏

目录

作者:LoRexxar'@知道创宇404区块链安全研究组

时间:2018-08-10

英文版:

一、简介

在智创宇404区块链安全研究团队编译输出的《知乎创宇以太坊合约审计清单》中,“未触发转账事件问题”、“未触发审批事件问题”、“虚假充值漏洞”、“构造函数编写错误”以及其他问题统称为“以太坊智能合约规范问题”。

“昊天塔(HaoTian)”是智创宇404区块链安全研究团队自主研发的区块链智能合约监控、扫描、分析、审计的安全自动化平台。 我们利用该平台对《知乎创宇以太坊合约审计清单》中上述《以太坊智能合约规范》全网公开的智能合约代码进行了扫描分析。 详情见下文:

2. 漏洞详情

ERC20 是用于以太坊区块链上智能合约的代币标准。 ERC20 定义了以太坊必须执行的通用规则。 如果以太坊上发行的代币符合ERC20标准,那么交易所就可以集成并实现代币在其交易所的买卖。

ERC20规定转账函数必须触发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日,KNOW创宇404区块链安全研究团队对该漏洞进行了跟进响应,并针对该漏洞发布了漏洞预警。

4.构造函数写错漏洞

在Solidity 0.4.22版本之前,编译器要求构造函数的名字要和合约的名字保持一致。 如果构造函数名称和合约名称的大小写不一致,该函数仍将被视为普通函数,可以被任何用户调用。

Solidity 0.4.22 引入了构造函数使用不当的问题。 构造函数中错误地添加了函数定义,会导致构造函数被任意用户调用,进而可能导致更严重的危害,如所有者权限被盗用。 .

构造函数大小写错误漏洞

contract own(){
    function Own() {
        owner = msg.sender;
    }
}

上述代码错误地将构造函数名大写,导致构造函数名和合约名不一致。 在本例中,该函数被设置为一个普通的公共函数,任何用户都可以通过调用该函数将自己修改为合约所有者。 进一步导致其他严重后果。

2018年6月22日,MorphToken合约代币宣布更新新的智能合约,修复了大写错误导致的构造函数问题。

2018年6月22日,KNOW创宇404区块链安全研究团队紧急跟进,输出《以太坊智能合约构造函数编码错误导致合约所有权非法转移报告》。

构造函数编码错误漏洞

    function constructor() public {
        owner = msg.sender;
    }

什么是以太坊智能合约_以太坊智能合约_以太坊智能合约安全性

上面的代码错误地将function用作构造函数的修饰符。 在本例中,该函数被设置为一个普通的公共函数,任何用户都可以通过调用该函数将自己修改为合约所有者。 进一步导致其他严重后果。

2018年7月14日,连安科技在公众号公布了构造函数写错问题的详情。

2018年7月15日,知乎创宇404区块链安全研究团队紧急跟进,输出《以太坊智能合约构造函数编写错误导致合约所有权非法转移报告》

3. 漏洞范围

此类问题可以利用昊天平台的智能合约审计功能进行精准扫描。

以太坊智能合约安全性_以太坊智能合约_什么是以太坊智能合约

根据昊天平台智能合约审计功能规则,我们共扫描全网39548个合约代码,共14978个合约涉及此类问题。

1.Transfer事件没有触发

截至2018年8月10日,我们发现有4604个合约代码不符合ERC20标准,没有触发Transfer事件。 其中,成交量最高的10个合约如下:

以太坊智能合约安全性_什么是以太坊智能合约_以太坊智能合约

2. Approval事件没有触发

截至2018年8月10日,我们发现有5231个合约代码不符合ERC20标准以太坊智能合约,没有触发Approval事件。 其中,成交量最高的10个合约如下:

以太坊智能合约_以太坊智能合约安全性_什么是以太坊智能合约

3.虚假充值漏洞

2018年7月9日,当得知创宇404区块链安全研究团队正在跟进紧急假充值漏洞时,他们扫描了全网公开的合约代码,发现了约3141个存在假充值问题的合约。 代码中,交易量最高的10个合约如下:

以太坊智能合约安全性_以太坊智能合约_什么是以太坊智能合约

截至2018年8月10日,我们共发现5027个合约代码存在虚假充值问题。 其中,成交量最高的10个合约如下:

什么是以太坊智能合约_以太坊智能合约_以太坊智能合约安全性

4.构造函数编写问题构造函数大小写错误漏洞

2018年6月22日,得知创宇404区块链安全研究团队正在跟进紧急假充值漏洞时,全网约有16个合约存在该问题。

截至2018年8月10日,我们在构造函数中发现90个大小写错误的合约代码,其中交易量最高的10个合约如下:

以太坊智能合约_以太坊智能合约安全性_什么是以太坊智能合约

构造函数编码问题

什么是以太坊智能合约_以太坊智能合约_以太坊智能合约安全性

截至2018年8月10日,我们共发现24个存在构造函数编写问题的合约代码,仅比2018年7月14日漏洞应急响应多1个合约。其中交易量最高的10个合约如下:

什么是以太坊智能合约_以太坊智能合约_以太坊智能合约安全性

4、修复方法 1)transfer函数中要触发Tranfser事件

  function transfer(address _to, uint256 _value) public returns (bool) {
    require(_value <= balances[msg.sender]);
    require(_to != address(0));
    balances[msg.sender] = balances[msg.sender].sub(_value);
    balances[_to] = balances[_to].add(_value);
    emit Transfer(msg.sender, _to, _value);
    return true;
  }

2) Approval事件应该在approve函数中触发

  function approve(address _spender, uint256 _value) public returns (bool) {
    allowed[msg.sender][_spender] = _value;
    emit Approval(msg.sender, _spender, _value);
    return true;
  }

3)验证转账余额时,应该使用require来抛错

  function transfer(address _to, uint256 _value) public returns (bool) {
    require(_value <= balances[msg.sender]);
    require(_to != address(0));

以太坊智能合约_什么是以太坊智能合约_以太坊智能合约安全性

balances[msg.sender] = balances[msg.sender].sub(_value); balances[_to] = balances[_to].add(_value); emit Transfer(msg.sender, _to, _value); return true; }

4) 0.4.22版本之前,构造函数要和合约名称保持一致

contract ownable {
    function ownable() public {
    owner = msg.sender;
  }

5) 0.4.22版本后,构造函数不再用function修饰

constructor() public {
        owner = msg.sender;
    }

5.一些想法

以上问题是我在回顾历史漏洞时经常发现的一类问题。 都是开发者不遵守ERC20标准造成的。 问题是后期维护合约代币会出现很多问题。

如果在转账和审批过程中没有触发相应的事件,开发者将需要更复杂的方式来监控合约的交易状态。 一旦发生大规模盗窃,甚至没有足够的日志来提供回滚。

如果在转账过程中没有抛出错误,可能会导致虚假充值漏洞。 如果平台根据交易状态核对交易结果进行判断,将导致平台利益受损。

如果开发者在构造函数时没有注意不同版本的编译器标准,可能会导致合约所有权被轻易窃取以太坊智能合约,进而引发盗币等更严重的问题。

当我们扫描监控全网公开的合约代码时,不难发现大量开发者并没有注意到这些问题,甚至在漏洞预警后仍然出现构造函数编写错误等低级错误。 考虑到目前大部分合约代码都没有公开,可能还有很多开发者在不遵守标准的情况下进行开发,还有很多潜在的问题需要考虑。

在此我们建议所有开发者重新检查自己的合约代码,检查是否符合ERC20合约标准,避免不必要的麻烦和安全问题。

智能合约审计服务

针对目前主流的以太坊应用,智创宇提供专业、权威的智能合约审计服务,避免因合约安全问题造成的财产损失,为各类以太坊应用的安全保驾护航。

知乎创宇404智能合约安全审计团队: