In our modern, interconnected world, the concept of Web3, also known as the decentralized web, represents the next significant shift in Internet technology. Web3, underpinned by blockchain technology and smart contracts, offers unprecedented decentralization, transparency, and user sovereignty possibilities. However, with these new possibilities come new challenges – one of the most crucial is security. Web3's decentralized nature eliminates central points of failure typical in Web2 applications, leading many to view it as inherently more secure. However, the security dynamics in Web3 are different, and a unique set of vulnerabilities has emerged.
From smart contract bugs to re-entrancy attacks, vulnerabilities in the Web3 ecosystem can lead to significant financial loss and trust erosion, as evidenced by high-profile hacking incidents over recent years. This highlights the increasing importance of understanding Web3 security. The secure design, development, and operation of Web3 applications and platforms have become crucial skills in the rapidly evolving digital landscape. It's no longer sufficient to build on top of blockchain technologies; developers, cybersecurity professionals, and even end-users must grasp the principles of securing these systems.
Figure 0. Level_up! GitHub Home page: https://github.com/Telefonica/level_up
The level_up! project is an open-source initiative aimed at teaching about security in Web3. It provides a platform featuring a system of challenges, categorized by difficulty level, where various Web3 concepts are presented, and points are earned upon successfully overcoming these challenges. The goal is learning. Users register on the platform and can deploy multiple SmartContracts. Each challenge might comprise one or more SmartContracts.
How does one overcome a challenge? As we do in any CTF, by achieving a flag. A flag is a hash that must be obtained to validate against the platform and earn the flags. In new versions of level_up! you can earn NFTs as you accrue different amounts of points. With an NFT, you can verify your level of knowledge within the platform. It could be said that level_up! operates on a web2.5 system. This means it incorporates elements of both web2 and web3. The visual aspect of level_up! is straightforward and intuitive, quickly showcasing the platform's capabilities.
Figure 1. Level_up! Home page
In the previous image, you can see the platform's home page, the term "Base Address," and a table where the challenges appear. The latest version of level_up! features 13 challenges, which increase monthly through the GitHub repository.
3. Level_up! Architecture
To better understand the platform, let's discuss its architecture and components. The platform offers a DApp (Decentralized Application). It is essential to be clear about the concept of DApp. A Decentralized Application, commonly known as a DApp, is an application that runs on a decentralized network, typically a blockchain. Unlike traditional applications that operate on centralized servers, DApps leverage blockchain technology's transparency, security, and direct peer-to-peer interactions. Each DApp comprises backend code running on a decentralized peer-to-peer network and a front-end user interface created using any language that can make calls to the backend. The critical defining factor is that DApps connect users and providers directly. The operations of a DApp are governed by smart contracts, which are self-executing contracts with the terms of the agreement now written into code. They facilitate, verify, and enforce the performance of a contract without the need for a central authority.
Because DApps operate on blockchain networks, they inherit some of the fundamental characteristics of blockchain technology, such as immutability, transparency, and resistance to censorship. Furthermore, DApps are typically open source, meaning their codebase is available for scrutiny and improvement by the community, promoting trust and collaboration. The paradigm shift DApps introduce facilitates the development of decentralized digital infrastructures and encourages the democratization of the internet.
Level_up! DApp is connected to the Blockchain (in this case, local—we recommend setting up a Ganache, but other providers could be used as there is a configuration file where everything necessary to launch the platform is set up—but we will leave this for another article). The DApp connects with the Blockchain and a SmartContract named "Base." The "Base" SmartContract is responsible for managing and storing which users are registered and which users have deployed levels, as well as the status of those levels. In other words, the base contract is the foundation of the game.
Each challenge seen on Figure1 will have learning objectives. For example, the first challenge aims to demonstrate how to interact with the platform. Still, there will be other challenges that deal with logic vulnerabilities in a contract, DelegateCall failures, Re-Entrancy, Overflow, flashloan, etc. When we want to play a challenge, we must deploy the contract of that challenge. This contract is different from the base contract. They have different goals—one provides us with a challenge in which we need to achieve the flag and the other manages scores, players, etc.—in other words, everything related to the platform. We play with the Ganache Blockchain connected.
Let's summarize the concepts:
In this setup, a Blockchain can be configured for personal use; it's typically recommended to initiate it for testing and employ Ganache or Hardhat.
- Present as well is a SmartContract that takes charge of managing players, levels, and scores, and validates the flags achieved. This contract goes by the name 'Base.'
- With each challenge, one or more contracts will be deployed, and objectives will be assigned. A flag must consistently be secured to validate it against the Base contract.
- Also integral to the system is a DApp, which offers a user-friendly method to interact with the platform.
5. How does the CTF work?
The first thing we must do when we enter the platform is register as a player. Remember, we must tell the Base contract we want to play on this CTF or learning/training platform.
Figure 2. player creation main screen
Creating a player is simple; we click on the "Create Player" button and accept the transaction with our Metamask. Once the user is created, they will be added to the Base contract, meaning they are ready to deploy challenges. The deployment of challenges can be requested from the backend, which holds an account (configured in the platform's configuration file) and carries out the deployment.
Figure 3. player creation process
The level_up backend pays for the transaction. For this reason, if someone wants to set this up in a real environment, they should keep this in mind, as each user who deploys a challenge does not pay—the backend does. This could be easily changed so the user covers the payment, but that's not the project's objective. The goal is for teams or users to deploy in a controlled environment and train (and "compete", as there is a Global Score with the scores of all registered users). When we want to deploy a challenge, we must access the challenge's page. On this page, we can find a series of steps that will guide us and, in some cases, give us a hint. For example, if we want to deploy the 'Interact' challenge, a tutorial-style challenge showing how the platform works. Upon accessing the 'Interact' challenge page, we will see information and a series of steps, and the contract or contracts that contain the challenge will be displayed. This is important, as auditing contracts requires understanding the language and seeing the contract's logic and function.
After deploying the first challenge, as explained in the description, we must open the browser console (the 'Dev Tools'). If we execute the 'help' command, we can see help with the available commands/objects for this challenge.
Some things to keep in mind:
- The 'Base' object always appears, allowing us to interact with the Base SmartContract. We will use this when we want to validate a flag or use some function of the SmartContract. Mainly, we will only need it when we solve the challenge, need to validate the flag and earn the challenge points.
- The 'player' command returns my account's public address: Simply for convenience, even though it is in Metamask. This address is the account with which I am connected to the platform, meaning the player I play with.
- The 'contract' allows us to interact with the contract that holds the flag and sets the challenge: There may be more objects from other contracts if needed to complete the challenge.
- We can easily see the functions through the contract objects, as seen in the image. In most challenges, there will be a getFlag() function, which will provide the flag when the challenge is overcome.
Figure 4. Function examples
This first tutorial challenge is straightforward; we only need to ask the contract to give us the flag. In other scenarios, we must perform other actions, exploit vulnerabilities, exploit application logic, or other actions to obtain the flag. If the contract has an Owner() function and getFlag() function, they can be queried through the following syntax. In this first challenge (tutorial mode), when asking for the flag, they give it to us directly (in the following challenges, it will be more complex).
Figure 5. Interaction with the contract from the console
Once we have the flag, we must give it to the base contract to validate the result and obtain the points associated with the challenge. The syntax for validating the flag is always the same:
- Base.validateFlag(<challenge contract address>, <flag value>)
It should be noted that each user who deploys a challenge has a different flag. If user 1 deploys challenge 1, the backend generates a flag (which will be reported to the base contract managing it) for that challenge. If user 2 deploys challenge 2, the flag will differ from the contract of challenge 1 that user 1 deployed. This way, players cannot share flags, as each one has unique flags for their instances of the difficulties deployed. This adds an individual learning component to the platform and prevents cheating. This approach also provides fairness and keeps the scoring accurate, reflecting individual effort.
In the following image, you can see how the flag is validated. Notice the hash passed to the function and that after the transaction is validated, the challenge is flagged as "solved."
After validating the flag, we earned the challenge's points, added to our total score, updating our position in the global scoreboard.
Figure 6. Interaction with the contract from the console
The scoreboard, or "Global Score," shows the players who have earned the most points. Points are obtained by overcoming challenges, each with a specific number of points. The level of difficulty of a challenge determines the points. For example, the tutorial challenge, 'Interact,' gives us only one point: its purpose is to show us how to play. In contrast, a more complex challenge that involves a better understanding of smart contracts or a specific vulnerability can give us many more points.
Figure 7. Global score
The level_up! platform offers an excellent opportunity to learn about the security aspects of smart contracts and Web3. Its gamified learning approach incentivizes users to keep pushing their understanding further while fostering a spirit of competition. Whether you're an experienced developer or a beginner in the world of smart contracts, you can find valuable learning experiences in the challenges provided by level_up! It's a fantastic initiative to improve the understanding and skills of everyone interested in this field and strengthen the security of the Web3 ecosystem.
To test the platform and learn about security and vulnerabilities in Web3, you can visit the GitHub repository: https://github.com/telefonica/level_up
Pablo Gonzalez Perez
University Degree in Computing Engineering and master’s degree in Cybersecurity. Speaker at BlackHat Europe Arsenal, 8dot8, Rooted Con, etc. Microsoft MVP from 2017 to 2023. Writer of several computer security books as Metasploit for Pentesters, Ethical Hacking, Pentesting with Kali, Metasploit hacking, Got Root and PowerShell pentesting. Co-founder of flu-project and founder of hackersClub. More than 10 years working in cybersecurity and teacher of several masters in cybersecurity in Spain. Currently working as Project/Team Manager and Security Researcher at Telefonica.
University Degree in Computing Engineering, certificate of higher education in Industrial and Digital Electronics and master’s degree in Cybersecurity. Huge experience working as an IT Senior System Engineer in USA and Canada, consolidating IT technologies and datacenters. Working at Telefonica and ElevenPaths from 2017 as Security Researcher. Co-writer of the following books: "SecDevOps: Docker", "Microhistorias" (computer history) and "Computer Security: Machine Learning Techniques", 0xWord publishing. Founder and writer blog: www.cyberhades.com (nick: cybercaronte) about security and geek culture.