ethernaut vault

The Ethernaut Level 9 : Vault

Solution to Vault challenge of The Ethernaut

--

Introduction to challenge

The Ethernaut is a Web3/Solidity based wargame inspired on overthewire.org, played in the Ethereum Virtual Machine. Each level is a smart contract that needs to be ‘hacked’. The game is 100% open source and all levels are contributions made by other players. Please complete this challenge to better understand the game.

Ethernaut challenge : https://ethernaut.openzeppelin.com/

All Problems

Smart Contract to Hack!!

Task

Unlock the vault to pass the level!

Things that might help

Checkout storage layout of the contract

Understanding the contract

line 8–11 Here in the constructor we set the value of password and locked variable. To complete the task we need to somehow change the state of locked to false.

line 13–16 We can do this using unlock() method but that requires us to have the value of password to unlock it.

Solution

The solution is even if the variable is marked as private we can see its value on the blockchain!! Yes if that shocked you read it again. Marking a variable as private only prevents other smart contracts from accessing it. We can access any storage variable by looking at the storage layout of the contract.

Now let us understand the storage layout to solve the challenge.

Each smart contract on the Ethereum Virtual Machine can store its values of its variables on a permanent storage. This permanent storage is like a array and each block of this array can store 32 bytes of data in it. This blocks are also knows as slots. There are total of 2²⁵⁶ of these slots. Well if you are thinking what if that is exhausted? Where will the new smart contract store its variables. Then let me tell you this number is far greater than the number of atoms on entire earth. So, at least in this lifetime we won’t face that issue.

Lets look at the simplified storage model of our smart contract to understand it better. There are 2 variables in our smart contract locked and password. It would look something like this on the permeant storage.

Simplified version of memory Layout

Now if we know the address of smart contract we can also access its storage memory and get the value of the password. We can use libraries like ethersjs , web3, etc. Here in our console we have instance of web3 so we’ll go with that.

  • You can get your ethernaut contact address using following line in console
    await contract.address
  • To get the value of slot 1 (where password is stored) run following code.
    await web3.eth.getStorageAt(“<contract address>”,1) . Here First parameter is the contract address and the second is the slot number.
  • Copy the value and call unlock() method in contract with that value.
    await contract.unlock(“<Copied Value>”).
  • Check the value of locked and submit the instance.

Conclusion

It’s important to remember that marking a variable as private only prevents other contracts from accessing it. State variables marked as private and local variables are still publicly accessible. Hence we should avoid storing any password or API key in the smart contract. One way to store them safely is encrypt its value and then store it. This way no one can get the value unless they have the encryption.

This challenge was very quick to solve but writing this article took more time. Please appreciate with a 👏(clap) it you got anything meaningful from it. Also, correct me if I miss anything in the comments.

Join Coinmonks Telegram Channel and Youtube Channel learn about crypto trading and investing

Also, Read

--

--

Kevin
Coinmonks

I am a Software Developer with experience in Data Engineering and Machine learning. Currently on look out for new opportunity.