Skip to content

Repository files navigation

Warning

The vm has been shut down and the subdomain name deleted (ctfman)!

CTFman

Table of Contents
  1. Built With
  2. Introduction
  3. Getting Started
  4. Documentation
  5. Usage
  6. License
  7. Contacts

Built With

(back to top)

Introduction

The goal of CTFman - a web application using a database - is to efficiently manage Capture The Flag (CTF) competitions. The database will store and organize information about CTFs, participants, teams, tools, and performance metrics. This will allow for:

  • Historical Tracking: Preserving records of competitions, which is essential since CTFs are only accessible for a limited time during the event duration.
  • Data Interaction: Providing a seamless interface to visualize, modify, and manage the stored data.
  • Comprehensive Functionality: Enabling functionalities like managing team registrations, tracking user activities, organizing challenges, managing tools and resources, and moderating comments.

Note

CTF - Capture The Flag - is a competition where participants solve cybersecurity challenges to gain points and compete against others.

Caution

Hacking is not necessarily a negative practice. In fact, it plays an essential role in learning and discovering existing vulnerabilities in computer systems. Through disciplines like CTF (Capture the Flag), cybersecurity enthusiasts can develop skills by identifying potential flaws and understanding how they could be exploited. This knowledge is then used to strengthen system security and prevent future attacks. Thus, ethical hacking or "white hat" hacking actively contributes to the protection of digital infrastructures by anticipating risks and proposing solutions.

(back to top)

Getting Started

Prerequisites

Java 21

  • asdf

    # Install the plugin if needed
    asdf plugin add java
    # Install
    asdf install java latest:temurin-21
  • Mac (homebrew)

    brew tap homebrew/cask-versions
    brew install --cask temurin@21
  • Windows (winget)

    winget install EclipseAdoptium.Temurin.21.JDK

For Developer

If are a standard user go here.

Running in local

Clone this repository with either ssh or http, but we recommend using ssh as it is more secure.

git clone git@github.com:shadowkudo/ctfman.git

Use the maven wrapper to install dependencies, build and package the project.

# install the dependencies
./mvnw clean install
# build
./mvnw package
# run
java -jar target/<filename>.jar --help

Running with Docker

Build the Docker image and publish it to GitHub Container Registry:

docker build -t ghcr.io/<username>/ctfman:latest
docker push ghcr.io/<username>/ctfman:latest

Note

We used GitHub Actions so that it publishes automaticaly when new commit is done in main branch.

Running with Docker Compose

Run the application using Docker Compose:

docker compose --profile dev up -d

(back to top)

Documentation

VM - Azure

In our project, we choose to use Microsoft Azure as the provider for the virtual machine for our web server. See below for the installation and configuration process for a student account.

Installation

Access the Azure portal with the following link: https://portal.azure.com and log in.

Create a new virtual machine from the dashboard in section Create a resource.

Select a virtual machine with the following characteristics:

  • Project details
    • Subscription: Azure for Students
    • Resource group: Create new with the name heig-vd-dai-course
  • Instance details
    • Virtual machine name: heig-vd-dai-course-vm
    • Region: (Europe) West Europe
    • Availability options: No infrastructure redundancy required
    • Security type: Trusted launch virtual machines (the default)
    • Image: Ubuntu Server 24.04 LTS - x64 Gen2 (the default)
    • VM architecture: x64
    • Size: Standard_B1ms - you might need to click "See all sizes" to see this option
  • Administrator account
    • Authentication type: SSH public key
    • Username: ubuntu - please use this username so the teaching staff can help you if needed
    • SSH public key source: Use existing public key
    • SSH public key: Paste your public key here - see the note below for more information
  • Inbound port rules
    • Public inbound ports: Allow selected ports
    • Select inbound ports: HTTP (80), HTTPS (443), SSH (22)

Caution

The server needs to have at least 2 GiB RAM so that it will not freeze ! You may also add a swap file of 1 GiB to be more secure on memory usage.

Click on the Review + create button.

Validate the configuration and click on the Create button.

It might take a few minutes to create the virtual machine. Once the virtual machine is created, you can access it with the Go to resource button.

Note the public IP address of the virtual machine. You will need it to connect to the virtual machine with SSH later.

Configuration

In this section, you will access the virtual machine with SSH and configure it.

Using the public IP address of the virtual machine, you can connect to the virtual machine with SSH with the following command:

# Connect to the virtual machine with SSH
ssh ubuntu@<vm public ip>

The first time you connect to the virtual machine, you will be asked to confirm the fingerprint of the public key of the virtual machine.

The output should be similar to the following:

The authenticity of host '104.45.17.214 (104.45.17.214)' can't be established.
ED25519 key fingerprint is SHA256:Xl0X5kv+aeZV28XA9iJ/L+geFVVvOvG4foRixbGRYnY.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])?

You can type yes and press the Enter key.

Once connected to the virtual machine, you can update the packages with the following command:

# Update the available packages
sudo apt update

# Upgrade the packages
sudo apt upgrade

You can then reboot the virtual machine with the following command to apply all the updates:

# Reboot the virtual machine
sudo reboot

Install and configure Docker and Docker Compose on the virtual machine. You will need them to run our web application.

Congratulations! You have now an up-to-date and configured virtual machine to use.

(back to top)

Zone DNS

For the server to be accessible easily on the Internet, you need to set up a DNS - Domain Name Server - so that you will use a name instead of a ip address to access the server remotely.

You need to either buy a domain name (like we did using Polisystems) or use a free domain name (see Duckdns).

Add an A record to the DNS zone of your domain name provider to point to the IP address of the virtual machine.

Add a second wildcard A record to the DNS zone of your domain name provider to point to the IP address of the virtual machine. This will allow access to all your services hosted under a subdomain of your domain name.

dns_zone

Validation

Test the DNS resolution of the DNS records you added from the virtual machine and from your local machine.

# Test the DNS resolution
nslookup ctfman.cybernest.ch

On success, the output should be similar to the following:

Server:		192.168.247.244
Address:	192.168.247.244#53

Non-authoritative answer:
Name:	ctfman.cybernest.ch
Address: 104.45.17.214

On failure, the output should be similar to the following:

Server:		192.168.247.244
Address:	192.168.247.244#53

** server can't find heig-vd-dai-course.duckdns.org: NXDOMAIN

Note

You might have to wait a few minutes (max 15 minutes in our experience) for the DNS record to be propagated and get a successful response. In case you use a WIFI to connect to the Internet, it may take longer if their cache take more time to reset (if during your configuration you made an error and had to update it)!

API

With Swagger, documentation is created during coding; see the endpoint https://api.ctfman.cybernest.ch/swagger or https://api.ctfman.cybernest.ch/redoc to look at the API documentation.

Note

It is recommended to use swagger as you can try the API easily.

(back to top)

Usage

  1. Starting the database
docker compose up db -d
  1. Setting up the database and populate it with data
docker compose run --rm prod setup --seed
  1. Starting the web application
docker compose up prod -d
  1. Accessing the application in a browser (tested with Firefox)
firefox https://ctfman.cybernest.ch

Important

You can go directly to step 4, as you do not have access to the server. In case a problem occur, create an issue here with the tag bug and we will try our best to support you!

(back to top)

Examples using Curl

If not yet installed, do (for Ubuntu systems):

# Install curl
sudo apt install curl
Login as an user
curl -i -X 'POST' \
  'https://api.ctfman.cybernest.ch/login' \
  -H 'accept: */*' \
  -H 'Content-Type: application/json' \
  -d '{
  "username": "user1",
  "password": "password"
}'

Will get:

HTTP/2 204
content-type: text/plain
date: Fri, 17 Jan 2025 16:57:54 GMT
expires: Thu, 01 Jan 1970 00:00:00 GMT
set-cookie: session=HTOsOvSX0eEPXaAwy76Zjwjaadim9bWeD4-DkOMVjqg; Path=/; Secure; SameSite=None
Get profile
curl -X 'GET' \
  'https://api.ctfman.cybernest.ch/profile' \
  -H 'accept: application/json' \
  -H 'Cookie: HTOsOvSX0eEPXaAwy76Zjwjaadim9bWeD4-DkOMVjqg'

Important

As seen here, you need to add the cookie from the login response to all the future request as you need to be logged in to access other information. The only exception would be to logout as it will not give confidential information.

Will get:

HTTP/2 200
content-type: application/json
date: Fri, 17 Jan 2025 17:09:47 GMT
content-length: 188

{"createdAt":"2025-01-13T12:49:41Z","deletedAt":null,"authentication":"user1","primaryContact":"user1@example.com","isChallenger":true,"isAdmin":false,"isModerator":false,"isAuthor":false}
Logout
curl -i -X 'POST' \
  'https://api.ctfman.cybernest.ch/logout' \
  -H 'accept: */*' \
  -d ''

Will get:

HTTP/2 204
content-type: text/plain
date: Fri, 17 Jan 2025 16:58:16 GMT
expires: Thu, 01 Jan 1970 00:00:00 GMT
set-cookie: session=; Path=/; Expires=Thu, 01-Jan-1970 00:00:00 GMT; Max-Age=0

Note

I think with those examples, you understood how it works. For others endpoints it will work the same way; be careful to never forget the cookie in the request !

(back to top)

Examples using the UI on a web browser

The following examples have been made with Firefox.

Login:

login

Logout:

logout

Navigation:

navigation

List teams:

list_team

Edit team:

edit_team

Create team:

create_team

Team details:

team_details

Note

It will work the same way for other field like CTF.

(back to top)

Contributing

Contributions are what make the open source community such an amazing place to learn, inspire, and create. Any contributions you make are greatly appreciated.

  1. Fork the Project
  2. Create your Feature Branch (git checkout -b feature/AmazingFeature)
  3. Commit your Changes (git commit -m 'Add some AmazingFeature')
  4. Push to the Branch (git push origin feature/AmazingFeature)
  5. Open a Pull Request

(back to top)

License

Distributed under the MIT License. See LICENSE for more information.

(back to top)

Contacts

Important

Have fun !

(back to top)

About

DAI - Project 3

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages