2

Here's a contract that I want to attack using recursive call:

contract Abstract {
    function foobar();
}

contract B {
    uint stateVar;
    function foo(Abstract someAddress){
        someAddress.foobar();
    }
    function bar(uint x) {
        stateVar = x;
    } 
}

Here's a malicious contract deployed at some other address:

contract MaliciousContract {
    function foobar() {
        //What do I need to put here to make **B.bar(255)** possible?
    }
} 

From solidity docs:

Any interaction with another contract imposes a potential danger, especially if the source code of the contract is not known in advance. The current contract hands over control to the called contract and that may potentially do just about anything. Even if the called contract inherits from a known parent contract, the inheriting contract is only required to have a correct interface. The implementation of the contract, however, can be completely arbitrary and thus, pose a danger. In addition, be prepared in case it calls into other contracts of your system or even back into the calling contract before the first call returns. This means that the called contract can change state variables of the calling contract via its functions. Write your functions in a way that, for example, calls to external functions happen after any changes to state variables in your contract so your contract is not vulnerable to a recursive call exploit.

What I'm trying to achieve is:

This means that the called contract can change state variables of the calling contract via its functions.

So, my actions are:

  • I call B.foo('maliciousContractAddress');
  • ...
1
contract MaliciousContract {
    function foobar() {
        //What do I need to put here to make **B.bar(255)** possible?
        B(msg.sender).bar(255);
    }
}

This is a good example to remind that calling the exploit a "recursive call" can be misleading, because the exploit does not call foo, it calls bar.

Reentrant attacks can use the initial function (foo) but it's important to be aware that re-entrancy can use any external or public function (and recall that the default for functions is public).

  • compiler throws an error Undeclared identifier B. I guess it means I need to add an abstract contract to MaliciousContract, right? Something like, contract B { function bar(uint x); }. – manidos Aug 14 '16 at 12:10
  • Right. (I pasted the whole question code in Solidity Browser so no issue that way. For quick testing, make it uint public statevar to get an accessor.) – eth Aug 14 '16 at 12:17
  • quick question. How did the DAO attacker knew the definition of the calling contract? Was the DAO source code available at the moment? – manidos Aug 14 '16 at 12:38
  • 1
    Yes, github.com/slockit/DAO Contracts should generally be open source otherwise it's hard for people to trust that it does what it claims to do. – eth Aug 14 '16 at 12:41
  • I've deployed these two contracts and couldn't reproduce the result. Out of gas exception was thrown and the state variable wasn't change. Is it the result of some sort of fix? Here's tx testnet.etherscan.io/tx/… – manidos Aug 14 '16 at 13:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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