[Ethernaut CTF] Force

0xDave·2022년 10월 3일
0

Ethereum

목록 보기
28/112

소스코드


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

contract Force {/*

                   MEOW ?
         /\_/\   /
    ____/ o o \
  /~____  =ø= /
 (______)__m_m)

*/}

해결과제


Some contracts will simply not take your money ¯\_(ツ)_/¯

The goal of this level is to make the balance of the contract greater than zero.

  Things that might help:

    Fallback methods
    Sometimes the best way to attack a contract is with another contract.
    See the Help page above, section "Beyond the console"

컨트랙트의 balance를 올리면 된다.

해결과정


contract의 abi가 비어있는 상황. 그냥 컨트랙트에 이더를 보내면 안 되나? 그런데 컨트랙트가 이더를 받으려면 payable 키워드가 있거나 receive() 또는 fallback() 함수가 있어야 한다. 힌트에서 말한대로 다른 컨트랙트를 이용해야 될 것 같다.

구글링을 통해 해결방법을 찾았는데, 잠시 죄책감을 가졌었다. 당연히 구글링을 하지 않고서 방법을 알 수는 없다. 처음 CTF하는데 모르는 것이 당연하다. 구글링 하는 걸 답지 훔쳐보는 것과 같다고 생각하지 말자. Ethernaut을 통해 그 동안 몰랐던 개념을 알려고 하는 것이지 혼자서 끙끙 앓는다고 몰랐던 개념을 저절로 배울 수 있는 것이 아니다. 하나씩 배워나가면 된다.

selfdestruct()

컨트랙트에 이더를 강제로 보내려면 selfdestruct를 알아야 한다. selfdestruct 는 컨트랙트를 파괴하는 함수다. 해당 컨트랙트의 데이터를 삭제하고 자금을 지정된 주소로 보내는 역할을 한다. selfdestruct를 사용하는 이유는 여러가지가 있다.

  1. 컨트랙트가 해킹을 당했을 때 긴급하게 컨트랙트를 파괴시킬 경우
  2. 컨트랙트를 업그레이드 하고 나서 이전 정보가 필요 없을 때
    (완전히 다른 컨트랙트로 배포한 상황)
  3. 기능을 다 한 컨트랙트로 이제 더 이상 사용하지 않는 경우

공격 컨트랙트

selfdestruct() 기능을 추가한 컨트랙트를 하나 만들어서 터트리면 된다. 이 때 소량의 이더와 함께 인스턴스 주소를 인자로 넣어준 채로 attack 함수를 실행하면(remix 좌측 상단에 value 값을 준 채로 실행) 내가 만든 컨트랙트가 자폭하면서 컨트랙트에 있던 소량의 이더가 인스턴스로 전송된다.

profile
Just BUIDL :)

0개의 댓글