zoukankan      html  css  js  c++  java
  • 智能合约安全-parity多重签名钱包安全漏洞

    漏洞原因:

        因为initWallet函数是公开函数( public function) , 攻击者调用initWallet,重新初始化钱包会把之前合约钱包所有者覆盖, 即可改变钱包所有者。 

    漏洞代码:

      // constructor - just pass on the owner array to the multiowned and
      // the limit to daylimit
      function initWallet(address[] _owners, uint _required, uint _daylimit) {
        initDaylimit(_daylimit);
        initMultiowned(_owners, _required);
      }
     
      // constructor - stores initial daily limit and records the present day's index.
      function initDaylimit(uint _limit) {
        m_dailyLimit = _limit;
        m_lastDay = today();
      }
     
      // constructor is given number of sigs required to do protected "onlymanyowners" transactions
      // as well as the selection of addresses capable of confirming them.
      function initMultiowned(address[] _owners, uint _required) {
        m_numOwners = _owners.length + 1;
        m_owners[1] = uint(msg.sender);
        m_ownerIndex[uint(msg.sender)] = 1;
        for (uint i = 0; i < _owners.length; ++i)
        {
          m_owners[2 + i] = uint(_owners[i]);
          m_ownerIndex[uint(_owners[i])] = 2 + i;
        }
        m_required = _required;
      }

    修复方法:

    设置 initMultiowned 和 initDaylimit 禁止外部调用,给initWallet添加only_uninitialized函数修改器,确保initWallt只被调用一次。

    安全修复代码:

      // throw unless the contract is not yet initialized.
      modifier only_uninitialized { if (m_numOwners > 0) throw; _; }
    
      // constructor - just pass on the owner array to the multiowned and
      // the limit to daylimit
      function initWallet(address[] _owners, uint _required, uint _daylimit) only_uninitialized {
        initDaylimit(_daylimit);
        initMultiowned(_owners, _required);
      }
    
      // constructor - stores initial daily limit and records the present day's index.
      function initDaylimit(uint _limit) internal {
        m_dailyLimit = _limit;
        m_lastDay = today();
      }
    
      // constructor is given number of sigs required to do protected "onlymanyowners" transactions
      // as well as the selection of addresses capable of confirming them.
      function initMultiowned(address[] _owners, uint _required) internal {
        m_numOwners = _owners.length + 1;
        m_owners[1] = uint(msg.sender);
        m_ownerIndex[uint(msg.sender)] = 1;
        for (uint i = 0; i < _owners.length; ++i)
        {
          m_owners[2 + i] = uint(_owners[i]);
          m_ownerIndex[uint(_owners[i])] = 2 + i;
        }
        m_required = _required;
      }  

    POC

    web3.eth.contract(MultiSigParityAbit).at(Vulnerable_Address).initWallet.getData([YOUR_ADDRESS], 1,2000000000000000000)

    POC未测试,待测。

     REF:http://shellcode.se/programming/simple-mistake-leads-to-30m-usd-theft/

  • 相关阅读:
    聊聊Mysql索引和redis跳表 ---redis的有序集合zset数据结构底层采用了跳表原理 时间复杂度O(logn)(阿里)
    各种排序算法的时间复杂度和空间复杂度(阿里)
    HashMap默认加载因子为什么选择0.75?(阿里)
    深入分析Synchronized原理(阿里面试题)
    Gflags 简明使用
    析构函数 (C++)
    C++11学习
    Visual Studio Code 构建C/C++开发环境
    C++经典排序算法总结
    C++迭代器失效的几种情况总结
  • 原文地址:https://www.cnblogs.com/xiaoxiaoleo/p/7209752.html
Copyright © 2011-2022 走看看