Unlock the vault to win the level. It’s set to locked and password protected at deployment, this is done using the bool public locked;
variable and the bytes32 private password;
variable, the problem is that this data is stored on chain, allowing anyone to determine what is being stored.
Private data shouldn’t be stored on-chain or it should be properly encrypted first.
And SWC Registry give’s us some good insight on variables, private doesn’t equate to unreachable.
It is a common misconception that
SWC-136, Unencrypted Private Data On-Chain.private
type variables cannot be read. Even if your contract is not published, attackers can look at contract transactions to determine values stored in the state of the contract. For this reason, it’s important that unencrypted private data is not stored in the contract code or state.
Let’s get to it.
Get a new instance, then copy and paste the contract over to Remix.
New file vault.sol
.
Compile, set your provider to MetaMask, copy and paste your instance address in the At Address
box.
Now we are going to use web3.eth.getStorageAt(contract.address, 1)
getStorageAt is a built in function in web3js
This should return the 32bytes password that is stored in slot 1.
I accomplished the same in the Ethernaut console like so:
Copy that return value and paste it into the unlock box, then transact.
All that’s left to do is submit our instance.
Congratulations, we just learned about private data on-chain.
DAVE