Cryptography / Cryptocurrency


Arizona CTF 2025.

This module explores problems in two forms of "crypto": cryptography and cryptocurrency. These are different, but the name collision has put both here!


Lectures and Reading

Smart contracts are self-executing programs that run on a blockchain. They allow you to encode business logic and agreements directly into code that cannot be altered once deployed (immutable).

Key Concepts

  • Solidity:
    Solidity is the primary programming language for writing smart contracts on the Ethereum Virtual Machine (EVM). It is statically typed and contract-oriented, meaning it organizes code into contracts similar to classes in object-oriented programming.

  • Contracts:
    A contract is like a blueprint for your decentralized application. It contains state variables, functions, and events that define its behavior and interactions. When you write a contract, you choose a descriptive name (e.g., Exploit, Token, Voting) that reflects its purpose.

  • Deployment:
    Deploying a smart contract means publishing it to the blockchain, where it becomes immutable and available for interaction. The deployment process involves compiling your Solidity code and sending it to the network, usually using tools like Foundry, Truffle, or Hardhat.

Solidity File and Contract Names

When working with Solidity, it's important to understand the distinction between the Solidity file name and the contract name within that file:

Solidity File Name

  • Definition:
    The Solidity file name (e.g., MyContract.sol) is the name of the file containing your Solidity code.
    A file named MyContract.sol might contain one or more contracts related to different functionalities.

Contract Name

  • Definition:
    The contract name is declared inside the Solidity file and defines the actual smart contract, which contains state variables, functions, and events.
    In MyContract.sol, you might have a main contract declared as contract MyContract { ... } and other contracts if needed.

Recommended Resources

  • Solidity Documentation:
    Comprehensive official documentation for learning and mastering Solidity.
    Solidity Docs

  • Ethereum Smart Contract Best Practices:
    A guide to secure smart contract development and common patterns.
    Smart Contract Best Practices

  • Solidity By Example:
    A collection of practical examples to help you quickly understand Solidity concepts.
    Solidity By Example

  • OpenZeppelin:
    Provides a library of secure and community-vetted smart contracts which you can use as building blocks.
    OpenZeppelin Contracts

  • Cyfrin:
    Tutorials on smart contract development and blockchain security.
    Cyfrin

  • Rareskills:
    Practical tutorials and modern resources for blockchain and smart contract development.
    Rareskills

This guide explains how to use the blockchain command to interact with the challenge. Whether you're starting a blockchain, stopping it, checking your progress, or deploying a solution, this script makes it simple. Below, we’ll go through each command step-by-step.

  1. Initialize the Environment:
    blockchain init

    • This command initializes the blockchain environment and starts the server.
    • Note: The server will start and its logs will be visible. Keep this terminal open while working on the challenge.
  2. Start the Blockchain:
    blockchain start

    • This command starts a new private blockchain instance. It parses the output from the server and updates the configuration file (Config.sol) with the new values.
    • Note: You can only use this command once which is when you start the challenge.If by any chance, you need a new instance of the private blockchain use blockchain restart.
  3. Copy Challenge Files:
    cp -r /challenge /home/hacker/name_of_your_folder
    Copy the content of /challenge directory to /home/hacker to ensure you can write your exploits and save your files in a permanent way even if you restart the challenge, your progress won't be lost. (No need to change user.)

  4. Restart the Blockchain:
    blockchain restart

    • Use this command if you need to refresh your blockchain instance and get new configuration values. This command stops the current blockchain instance and then starts a new instance. The new configuration values are parsed and updated in /challenge/Config.sol automatically.
  5. View Blockchain Configuration:
    blockchain info

    • This command reads the configuration from /challenge/Config.sol and displays the current settings.
  6. Retrieve the Flag:
    blockchain get flag

    • This command retrieves the flag from the blockchain instance. It uses the Node ID and Challenge contract address from /challenge/Config.sol to send a request to get the flag.
  7. Deploy Your Contract/Exploit:
    blockchain deploy <solidity_file_path> <contract_name> [value]

    • Use this command to deploy any Solidity contract (for example, your exploit).
    • Replace <solidity_file_path> with the full path to your Solidity file and <contract_name> with the name of the contract to deploy.
    • The optional [value] argument can be included if your deployment requires sending a specific amount of Ether.
    • Example:
      blockchain deploy /home/hacker/test/Test.sol Test
      blockchain deploy /home/hacker/test/Test.sol Test 2ether

Additional Note:

  • If you are comfortable using Foundry, you can also deploy and test your contract using forge create directly.
  • Both blockchain start & blockchain restart commands automatically update and save new values in the configuration file.
  • With each challenge, you will find a dummy Exploit contract you can use as an initial template to write your exploit. You can't get the flag using this dummy contract.

Have fun and good luck!


Challenges

Overview

This challenge is a Solidity contract that requires you to guess the correct number. The contract verifies that the SHA-256 hash of the encoded number matches a predetermined constant.

Challenge Goal

Your goal is to determine the number that, when processed with sha256(abi.encodePacked(Number)) produces the predetermined hash.

Challenge Structure

  • Challenge.sol: The main contract you’ll exploit and defines the win condition .
  • Config.sol: This Solidity file stores the critical configuration parameters for the challenge, it will automatically updated each time you run blockchain restart.
  • Exploit.sol: Example solidity that you can use to implement your exploit.

How to Solve

Please read the How to interact with the blockchain section to learn how the blockchain command works, how to deploy your exploit, and how to retrieve the flag.

Challenge Explanation

Objective:
Your goal in this challenge is to find a way to produce a new block that has the same hash as a given original block. More specifically, you must craft a new block where the nonce and data is different than the original one and the block hash computed using a hash function remains unchanged.

What This Means for You:

  • Original Block:
    You are provided with an original block that contains a block number, some data, and an associated nonce.

  • New Block Requirement:
    You need to create a new block that has:

    • The same block number.
    • Different data.
    • Different nonce.

Your challenge is to ensure that the hash of the new block (when computed with the new nonce) is identical to the hash of the original block (computed with the original nonce).

This challenge demonstrates a vulnerability: even with a changed nonce and data, it is possible to produce the same hash. This illustrates why robust collision-resistant hashing is important in real world applications.

Verify Block Hash Challenge Script

This Python script lets you verify if your supplied block data and nonce produce the same hash as the original block then print out the flag.

/challenge/Verify new_block_data new_nonce

Example:

/challenge/Verify 000000aaa 00000

Overview

This challenge is around a Vault contract that provides both flash loan functionality and yield through a simple rewards system. Users can deposit tokens into the Vault to earn a fixed reward per deposit and withdraw their funds along with the reward. In addition, the Vault supports flash loans allowing users to borrow tokens as long as they are returned within the same transaction.

Challenge Goal

Your goal is to drain the Vault of its entire token balance, find a way to exploit the contract’s logic to withdraw all tokens.

Challenge Structure

  • Challenge.sol: The main Vault contract you’ll target.
  • Token.sol: The token contract used by the vault.
  • Config.sol: This Solidity file stores the critical configuration parameters for the challenge, it will automatically updated each time you run blockchain restart.
  • Exploit.sol: Example solidity that you can use to implement your exploit.

How to Solve

Please read the How to interact with the blockchain section to learn how the blockchain command works, how to deploy your exploit, and how to retrieve the flag.

Hints

For this challenge focus on how you can use the flashloan function to grant you approvals.

Overview

This challenge involves a Solidity Vault contract that manages user stakes and rewards, interacting with a mock pool (MockPool). The contract is deployed with an initial balance of 10 ETH and allows users to stake and unstake ETH based on certain conditions.

Challenge Goal

Your goal is to drain the Vault of its entire ETH balance 10 ETH. Find a way to exploit the contract’s logic to withdraw more ETH than you’re entitled to.

Challenge Structure

  • Challenge.sol: The main Vault contract you’ll target.
  • Pool.sol: A pool contract that supports liquidity operations and can send ETH during certain actions.
  • Config.sol: This Solidity file stores the critical configuration parameters for the challenge, it will automatically updated each time you run blockchain restart.
  • Exploit.sol: Example solidity that you can use to implement your exploit.

How to Solve

Please read the How to interact with the blockchain section to learn how the blockchain command works, how to deploy your exploit, and how to retrieve the flag.

Challenge Description

Overview

In this challenge, you are given an ECDSA signature for a message that was hashed using a custom encryption function called spn_encrypt (defined in hash.py). Your task is to find a new message that is different from the original, yet when processed by spn_encrypt produces a hash that verifies correctly against the provided ECDSA signature which means the output of spn_encrypt for the new message will be the same as the old message.

Challenge Goal

You must craft a new message M2 that, when encrypted using spn_encrypt results in a digest for which the given ECDSA signature still verifies. In other words, you need to find a collision under the hash function so that spn_encrypt(M2) == spn_encrypt(ori_msg).

Verify Challenge Script

The provided verify.py script accepts the new message in hexadecimal format. It ensures the new message is different from the original and computes its hash using spn_encrypt.Then it uses the public key and signature to verify if the new hash is valid. If signature verification succeeds against your new message, the script prints a success message and flag.

/challenge/Verify new_message_in_hex

Example:

/challenge/Verify 000000aaa00000


30-Day Scoreboard:

This scoreboard reflects solves for challenges in this module after the module launched in this dojo.

Rank Hacker Badges Score