前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >智能合约安全审计之路-整数溢出漏洞

智能合约安全审计之路-整数溢出漏洞

作者头像
Gcow安全团队
发布2020-03-19 18:28:09
3710
发布2020-03-19 18:28:09
举报
文章被收录于专栏:Gcow安全团队Gcow安全团队

描述:变量在参与运算的过程中,运算结果超出了变量类型所能表示的范围,导致实际存储的计算结果出错

核心问题:非预期的整数溢出将导致智能合约运行出错,影响合约的可靠性和安全性

基础知识

整数溢出的分类

整数上溢

整数下溢

整数的分类

有符号数(int)

无符号数(uint)

Solidity中的整数类型

int8/int16/int24/…/int256(int8表示-127~127)

uint8/uint16/uint24/…/uint256(uint8表示0~255)

漏洞合约分析

pragma solidity ^0.4.24;
 
contract IntOverflow{
 
    function addNumber(uint a, uint b) public constant returns (uint){
        uint c;
        c = a+b;
        return c;
    }
 
}

漏洞点:由于这里a、b的数值类型为uint256,a、b的最大值为2^256-1,当超过这个最大值即回到起点0从新开始,所以输出c值存在整数溢出

BTCR下溢增持漏洞分析

function distributeBTR(address[] address) onlyOwner {
    for (uint i = 0; i < addresses.length; i++){
        balances[owner] -= 2000 * 10**8;
        balances[address[i]] += 2000 * 10**8;
        Transfer(owner, addresses[i], 2000 * 10**8);
    }
}

漏洞点:通过在distributeBTR函数中调用onlyOwner管理员向指定的用户列表地址进行批量打款,这里就存在一个减法下溢漏洞,当balances[owner]小于2000 * 10**8的时候,这个时候balances[owner]就为负数,但是在uint数的表示范围之内,balances[owner]值就是一个超级大的数,管理员可以通过这个漏洞对自己的balances进行增持。

整数溢出分析

  • 可能产生溢出的操作:加(+)、减(-)、乘(x)
  • 操作数由攻击者可控(函数参数)
  • 上下文末对高危操作数进行有效校验
  • ERC20重点关注balanceOf[]、 allownce[]、 toitalBalance、 totalSupply
  • 溢出成功不代表一定有危害

漏洞预防

  • 有效的上下文校验

require()/assert()/revert()

  • 使用SafeMath

直接调用SafeMath函数

using safeMath for uint256

SafeMath库

pragma solidity ^0.4.24;
 
library SafeMath {
  function mul(uint256 a, uint256 b) internal pure returns (uint256) {
    if (a == 0) {
      return 0;
    }
 
    uint256 c = a * b;
    require(c / a == b);
 
    return c;
  }
 
  function div(uint256 a, uint256 b) internal pure returns (uint256) {
    require(b > 0); 
    uint256 c = a / b;
 
    return c;
  }
 
  function sub(uint256 a, uint256 b) internal pure returns (uint256) {
    require(b <= a);
    uint256 c = a - b;
 
    return c;
  }
 
  function add(uint256 a, uint256 b) internal pure returns (uint256) {
    uint256 c = a + b;
    require(c >= a);
 
    return c;
  }
 
 
  function mod(uint256 a, uint256 b) internal pure returns (uint256) {
    require(b != 0);
    return a % b;
  }
}
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-03-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Gcow安全团队 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 基础知识
  • 漏洞合约分析
  • BTCR下溢增持漏洞分析
  • 漏洞预防
  • SafeMath库
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档