새소식

인기 검색어

Write Up/Ethernaut

[Ethernaut] Vault

  • -
반응형

// 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;
    }
  }
}

우리의 mission은 password를 풀어야 한다.

현재 locked는 true이다.

password는 private라서 접근을 못하는 데 어떻게 알 수 있을까??

이 문제을 풀기 위해선 Solidity의 저장영역의 구조를 알고 있으면 쉽다.

Solidity의 저장 영역은 총 4개이다.

  • Storage
  • memory
  • calldata
  • stack

이 중 영속적으로 저장을 하면서 변수나 함수가 저장되는 영역은 어디일까?? 바로 Storage이다.

Storage에는 변수와 함께 값도 같이 저장이 되어서 private이 걸려 있어도 접근할 수 있다. 왜냐하면 외부에서는 직접적으로 변수에는 접근을 할 수 없지만, 저장공간의 값에 접근을 하는 것이기 때문에 가능하다.

 

자 이제 문제로 들어와서 각 변수들은 Storage에 순차적으로 저장이 되는 데 slot하나당 32byte까지 저장할 수 있다.

만약 변수의 숫자가 32byte가 되지 않는다면 나머지는 0으로 채운다. 하지만 오른쪽과 같이 변수를 합쳐도 32byte가 안 넘으면 하나의 슬롯에 저장한다. 즉 a와 b는 slot2에 같이 저장돼있는 것을 확인할 수 있다.

다시 문제를 보면 현재 Contract에는 변수가 2개가 있다. locked와 password가 있기 때문에 slot0에는 locked가 slot1에는 password의 값이 있다.

 

그러면 Storage의 값을 보기 위해서는 getStorageAt(address _address, uint256 _index)함수를 써야 한다.

해당 _address의 _index에 들어있는 값을 확인할 수 있다.

slot1을 보면 password의 값을 볼 수 있다.

locked가 false가 뜨는 것을 확인할 수 있다.

반응형

'Write Up > Ethernaut' 카테고리의 다른 글

[Ethernaut] Re-entrancy  (0) 2023.02.07
[Ethernaut] King  (0) 2023.02.07
[Ethernaut] Force  (0) 2023.02.03
[Ethernaut] Delegation  (0) 2023.02.01
[Ethernaut] Token  (0) 2023.02.01
Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.