Ethernaut Challenge #2 솔루션 — Fallout

이것은 "Let's play OpenZeppelin Ethernaut CTF" 시리즈의 2부입니다. 각 문제를 해결하는 방법을 설명하겠습니다.

The Ethernaut is a Web3/Solidity based wargame created by OpenZeppelin.
Each level is a smart contract that needs to be 'hacked'. The game acts both as a tool for those interested in learning ethereum, and as a way to catalogue historical hacks in levels. Levels can be infinite and the game does not require to be played in any particular order.



과제 #2: 낙진



Claim ownership of the contract below to complete this level.

Things that might help

  • Solidity Remix IDE

Level author(s): Alejandro Santander



계약 연구



가장 먼저 눈에 띄는 것은 사용된 Solidity 컴파일러 버전이 < 0.8.x 입니다. 이것은 계약이 수학 언더플로 및 오버플로 버그가 발생하기 쉽다는 것을 의미합니다.

이 계약은 OpenZeppelinSafeMath 라이브러리를 가져와서 사용하므로 오버플로우/언더플로우 문제에 대해 안전해야 합니다.

이 문제는 매우 독특하며 Solidity 보안 주제를 처음 접하는 경우 이 문제를 해결하는 방법을 이해하기 어려울 수 있지만 이유는 단 하나입니다. 이 문제는 이전에만 존재했습니다Solidity 0.4.22.

이전Solidity 0.4.22에는 계약에 대한 생성자를 정의하는 유일한 방법은 계약 자체와 동일한 이름으로 함수를 정의하는 것이었습니다.
무엇이 잘못될 수 있는지 상상할 수 있습니다... 컨트랙트의 이름을 가져야 하는 생성자 함수를 정의했다고 생각하지만 작성하는 동안 오타를 범했습니다... 함수는 컨트랙트로 인식되지 않기 때문에 자동으로 호출되지 않습니다. 더 이상 생성자이므로 생성 시 계약이 초기화되지 않습니다.

그 Solidity 버전 이후, 그들은 이런 종류의 실수를 피하기 위해 새로운constructor 키워드를 도입했습니다.

코드를 보면 컨트랙트의 이름은 Fallout인데 생성자 함수는 Fal1out라고 합니다. 오타가 보이시나요? 그들은 l 대신 1을 사용했습니다.
해당 오타로 인해 계약이 배포될 때 생성자 함수가 생성 시 실행되지 않으며 owner 변수가 업데이트되지 않습니다. 이는 Fal1out가 이제 "정상"기능으로 간주되기 때문입니다.

솔루션 코드



이 문제의 해결 방법은 매우 쉽습니다. 한 번도 호출된 적이 없는 Fal1out 함수를 호출하기만 하면 됩니다.

function exploitLevel() internal override {
    vm.startPrank(player);

    // Before Solidity 0.4.22 the only way to define a constructor for a contract was to define a function with the same name of the contract itself
    // After that version they introduced a new `constructor` keyword to avoid this kind of mistake
    // In this case the developer made the mistake to misstype the name of the constructor
    // Contract name -> Fallout
    // Constructor name -> Fal1out
    // The result of this is that the contract was never initialized, the owner was the address(0)
    // and we were able to call the `Fal1out` function that at this point is not a constructor (callable only once)
    // but a "normal" function. This also mean that anyone can call multiple time this function switching the owner of the contract.
    level.Fal1out();

    vm.stopPrank();
}


챌린지 오프닝의 전체 솔루션을 읽을 수 있습니다Fallout.t.sol.

추가 자료


  • SWC-118 - Incorrect Constructor Name

  • 부인 성명



    이 리포지토리의 모든 Solidity 코드, 관행 및 패턴은 DAMN VULNERABLE이며 교육 목적으로만 사용됩니다.

    나는 어떠한 보증도 하지 않으며 이 코드베이스의 사용으로 인해 발생하는 손실에 대해 책임을 지지 않습니다.

    생산에 사용하지 마십시오.

    좋은 웹페이지 즐겨찾기