Hacks Demonstrated and Explained Discussion

Feel free to ask questions or discuss below!

Itā€™s instructive to replicate the DAO hack, thanks for the example.

One critical concept that I overlooked is the fact that the Attacker contract has to have a balance in the DAO contract which is accomplished by using the Attacker.payMe() function call when setting things up. It wouldā€™ve been more clear to me to name it say Attacker.contribute() to reiterate that the attacker contract is obtaining a balance in the DAO with itā€™s address so it can successfully pull off the hack.

2 Likes

On the DAO hacks section I didnā€™t know if you were going to include the code, like Iā€™ve seen Filip do, so I started coding the contract from scratch as you did and that was educational on itā€™s own. I made a couple mistakes, one was not including payable on the anonymous function of the Attacker contract which was the hardest to trouble shoot, but it a learning experience to make it work like it should.

Great demonstration of DAO hack, thank you!

What is going in my mind is what basically happen if sending of Ether somehow fails
but balance was already set to 0. Does in this case contract trying to retrieve Ether is left without money,
because balance was set to 0, but transaction has failed?

Iā€™m trying to create this case, but I canā€™t find the way to make transaction fail,
but surely in real world scenario this can happen.

1 Like

RE: library freeze attack

One thing that wasnā€™t discussed is how the contract using the library could have protected itself from this vulnerability. Drawing from what Filip talked about in the last section, instead of hard coding the library address you could use the Proxy pattern.

I fiddled around with this concept a bit, but it seems the proxy pattern is a bit more complicated than the following- which complies but fails when the function is called. Iā€™m guessing it doesnā€™t like redefining the lib variable.

// constructor
function Fundraiser(address libAddress) {
        lib = Library(libAddress);
}

// allow the owner to point the library to a different address if needed
function initLibrary(address addr) onlyOwner {
        lib = Library(addr);
    }

An internet search for articles on the proxy pattern revealed something rather complicated using ā€˜delegatecallā€™:

1 Like

@ivan The solution you give to prevent the hack is missing one little thing:
You reset the balance of the sender from the mapping without storing it into a local variable, and therefore will then send 0 wei to the sender, even if his balance wasnt 0, because you are accessing the mapping after setting its value to 0.

8 Likes

Correct, just noticed that as well when I saw the video

4 Likes

I was wondering how to withdraw funds from the Fundraiser using the other addresses? I get error when trying to withdraw. How to withdraw inital deposit for each address?

I think the contract reverts if it fails so that the balance reverts to the previous balance not zeroā€¦ I havenā€™t looked at the code, but I think thatā€™s how that works.

1 Like

How I am able to prevent the parity hack? Just use a constructor with setting adress owner=msg.sender ? This would be enough or?

1 Like

In the parity hack the initialize function was the problem so without checking if the owner is calling this function you will still have an issue.

You should
initializing the library.
Creating a boolean to check if the init function has already been called or making it only accessible by the owner of the contract.
Making the init function internal.
or not creating a kill() function for a library were two ways to avoid this ā€œā€œhackā€ā€ ^^
oups

1 Like

Agree I think the video should be slightly updated to show correct way how to fix the hack @ivan @filip @gabba

Otherwise great job with the demonstration!

3 Likes

Yes you are right we should do something for it, thank you for the feedback @Filipo24

2 Likes

I noticed this as well. Apparently, the solution in the video is still flawed today.

As others have noted. The video ā€œDAO Hack - Replicating the Vulnerability Part 2ā€ correctly shows the attack, but the solution provided is incorrect since you are setting balances[msg.sender]=0 and then you send the value of balances[msg.sender which you have just made 0. :nerd_face:

wrong

balances[msg.sender] = 0;
msg.sender.call.value(balances[msg.sender])();

fixed

uint balanceAmount = balances[msg.sender];
balances[msg.sender] = 0;
msg.sender.call.value(balanceAmount])();

4 Likes

So basically the DAO hack could be prevented if the balance was updated to zero first before sending ether? Awww that sucks

Nice section! Very informative!

1 Like

could be prevented if the balance was updated to zero first before sending ether?

That is correct, keep that in mind :slight_smile:

Happy learning,
Dani

Regarding the library freeze, can we use a constructor to set the owner initially and then just remove the initOwner()? Would that fix the issue

Hi, in the DAO hack, @ivan
1- I didnā€™t understand how this : Fundraiser(fundraiserAddress).contribute.value(msg.value)() ; works,

I know that it will contribute money to the fundraiser but I donā€™t understand how it does that , it looks strange .

2- Here :
balances[msg.sender] = 0;
msg.sender.call.value(balances[msg.sender])();
This sounds incorrect , it should use for example :
uint amount = balances[msg.sender];
balances[msg.sender] = 0;
msg.sender.call.value(amount)();

3- I do not understand how an attacker can modify the fundraiser smart contract by adding this function:
function getFunds() returns (uint){
return address(this).balance;
}
if an attacker is able to modify the contract, this means that he can make modifications to make it insecure and then , he can attack it .

Regarding the topic of dependencies, Ivan was explaining about the removal of a dependent library which in turn, the smart contract using it, all of a sudden is not working.
In Android, any java programs or I believe in Node.js, if you have a dependent library, it will automatically download it, include or package it to your app. So if someone deleted it from the repository(or github), you app will not be affected and will still work, right?
So does it mean that solidity will always rely on that repository on where your dependent resides because it is not downloading it as part of the package?
So to be sure your smart contract will always work, you must have a copy of that library locally and part of your smart contract.
Does my question makes sense?