JavaScript 不可用。

我们检测到浏览器禁用了 JavaScript。请启用 JavaScript 或改用支持的浏览器来继续访问

BeautyChain 美链BEC智能合约漏洞分析 [整数溢出攻击]

作者:Anban Chu

发表日期:2018年04月25日

所属目录:黑客攻击

攻击描述

  • 被黑目标:BeautyChain
  • 事件描述:黑客利用数据溢出攻击 BeautyChain 智能合约,成功将 BEC 代币转入两个地址,导致市场上大量抛售 BEC,数字货币价值几乎为零, 给 BEC 市场带来了毁灭性的打击。
  • 损失金额:代币归零
  • 攻击方式:整数溢出攻击

合约开发者使用了 SafeMath 库,但是使用使用的时候却没有严格使用该库。

合约描述

攻击过程技术分析

核心代码如下:

function batchTransfer(address[] _receivers, uint256 _value) public whenNotPaused returns (bool) {
  uint cnt = _receivers.length;
  uint256 amount = uint256(cnt) * _value; // 这里没有使用 SafeMath
  require(cnt > 0 && cnt <= 20);
  require(_value > 0 && balances[msg.sender] >= amount);

  balances[msg.sender] = balances[msg.sender].sub(amount); // 使用 SafeMath 减去 amount
  for (uint i = 0; i < cnt; i++) {
      balances[_receivers[i]] = balances[_receivers[i]].add(_value);
      Transfer(msg.sender, _receivers[i], _value);
  }
  return true;
}

这里 amount = uint256(cnt) * _value 没有使用 SafeMath,只需要把 amount 值设为零即可。后面虽然使用 SafeMath 减去 amount,但是 amount 为零,还是可以通过检查的。

攻击者传入两个地址,value 使用 2**256 作为转账的值,2**256 * 2 刚好等于零。amount=0,绕过了require(_value > 0 && balances[msg.sender] >= amount);异常检查语句。

下面是测试的演示。

// SPDX-License-Identifier: MIT
pragma solidity ^0.4.19;

contract BECTest {
    uint256 _value = 2**255;
    function mulTest() public constant returns (uint) {
        uint256 amount = 2 * _value;
        return amount;
    }
}

修复方式

严格使用 SafeMath 即可,合约的开发者是有防范意识的,所以引入了 SafeMath,但是计算的时候没有严格的使用。

反思

认真对待自己的代码,严格按照规范编程。

相关攻击





以上就是本篇文章的全部内容了,希望对你有帮助。

>> 本站不提供评论服务,技术交流请在 Twitter 上找我 @anbang_account