ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Ethernaut 풀이] 이더리움을 해킹해보자 - 0.Hello Ethernaut
    BlockChain/Technology 2021. 8. 10. 22:38

    Ethernaut는 Web3/Solidity 기반의 게임으로 각 레벨마다 '해킹'을 해야하는 게임입니다. 플레이어는 이를 통해 이더리움 스마트 컨트랙트의 취약점을 직접 배울 수 있습니다.

     

    OpenZeppeline과 Smart Contract Auditing으로 유명한 Zeppeline team에서 제공하고 있으며, 총 15단계로 이뤄져 있고 각 레벨마다 컨트랙트의 취약점을 찾아내야 합니다. 100% 오픈 소스로 모든 레벨은 다른 플레이어가 기여한 것입니다. 

     

     


    The Ethernaut 

    사이트에 접속하면 아래와 같은 화면이 나옵니다. Play now 버튼을 눌러 게임을 시작할 수 있습니다.

    Ethernaut play하기

    https://ethernaut.openzeppelin.com/

     

    Ethernaut

     

    ethernaut.openzeppelin.com

     

     


    Level 0 Hello Ethernaut

     

    이 레벨은 게임을 플레이 하는 방법에 대해 매우 기본적인 사항을 안내합니다.

     

    1. Set up MetaMask

     

    먼저 꼭 세팅해야할 것은 메타마스크입니다. 메타마스크는 이더리움을 보유하고 송금 및 관리할 수 있는 암호화 화폐 지갑입니다. 구글 크롬 웹브라우저에서 플러그인으로 사용하는 크롬 확장 프로그램입니다. 메타마스크를 설치한 후 네트워크 선택기를 눌러서 'Rinkeby 테스트 네트워크'로 설정합니다. 

    → 메타마스크 설치하기(https://metamask.io/download.html)

     

    MetaMask Download

    A crypto wallet & gateway to blockchain apps

    metamask.io

    여기서 Rinkeby 테스트 네트워크를 사용하기 위한 테스트 이더를 받을 수 있습니다. SNS에 공개키를 포스트하고, 게시글 링크를 입력하여 이더를 얻습니다.

    → Rinkeby 이더 받기(https://faucet.rinkeby.io/)

     

    2. 브라우저 콘솔 열기

     

    Ethernaut은 브라우저 콘솔창에 메시지가 표시되고, 명령어를 입력할 수 있기 때문에 F12 or 개발자 도구(ctrl+shift+I)를 눌러 콘솔창을 엽니다. 

    콘솔창을 열면 이렇게 요란한? 환영의 메시지가 뜹니다.

    콘솔창에 player를 입력하면 항상 플레이어 주소를 볼 수 있습니다.

     

    3. console helpers 사용하기

     

    getBalance(player)를 입력하면 현재 이더 잔액을 볼 수 있습니다. 안나오면 앞에 await를 입력합니다.

    참고: "보류 중"이라고 나오더라도 실제 값을 보려면 promise를 확장해야 합니다. Chrome v62를 사용하는 경우 더 분명한 콘솔 환경을 위해 await getBalance(player)를 사용할 수 있습니다.

    게임을 플레이하는데 여러가지 필요한 도움말을 보려면 help()라고 입력하면 됩니다.

     

    4. 이더리움 컨트랙트

     

    다음 명령어를 입력합니다. 

    ethernaut

    이것은 게임의 주요 스마트 계약입니다. 이 개체를 가지고 노는 것은 게임의 다른 스마트 계약과 상호 작용 하는 방법을 배울 수 있습니다.

     

    5. ABI와 상호 작용하기

     

    Ethernaut는 Ethernaut.sol 컨트랙트를 래핑하는 TruffleContract 개체입니다. 컨트랙트의 ABI는 소유자와 같은 Ethernaut.sol의 모든 public method를 보여줍니다. 예를 들어 다음 명령어를 입력합니다.

    ethernaut.owner()

    ethernaut 컨트랙트의 소유자가 누구인지 알 수 있습니다.

    ethernaut.owner()로 소유자의 주소가 나타납니다.

    6. level instance를 얻기

     

    각 레벨을 플레이할 때 ethernaut 컨트랙트와 직접 상호 작용하지 않습니다. 대신에 level instance를 생성하도록 요청합니다. 메타마스크 창이 열리며, 가스비를 지불하여 컨트랙트를 배포할 수 있습니다. 블록체인에 배포가 완료되면 트랜잭션이 채굴이 됐다는 메시지와 생성된 Instance의 주소가 표시됩니다. 새로운 컨트랙트를 배포할 때에는 몇 초가 걸릴 수 있습니다.

     

    새로운 instance가 생성된 콘솔화면입니다.

    7. 컨트랙트 조사하기

     

    ethernaut 컨트랙트에서 했던 것처럼 컨트랙트 변수를 사용하여 컨트랙트의 ABI를 검사할 수 있습니다.

    contract를 입력합니다. 

    abi를 확인할 수 있는데, 펼치면 호출할 수 있는 public method를 확인할 수 있습니다.

     

    8. 컨트랙트와 상호작용하여 레벨 0 완료하기

     

    지금부터 level 0의 본격적 시작입니다. 콘솔 메시지를 통해 나오는 컨트랙트의 ABI를 확인하며 따라가면 듀토리얼을 완료할 수 있습니다.  

    contract.info()를 입력합니다.

    입력하면 콘솔에 위와 같은 힌트메시지가 나옵니다. 다음으로 컨트랙트의 info1() 함수를 확인합니다.

    이번에는 info2() 함수를 확인하며 인자로 "hello"를 넘깁니다.

    infoNum() 함수를 확인하면 다음으로 넘어가는 번호를 찾을 수 있습니다. 이런식으로 마지막 authenticate 함수의 패스워드를 입력하여 호출을 하면 level 0은 완료하게 됩니다. 패스워드를 찾으려면 앞에서 배운 힌트를 이용해야 합니다. 완료한 다음 Submit instance를 누르고, 메타마스크로 트랜잭션을 보냅니다. 트랜잭션이 처리되면 다음 단계로 넘어가는 격한 환영의 메시지와 함께 Source가 공개됩니다. 

    level 0을 클리어했을 때 나오는 콘솔창의 메시지

     

    Source 확인하기

    // SPDX-License-Identifier: MIT
    pragma solidity ^0.6.0;
    
    contract Instance {
    
      string public password;
      uint8 public infoNum = 42;
      string public theMethodName = 'The method name is method7123949.';
      bool private cleared = false;
    
      // constructor
      constructor(string memory _password) public {
        password = _password;
      }
    
      function info() public pure returns (string memory) {
        return 'You will find what you need in info1().';
      }
    
      function info1() public pure returns (string memory) {
        return 'Try info2(), but with "hello" as a parameter.';
      }
    
      function info2(string memory param) public pure returns (string memory) {
        if(keccak256(abi.encodePacked(param)) == keccak256(abi.encodePacked('hello'))) {
          return 'The property infoNum holds the number of the next info method to call.';
        }
        return 'Wrong parameter.';
      }
    
      function info42() public pure returns (string memory) {
        return 'theMethodName is the name of the next method.';
      }
    
      function method7123949() public pure returns (string memory) {
        return 'If you know the password, submit it to authenticate().';
      }
    
      function authenticate(string memory passkey) public {
        if(keccak256(abi.encodePacked(passkey)) == keccak256(abi.encodePacked(password))) {
          cleared = true;
        }
      }
    
      function getCleared() public view returns (bool) {
        return cleared;
      }
    }

     

    이제 문제 풀이를 위한 기본 준비를 마쳤습니다. 앞으로 한 문제씩 풀어가며 포스팅을 할 예정입니다. 스포가 포함되어 있으니 직접 풀고싶으신 분들은 ethernaut 사이트에 접속해 문제를 풀어보세요 !

    댓글

Designed by Tistory.