几个智能合约漏洞分析
    
    
    
        
            Created At : 
        
    
    
        
        
        
            Views 👀 :
                
            
        
        
        
    
    
    
    
    
      
        1、CVE-2018-11810
超额定向分配相关合约源码
漏洞点
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
   | function allocate(address _address, uint256 _amount, uint8 _type) public onlyOwner returns (bool success) {     // one allocations by address     require(allocations[_address] == 0);     if (_type == 0) { // advisor         // check allocated amount         require(advisorsAllocatedAmount + _amount <= ADVISORS_AMOUNT);         // increase allocated amount         advisorsAllocatedAmount += _amount;         // mark address as advisor         advisors[_address] = true;     } else if (_type == 1) { // founder         // check allocated amount         require(foundersAllocatedAmount + _amount <= FOUNDERS_AMOUNT);         // increase allocated amount         foundersAllocatedAmount += _amount;         // mark address as founder         founders[_address] = true;     } else {         // check allocated amount         require(holdersAllocatedAmount + _amount <= HOLDERS_AMOUNT + RESERVE_AMOUNT);         // increase allocated amount         holdersAllocatedAmount += _amount;     }
  | 
 
1 2 3 4 5 6 7 8 9 10 11 12
   | // 5% for advisors     uint256 constant ADVISORS_AMOUNT =   5 * onePercent;     // 15% for founders     uint256 constant FOUNDERS_AMOUNT =  15 * onePercent;     // 60% sold in pre-sale     uint256 constant HOLDERS_AMOUNT  =  60 * onePercent;     // 20% reserve     uint256 constant RESERVE_AMOUNT  =  20 * onePercent;     // ADVISORS_AMOUNT + FOUNDERS_AMOUNT + HOLDERS_AMOUNT +RESERVE_AMOUNT     uint256 constant INITIAL_AMOUNT  = 100 * onePercent;     // 20% for holder bonus     uint256 constant BONUS_AMOUNT    =  20 * onePercent;
   | 
 
- 分别对应上述漏洞点中的三个require,主要的发生位置即为转账数额。allocate中_amount是可控的,同时为uint256,那么向上溢出可以使得和为0,满足require条件,但下面的加钱操作会使得数额超出限制。
 
- 以5%的为例,使用两个账户测试,首先计算最大的数额
 

- 可以看到当超出这个范围时就会失败


 
- 将传入的金额为2^256 - 最大规定数额,那么溢出后为0,满足条件



 
2、CVE-2018-11809
超额铸币相关合约源码
1 2 3 4 5 6 7 8 9
   | function mint(address _holder, uint256 _value) external icoOnly {   require(_holder != address(0));   require(_value != 0);   require(totalSupply + _value <= tokenLimit);
    balances[_holder] += _value;   totalSupply += _value;   Transfer(0x0, _holder, _value); }
  | 
 
3、CVE-2018-11687
下溢增持相关合约源码
1 2 3 4 5 6 7
   | function distributeBTR(address[] addresses) onlyOwner {     for (uint i = 0; i < addresses.length; i++) {         balances[owner] -= 2000 * 10**8;         balances[addresses[i]] += 2000 * 10**8;         Transfer(owner, addresses[i], 2000 * 10**8);     } }
  | 
 
- 通过BitcoinRed函数中balances (owner)限制上限,执行多次balances(addresses)的加操作后,可以整型上溢出,同时因为没有判断Owner的账户是否有足够的余额,所以导致了减法的整型下溢出.
 
4、CVE-2018-11811
高卖低收相关合约源码
1 2 3 4 5 6
   |  function sell(uint256 amount) {       require(this.balance >= amount * sellPrice);            _transfer(msg.sender, this, amount);                   msg.sender.transfer(amount * sellPrice);            } }
  | 
 
- 漏洞描述:sellPrice被修改为精心构造的大数后,可导致amount * sellPrice的结果大于整数变量(uint256)最大值,发生整数溢出,从而变为一个极小值甚至归零
 
1 2 3 4 5 6 7 8 9 10
   | function setPrices(uint256 newSellPrice, uint256 newBuyPrice) onlyOwner {       sellPrice = newSellPrice;       buyPrice = newBuyPrice;   }
    /// @notice Buy tokens from contract by sending ether   function buy() payable {       uint amount = msg.value / buyPrice;               // calculates the amount       _transfer(this, msg.sender, amount);              // makes the transfers   }
  | 
 
- 根据以上两个函数setPrices与buy修改sellPrice的值,造成溢出.
 
      
       
 转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 1259742453@qq.com