Ethernaut ‘Vault’ Problem

Christian Ruink
Coinmonks
4 min readMay 17, 2018

--

A soft touch… A quick glance

This is the fourth time I write about one of the awesome Ethereum security problems at: Ethernaut, and I have become exceedingly efficient at it! Let’s get started.

The “Vault” contract

Unlock the vault to pass the level!

This one definitely has a different flavor than other problems we’ve faced so far. There are potentially two routes we can take to open this vault:

  1. Brute force it somehow, through a vulnerability unlock the vault without knowing the password.
  2. Use our guile to get our hands on the secret password.

Honestly, 1 is just a waste of time, this contract is so simple that there’s really not much room for acrobatics, the only way we’re getting through is if we learn the password. So, what do we know about the password at this early stage?

Know thy Target 👀

Password is a storage variable, type bytes32 with private access. The last point is worth clarifying, as per the docs here’s what the different access types mean:

  • external: all, only externally
  • public: all (this is the default), externally and internally
  • internal: only this contract and contracts deriving from it, only internally
  • private: only this contract, only internally

Basically, that means we can’t just go contract.password() on our console and call it a day. Notably if password had internal visibility we could inherit from this contract and access the password variable through the son!

This works

With the private accessibility though, only internal calls from the very same contract can access them. At this point, you can feel defeated or remember that Ethereum is a public ledger detailing millions of transactions in a completely transparent way for the eyes of the world to see. This means we can just query the contract for it’s storage. This fact won’t change, no matter how carefully you encapsulate delicate variables in your contract.

Spelunking Storage 🐚

So, how do we unofficially inspect a contract? (That is, through the public ledger and not the neat and tidy implementation of the contract itself)

Enter web3 the js library for interacting with the Ethereum blockchain.

It’s been available for Ethernauts all along…

The method we’re interested in is the aptly name web3.eth.getStorage. Takes a contract address, an integer (index!) and if you’re using Metamask you’re going to also have to pass a callback function to avoid unnecessary freakouts.

Wait a minute, indexes? Yes! We’re not querying the entire storage, we’re getting it piecemeal and luckily the storage is organized in a pretty straightforward way.

Each storage element is indexed accordingly to the order they’re defined in. In the case of the vault contract, the locked storage variable has index 0, and that juicy password has index 1.

Put it all together and:

You’re going to get a hexadecimal string as a result here, so if you want to make sure you’ve got the right variable why don’t you try converting that result to Ascii?

Conclusion

This problem is meant to drill home this simple fact: “Everything is public on a public blockchain”. The information asymmetry of a client / server application is not present in a client / blockchain environment.

Think on that before uploading your DNA to the blockchain with a “private” visibility.👩‍🔬

If you want to know more about inspecting Ethereum smart contracts check out this great write-up by Darius, famous TSM toplaner!

Join Coinmonks Telegram Channel and Youtube Channel get daily Crypto News

Also, Read

--

--