Pwnstar

Ethernaut Level 12(Privacy) 본문

Wargame/Ethernaut

Ethernaut Level 12(Privacy)

포너블처돌이 2023. 4. 5. 17:08

난이도 총 5단계에서 4단계 짜리 문제여서 겁을 좀 먹었는데 좀 많이 쉽다.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract Privacy {

  bool public locked = true;
  uint256 public ID = block.timestamp;
  uint8 private flattening = 10;
  uint8 private denomination = 255;
  uint16 private awkwardness = uint16(block.timestamp);
  bytes32[3] private data;

  constructor(bytes32[3] memory _data) {
    data = _data;
  }
  
  function unlock(bytes16 _key) public {
    require(_key == bytes16(data[2]));
    locked = false;
  }

  /*
    A bunch of super advanced solidity algorithms...

      ,*'^`*.,*'^`*.,*'^`*.,*'^`*.,*'^`*.,*'^`
      .,*'^`*.,*'^`*.,*'^`*.,*'^`*.,*'^`*.,*'^`*.,
      *.,*'^`*.,*'^`*.,*'^`*.,*'^`*.,*'^`*.,*'^`*.,*'^         ,---/V\
      `*.,*'^`*.,*'^`*.,*'^`*.,*'^`*.,*'^`*.,*'^`*.,*'^`*.    ~|__(o.o)
      ^`*.,*'^`*.,*'^`*.,*'^`*.,*'^`*.,*'^`*.,*'^`*.,*'^`*.,*'  UU  UU
  */
}

코드를 보면 여러 변수들이 있고, 마지막에 bytes32 배열이 존재한다.locked 변수를 false로 만들면 되는데, 그 조건은 data[2]를 bytes16으로 캐스팅한 값과 같아야 한다는 것이다.

우선 web3.eth.getStorageAt() 함수로 각 변수의 값을 좀 살펴보자.

locked 변수와 ID(block.timestamp) 변수의 값.

여기에는 세 변수의 값이 함께 들어가 있는데, 이렇게 되어 있는 이유는, storage 공간을 더 효율적으로 활용하기 위해서라고 한다.

하위 1바이트(0x0a)는 flattening의 값(10)이고, 그 다음 1바이트(0xff)는 denomination의 값(255)이다.

그 다음 두 바이트는 block.timestamp값을 uint16형으로 캐스팅한 값이고, block.timestamp값의 하위 2바이트의 값을 가지고 있다.

bytes32 배열의 값들이다.

data[2]의 값은 맨 마지막 값일테고, 이 값을 bytes16으로 캐스팅하면 block.timestamp와 마찬가지로 하위 16바이트일 것이라고 생각했는데, 그게 아니었다.

그 이유는 아직도 모르겠지만 상위 16바이트를 매개변수로 unlock함수를 호출해주면 문제를 해결할 수 있다.


Uploaded by N2T

'Wargame > Ethernaut' 카테고리의 다른 글

Ethernaut Level 11(Elevator)  (0) 2023.04.05
Ethernaut Level 10(Re-entrancy)  (0) 2023.04.04
Ethernaut Level 9(King)  (0) 2023.04.03
Ethernaut Level 8(Vault)  (0) 2023.04.03
Ethernaut Level 7(Force)  (0) 2023.04.03
Comments