Web3/The Ethernaut

[The Ethernaut] Vault

프레딕 2025. 1. 23. 17:25
728x90
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract Vault {
    bool public locked;
    bytes32 private password;

    constructor(bytes32 _password) {
        locked = true;
        password = _password;
    }

    function unlock(bytes32 _password) public {
        if (password == _password) {
            locked = false;
        }
    }
}

password를 알아내면 되는 문제이다.

password가 private이여서 일반적인 접근은 안된다.

다만, solidity는 private변수도 접근이 가능하다.

 

await web3.eth.getStorageAt("0x5ddb7cBC357dC96141232FBbDf8e14e5A5706e99",1);

해당 코드를 통해 contract의 1번째 storage에 접근 가능하다. (0번째는 locked, 1번째는 password)

 

그러면 32바이트만큼 읽을 수 있고 password가 32바이트니 이 값을 그대로 unlock에 넣어주면 된다.

 

주의 해야할 점은 password가 bytes32형식이여서 index값을 1로 줬지만 아래와 같은 경우에는 다르게 줘야한다.

 

1. 동적 데이터 (string, bytes, array, mapping....) 

- 32바이트 보다 큰 bytes형식이거나 동적 데이터일때

- 데이터가 keccak256(slot_number)로 계산된 해시된 슬롯에서 시작되기 때문에

  web3.utils.soliditySha3(1) 한 값을 index로 넘겨줘야함

 

2. 정적 데이터 (uint256, address ....)

- 이런 값은 그냥 1,2,3... 이렇게 넘겨줘도 됨

 

근데 위에는 지피티 피셜이고 실제로 비슷한 문제 여러번 풀었는데 그때마다 1 넣을때 되는얘가 있고 sha3한 값 넣어야 되는얘도 있어서 버전 차이가 있는 거 같다.

아직 왜그런진 모르겠는데 걍 때려봐야 알듯

728x90
반응형