Solving CaptureTheEther - Part 1 of 5 - Warmup
Overview
This is the first post in a series about the Ethereum security introductory CTF "CaptureTheEther". There will be a total of five posts, each one of them focused in one of the categories of the game. For each level I'll describe the contract, the vulnerability, the solution I used and a conclusion about what to check when developing or auditing smart contracts.
I used Remix to solve most of the challenges of this game, so my solutions and procedures will be tied to that IDE. The wallet provider I use is Metamask.
The "Warmup" category consists in three really easy to solve challenges, meant for the player to test the tools and/or environment that is going to be used for the rest of the game.
Info
All my solutions to CaptureTheEther were coded some time ago, while I was still new at Solidity and EVM. All of them work, however they certainly don't meet any good coding recommendation whatsoever.
It was part of my learning path, and I don't intend to update them as it serves me (and hopefully you too!) as a remainder that learning is a never-ending process that rewards you when you look back and see your real progress.
The complete code for these solutions is at my CTE-Solutions github repo.
Deploy a contract
Nothing to do here, just deploy the contract. This will help you check if your wallet provider is correctly connected, and that you have
some Ropsten testnet ether to deploy the contract.
As stated in the instructions, once you deploy the contract, click on Check solution
to solve the challenge.
Contract analysis
It is a very simple contract that exposes a single pure public function called isComplete()
. All this function does is return a boolean true,
that indicates that the level is complete. This structure will repeat in future challenges, so it's important to read and understand the
structures of the contracts.
Vulnerability / Attack vector
There is none in this level.
Solution
Stated in the challenge description. Deploy the contract and hit the Check solution
button.
Conclusions
This introductory level will help you understand a few key concepts of the Ethereum network and the mechanics of the CTE game:
- The process of wallet provider connection to a Web3 site.
- The approval of transactions.
- The interaction with smart contracts from a Web3 site.
If all this works correctly in your setup, you're all set to solve the rest of the challenges.
Call Me
The next challenge tests our capability of calling functions in deployed contracts. When the Begin challenge
button is clicked, the contract will
be deployed and its address will be shown.
Contract analysis
The deployed contract has a public boolean variable called isComplete
initialized to false. The goal is to call the callme()
public function to
change the state of the boolean flag.
Vulnerability / Attack vector
Still none.
Solution
Calling a function of a deployed contract using Remix, needs either the ABI for that contract, or the source code. Since the code is known, you can compile it and then go to the Deploy and run transactions tab at the left side of the Remix interface, and paste the address where the contract is deployed. If everything goes as expected, the IDE will show a button for each function and getter in the deployed contract. Clicking the button will trigger a transaction that, once approved, will call the function.
Finally, to solve the level, go back to the challenge page and check the solution.
Conclusions
Building on the previous level knowledge, now you can call functions on deployed contracts using Remix IDE. This will be useful in some challenges, although most of them will need an additional layer of coding. The takeaway of this level is that, whenever you know the ABI or the code of a deployed contract, you can call its public functions and interact with the network using your wallet provider.
Choose a nickname
This level will let you identify yourself as a player with a name. You can choose whatever name you like.
Contract analysis
The code section shows two contracts.
The first one is the CaptureTheEther
contract, and it's just showing the relevant part for this challenge. There's a mapping from addresses to
bytes32 that stores the nicknames for every address, and a setNickname(bytes32)
function to change the nickname of the msg.sender
.
This contract is already deployed at 0x71c46Ed333C35e4E6c62D32dc7C8F00D125b4fee
.
The second contract is NicknameChallenge
, and it has a isComplete()
function that verifies that the first letter of your nickname is different
to 0
, or, in other words, that you have set your nickname. As stated in the level description, you don't have to interact with this contract.
Vulnerability / Attack vector
Guess what? None.
Solution
To solve, you have to copy CaptureTheEther
contract code to Remix, and then interact with the setNickname(bytes32)
function in the Deploy and
run transaction tool.
Strings in Solidity are left-aligned, that is, the first character in the string is the highest value byte of the storage word. The argument
to the function must be 32 bytes long, so you need to pad the string with the hex value 00
up to a length of 32 bytes.
If the transaction was correct, the chosen name should be visible in the top right corner of the CaptureTheEther website.
Conclusions
This is similar to the previous challenge, in that you have to call a function of a deployed contract. However, this time the function needs some data as parameters, and the type of the data passed should match what the function expects.
Further information on Solidity data types and function arguments can be read at the official website of Solidity documentation.