几个智能合约漏洞分析
    
    
    
        
            Created At : 
        
    
    
        
        
        
            Views 👀 :
                
            
        
        
        
    
    
    
    
    
      
        1、CVE-2018-11810
超额定向分配相关合约源码
漏洞点
| 12
 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;
 }
 
 | 
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 
 | // 5% for advisorsuint256 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
超额铸币相关合约源码
| 12
 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
下溢增持相关合约源码
| 12
 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
高卖低收相关合约源码
| 12
 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)最大值,发生整数溢出,从而变为一个极小值甚至归零
| 12
 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