3

I want to understand the concept of reentrancy attack in a smart contract. I know that a Malicious contract starts executing the code of another contract and this results in reentrancy attack. It can happen when in a contract a function receives ether. In this case a fallback function comes into play. But I can't understand how a contract gets control of another contract and recursively calls its functions like withdraw(). Kindly explain me this concept using the following two contracts, i got from a research paper:

contract Malicious {
   uint balance;
   MyBank bank = MyBank(0xdeadbeef8badf00d...);
function Malicious(){
   balance = msg.value;
   bank.Deposit.value(balance)();
   bank.Withdraw.value(0)(balance); // forwarding gas
}
function (){ // fallback function
   bank.Withdraw.value(0)(balance);
}
}

I can see that the contract has a Deposit() function and an unnamed fall back function(). This fall back function is calling

Withdraw.value(0)(balance);

What does the above call mean (particularly why it has two set of parenthesis?) and how it becomes recursive?

I am also showing the bank contract:

contract MyBank {
   mapping (address=>uint) balances;
function Deposit() {
   balances[msg.sender] += msg.value;
}
function Withdraw(uint amount) {
   if(balances[msg.sender] >= amount) {
      msg.sender.send(amount);
      balances[msg.sender] -= amount;
   }
}
function Balance() constant returns(uint) {
   return balances[msg.sender];
 }
}

Zulfi.

  • If I add "<code> payable </code>" modifier in the Malicious constructor and keep the rest of the code same, will i still get reentrancy attack due to faulty code in the fall back function? – zak100 Sep 26 '18 at 22:59
3

A computer program or subroutine is called reentrant if it can be interrupted in the middle of its execution and then safely be called again before its previous invocations complete execution. The interruption could be caused by an internal action such as a jump or call, or by an external action such as an interrupt or signal. Once the reentered invocation completes, the previous invocations will resume correct execution. And doing this with some piece of code will causes an Reentrancy Attack.

Now let's see this line of code:

bank.Withdraw.value(0)(balance);

This line of code means, call the function Withdraw with argument balance such as Withdraw(balance) but also set the value of this function call as 0 which is done by value(0). So the in simple english we can say this line of code as:

There is a function in bank contract, named as Withdraw, set the value as 0, and pass the balance as function argument.

Let say the above line of code is as follows:

bank.Withdraw.value(0);

that mean, only set the value of function Withdraw as 0 but did not call.

Before going further to actual attack here, let me explain you a little bit about fallback functions in contract.

  • In Solidity, a contract may have precisely one unnamed function, which cannot have arguments, nor return anything.
  • Fallback functions are executed if a contract is called and no other function matches the specified function identifier, or if no data is supplied.
  • These functions are also executed whenever a contract would receive plain Ether, without any data, in this case it must be payable.

Now come to the actual attack. Your Malicious contract is actually an attacker contract, because it has a malicious fallback function.

function (){
   bank.Withdraw.value(0)(balance);
}

this function is actually calling again to bank contract by withdraw function which is actually a line of attack.

Now see the MyBank contract which is innocent baby contract and does not know that outside world is so cruel and called the external function from withdraw function.

function Withdraw(uint amount) {
   if(balances[msg.sender] >= amount) {
      msg.sender.send(amount);
      balances[msg.sender] -= amount;
   }
}

msg.sender.send(amount); this line is actually an external call to Malicious contract's fallback function before the execution of withdraw function completes. It becomes like this. Calling each other

And this function calling will continue unless MyBank contract drain out of all it's ether (via gas or value). The recursive tree will look like this

enter image description here

I hope this answer will help you.

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.