Force
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract Force {/*
MEOW ?
/\_/\ /
____/ o o \
/~____ =ΓΈ= /
(______)__m_m)
*/}
Goal
We need to find a way to send ETH to the Force contract
Exploit
In order for a smart contract to be able to receive ETH it should have fallback() and/or receive() functions implemented.
As we can see our Force smart contract is empty so it seems it is not possible to send ETH to it, or maybe it is :). Let's find out.
Every smart contract in Solidity can call a special function called selfdestruct. What this function does is deleting the contract from the blockchain and sending all remaining ETH stored in the contract to a designated address. More info can be found here.
So, how can we make use of selfdestruct to solve the CTF. We can create another smart contract (Attacker), call the selfdestruct function on the Attacker contract, and set the address of the Force contract as a designated target for sending the ETH
To exploit the contract we need to:
- create Attacker contract, and send the address of the Force contract inside the Attacker contract
- the constructor of the Attacker smart contract should be payable in order to be able to receive ETH while instantiating the contract (we will send this ETH on contract creation)
- create external destruct() function inside Attacker contract, this function will call selfedstruct with the Force address as argument
- call the destruct() function
Attacker contract code
contract Attacker {
address private forceContractAddress;
// send 1 ETH to the contract on creation
constructor(address _force) payable {
forceContractAddress = _force;
}
function destruct() external {
selfdestruct(forceContractAddress);
}
}