Articles

Ethernaut - Level 07 - Force

Image courtesy of OpenZeppelin Ethernaut 07 - Force This level from Ethernaut, Force, provides us with an empty smart contract containing only some ASCII-art. The goal here is to send some ether to the contract using the selfdestruct() instruction. # Level 07 - Force ### Source Code // SPDX-License-Identifier: MIT pragma solidity ^0.6.0; contract Force {/* MEOW ? /\\_/\\ / ____/ o o \\ /~____ =ΓΈ= / (______)__m_m) */} Before explaining why this smart contract is vulnerable, let’s get familiarized with the function selfdestruct().

Ethernaut - Level 06 - Delegation

Image courtesy of OpenZeppelin Ethernaut 06 - Delegation This level from Ethernaut, Delegation, is about a special Solidity method called delegatecall(). To complete this level, we must understand how this low level function works, how it can be used to delegate operations to on-chain libraries, and what implications it has on execution scope. // SPDX-License-Identifier: MIT pragma solidity ^0.6.0; contract Delegate { address public owner; constructor(address _owner) public { owner = _owner; } function pwn() public { owner = msg.

Ethernaut - Level 05 - Token

Image courtesy of OpenZeppelin Ethernaut 05 - Token This level from Ethernaut, called Token, is a good exercise to become familiar with the integer underflow and integer overflow concepts. In this challenge you are given 20 tokens to start with and you will beat the level if you somehow manage to get your hands on any additional tokens. Preferably a very large number of tokens. // SPDX-License-Identifier: MIT pragma solidity ^0.

Ethernaut - Level 04 - Telephone

Image courtesy of OpenZeppelin Ethernaut 04 - Telephone This level from Ethernaut, called Telephone, is a good exercise to learn the nuances between tx.origin and msg.sender and why you should never use tx.origin for authentication purposes: // SPDX-License-Identifier: MIT pragma solidity ^0.6.0; contract Telephone { address public owner; constructor() public { owner = msg.sender; } function changeOwner(address _owner) public { if (tx.origin != msg.sender) { owner = _owner; } } } Solidity has a global variable, tx.

Ethernaut - Level 03 - Coinflip

Image courtesy of OpenZeppelin Ethernaut 03 - Coinflip The third level in Ethernaut, CoinFlip, is a good exercise that will teach you how to exploit pseudo randomness implementations in smart contracts. This contract will require you to correctly guess the outcome of a coin flip ten times in a row: // SPDX-License-Identifier: MIT pragma solidity ^0.6.0; import '@openzeppelin/contracts/math/SafeMath.sol'; contract CoinFlip { using SafeMath for uint256; uint256 public consecutiveWins; uint256 lastHash; uint256 FACTOR = 57896044618658097711785492504343953926634992332820282019728792003956564819968; constructor() public { consecutiveWins = 0; } function flip(bool _guess) public returns (bool) { uint256 blockValue = uint256(blockhash(block.

Ethernaut Challenges

Please read This is a work in progress article that will receive updates as we continue publishing detailed walkthroughs for each level. Ethernaut is OpenZeppelin Web3/Solidity based wargame to learn about Ethereum smart contract security and become familiar with programming principles in Solidity. Although the game was launched few years ago it has become a good place to start for those who are interested on security and smart contracts. Challenges are currently running on the Rinkeby testnet and you will require to use a Rinkey Faucet to get free testnet ETH and test the smart contracts.

Ethernaut - Level 01 - Fallback

Image courtesy of OpenZeppelin Ethernaut 01 - Fallback The first level from Ethernaut is pretty straightforward and we will use it to become familiar with some Solidity concepts and the Brownie framework that we will use to complete this challenge. The code for the smart contract that we must exploit is shown above: // SPDX-License-Identifier: MIT pragma solidity ^0.6.0; import '@openzeppelin/contracts/math/SafeMath.sol'; contract Fallback { using SafeMath for uint256; mapping(address => uint) public contributions; address payable public owner; constructor() public { owner = msg.

Ethernaut - Level 02 - Fallout

Image courtesy of OpenZeppelin Ethernaut 02 - Fallout The goal for this level is to claim ownership of the contract, which has the following implementation: // SPDX-License-Identifier: MIT pragma solidity ^0.6.0; import '@openzeppelin/contracts/math/SafeMath.sol'; contract Fallout { using SafeMath for uint256; mapping (address => uint) allocations; address payable public owner; /* constructor */ function Fal1out() public payable { owner = msg.sender; allocations[owner] = msg.value; } modifier onlyOwner { require( msg.sender == owner, "caller is not the owner" ); _; } function allocate() public payable { allocations[msg.

Ethernaut Challenges

August 3, 2022

Please read

This is a work in progress article that will receive updates as we continue publishing detailed walkthroughs for each level.

Ethernaut is OpenZeppelin Web3/Solidity based wargame to learn about Ethereum smart contract security and become familiar with programming principles in Solidity.

Although the game was launched few years ago it has become a good place to start for those who are interested on security and smart contracts.

Challenges are currently running on the Rinkeby testnet and you will require to use a Rinkey Faucet to get free testnet ETH and test the smart contracts.

This article is my little contribution to those interested on learning the basics on Ethereum smart contract security by providing guidance and explanations on how to solve each Ethernaut challenge using brownie framework. There are different approaches and frameworks that can be used, rather than the approach you will find here, so feel free to explore and learn from others.

You can find my solutions on my GitHub repository and a technical detailed explanation for each challenge below.

Let’s go over these Ethernaut’s challenges and learn few security aspects of smart contracts written in Solidity!

Ethernaut Challenges

0x0. Hello

0x1. Fallback

The first real challenge and a simple one actually. You have to become the contract’s owner, and you can achieve this by calling the contract’s fallback function. However, you must send some Ethers first and call the contribute function once. After that, you will become the legitimate owner and you will be able to call the withdraw method to steal all the funds.

You can read a walkthrough for this challenge here.

0x2. Fallout

This vulnerability is unlikely to occur on recent versions of Solidity. The problem with this contract is a typo in the Fal1out function, which can be called by anyone, thus becoming the contract’s owner.

You can read a walkthrough for this challenge here.

0x3 Coinflip

The goal in this challenge is to guess the coin flip ten times in a row. The contract uses the previous blockhash as the flip outcome. This challenge can be solved by creating a similar contract that mimics the same coin flipping logic and calls Ethernaut’s original contract with the result obtained.

You can read a walkthrough for this challenge here.

0x4 Telephone

The idea behind this challnge is to call the changeOwner function from a smart contract. So msg.sender will be the helper contract address while tx.origin will always refers to the address who started the original transaction. Once tx.origin != msg.sender is true, you will become the contract’s new owner.

You can read a walkthrough for this challenge here.

0x5 Token

The goal in this contract is to increase our balance. Despite there is a requirement that checks for potential overflows (require(balances[msg.sender] - _vaalue >= 0);), we are dealing with unsigned integers which are known to be prone to overflow and underflow issues. To pass this challenge we will have to call the transfer method with an amount of tokens greater than 20.

You can read a walkthrough for this challenge here.

0x6 Delegation

This challenge consists of a delegation contract that forwards any calls using delegatecall in its fallback function to a Delegate contract. To complete this challenge we must get familiar with the delegatecall instruction and understand that the call performed heere is executed in the caller’s context, thus the Delegate contract will access the Delegation owner storage variable and msg.sender. To pass this challenge you simply need to call the pwn() function in th Delegation contract, despite it doesn’t exist.

You can read a walkthrough for this challenge here.

0x7 Force

The purpose of this challenge is to send ether to the contract. Sending ether to a contract requires a fallback function to be implemented, however, one can force-send ether by calling the selfdestruct instruction on a contract containing ether.

You can read a walkthrough for this challenge here.