How to Exploit ETH Using Delegatecall and Selfdestruct – Security Insights

contract-designSecurity

This documentation says

Even if a contract’s code does not contain a call to selfdestruct, it can still perform that operation using delegatecall or callcode.

This worries me.

I've created some pseudo code to give a gist of a possible exploit. The code below creates an "exception: invalid opcode", but you'll be able to follow my logic. Assuming this style of attack works, what can be done to guard against it?

pragma solidity ^0.4.2;        
contract Steal{
      function delegatecall_selfdestruct(address _target) external returns (bool _ans) {
          _ans = _target.delegatecall(bytes4(sha3("selfdestruct(address)")), this); 
      }
}

contract Mark { 
  function Deposit() payable {
  }
}

The idea is to send some testnet ETH to the contract Mark then use the Steal contract to call Mark and make it selfdestruct and give the ETH to the Steal Contract.

Best Answer

It doesn't work to just call built-in Solidity functions in other contracts using delegatecall.

What delegatecall really does is call a function in another contract, which executes in the context of the first contract. It's really dangerous to make delegatecalls to contracts you don't trust. The documentation is warning you about this possibility:

pragma solidity ^0.4.2;        
contract Steal{
    address owner;
    function Steal() {
        owner = msg.sender;
    }
    function innocence() {
        selfdestruct(owner);
    }
}

contract Mark { 
    function Deposit() payable {}
    function call(address a) {
        a.delegatecall(bytes4(sha3("innocence()"))); 
    }
}

If Mark calls Steal, then Mark will selfdestruct.