设为首页 - 加入收藏 ASP站长网(Aspzz.Cn)- 科技、建站、经验、云计算、5G、大数据,站长网!
热搜: 创业者 手机 数据
当前位置: 首页 > 服务器 > 安全 > 正文

浅谈AMR智能合约批量转账溢出漏洞

发布时间:2022-06-27 13:11 所属栏目:53 来源:互联网
导读:日前,互联网爆出AMR合约存在高危安全风险的交易,该合约存在批量转账溢出漏洞,当合约实现批量转账功能时,容易在计算通证增加量时发生溢出漏洞,BUGX.IO安全团队经过研究分析发现,同类漏洞仍在以太坊里面部分存在。 以下为漏洞分析过程: 原理 /** * @dev
  日前,互联网爆出AMR合约存在高危安全风险的交易,该合约存在批量转账溢出漏洞,当合约实现批量转账功能时,容易在计算通证增加量时发生溢出漏洞,BUGX.IO安全团队经过研究分析发现,同类漏洞仍在以太坊里面部分存在。
 
  以下为漏洞分析过程:
 
  原理
     /**
 
       * @dev Function is used to perform a multi-transfer operation. This could play a significant role in the Ammbr Mesh Routing protocol.
 
       *  
 
       * Mechanics:
 
       * Sends tokens from Sender to destinations[0..n] the amount tokens[0..n]. Both arrays
 
       * must have the same size, and must have a greater-than-zero length. Max array size is 127.
 
       *
 
       * IMPORTANT: ANTIPATTERN
 
       * This function performs a loop over arrays. Unless executed in a controlled environment,
 
       * it has the potential of failing due to gas running out. This is not dangerous, yet care
 
       * must be taken to prevent quality being affected.
 
       *
 
       * @param destinations An array of destinations we would be sending tokens to
 
       * @param tokens An array of tokens, sent to destinations (index is used for destination->token match)
 
       */
 
      function multiTransfer(address[] destinations, uint[] tokens) public returns (bool success){
 
          // Two variables must match in length, and must contain elements
 
          // Plus, a maximum of 127 transfers are supported
 
          assert(destinations.length > 0);
 
          assert(destinations.length < 128);
 
          assert(destinations.length == tokens.length);
 
          // Check total requested balance
 
          uint8 i = 0;
 
          uint totalTokensToTransfer = 0;
 
          for (i = 0; i < destinations.length; i++){
 
              assert(tokens[i] > 0);
 
              totalTokensToTransfer += tokens[i];
 
          }
 
          // Do we have enough tokens in hand?
 
          assert (balances[msg.sender] > totalTokensToTransfer);
 
          // We have enough tokens, execute the transfer
 
          balances[msg.sender] = balances[msg.sender].sub(totalTokensToTransfer);
 
          for (i = 0; i < destinations.length; i++){
 
              // Add the token to the intended destination
 
              balances[destinations[i]] = balances[destinations[i]].add(tokens[i]);
 
              // Call the event...
 
              emit Transfer(msg.sender, destinations[i], tokens[i]);
 
          }
 
          return true;
 
      }
 
  `totalTokensToTransfer += tokens[i];` 这一句溢出,溢出后,totalTokensToTransfer 变小了,从而绕过了 `assert (balances[msg.sender] > totalTokensToTransfer);` 的判断,这样就能花极少的token ,任意增加目标地址的token。
 
  漏洞复现
  1. 部署 AMR 合约。
  2. 因为需要攻击者 token 数量大于0,所以先使用管理员账户给攻击者地址充 token。
 
  3. 使用漏洞溢出攻击
  这里需要两个地址,一个是攻击者,另一个为其它地址,这里设置 0 地址就行。

(编辑:ASP站长网)

    网友评论
    推荐文章
      热点阅读