Technical Details

I wanted to make the deployment of this CTF as simple as possible in the beginning. Hence, I’m going to split the technical details into 2 parts:

1 — The Infrastructure of the CTF.

2 — The deployment of the challenges (Nginx and docker).

1 — The Infrastructure of the CTF

Since the number of participants is not too many, I decided to go for a simple option which is DigitalOcean. I reserved the ‘$15/month’ instance, as shown below:

DigitalOcean plans

The above instance looks good for launching the CTF platform. When it comes to the CTF platform, there are multiple choices for that:

1 — CTFd

2 — FBCTF

I don’t have an explicit answer on which platform would be better for hosting the CTF, it depends on your preferences. I prefer FBCTF since it has interactive and fancy UI.

Installing the FBCTF

There are multiple ways of installing the ‘FBCTF’ platform as below:

FBCTF installation options

Since the event is quite small, I decided to go with the ‘Direct installation’. The direct installation is very simple as seen below:

From the system you wish to install the platform, execute the following: git clone https://github.com/facebook/fbctf cd fbctf source ./extra/lib.sh sudo apt-get install docker docker-compose quick_setup install prod or quick_setup install dev

Creating the subdomain & install the SSL/TLS certificate

it’s important to mention that FBCTF is designed to work over HTTPS and it needs some tweaking to change it to HTTP. Hence, we take further steps to make sure that the platform will be running properly with no misconfiguration issue.

a — Create the subdomain

A subdomain can be created on DigitalOcean by setting-up the ‘A’ DNS record and point it to the ‘FBCTF’ instance as below:

Pointing the subdomain to the ‘FBCTF’ instance

More details: https://www.digitalocean.com/docs/networking/dns/how-to/add-domains/

b — Create the SSL/TLS certificate with LetsEncrypt

There is an option with FBCTF to provision the platform with the signed certificated directly as below:

./extra/provision.sh -m prod -s $PWD -c certbot -D "ctf.sherif.ninja" -e "email@whatever.com"

The above option did not work with me and resulted in multiple errors.

Another option which worked with me is as below:

sudo apt-get install -f libboost-all-dev

sudo apt-get install libcurl3 -y

sudo apt-get install libcurl4 libcurl4-openssl-dev -y export LC_ALL="en_US.UTF-8"

export LC_CTYPE="en_US.UTF-8" apt-get install letsencrypt service nginx stop certbot-auto certonly -n --agree-tos --standalone --preferred-challenges http -m " e mail@whatever.com" -d "ctf.sherif.ninja" service nginx start

2 — The challenges deployment (Nginx and docker)

Since we have already deployed the CTF platform and the SSL/TLS certificate. All that we can do is to add the challenges in the dashboard of FBCTF. We need first to deploy the challenges.

There are many options to host the CTF challenges:

1 — Hosting each challenge on a different instance.

2 — Hosting the challenges in containers and on the same instance of FBCTF (not my preferred option).

3 — Dockerize each challenge and add it on an instance with a reverse proxy (Preferred option).

Below is how the diagram should look like after the deployment:

A simple diagram to explain how the deployment works

To explain the deployment easily, we can assume that we are preparing for a CTF that consists of only 3 web challenges (i.e. x1,x2,x3).

The technology behind every challenge is different which will require different docker images (i.e. PHP with MySQL, python2 with flask,etc.).

Whenever the player gets the link for a challenge, for instance, x1, then the Nginx proxy will forward it to the right container to start with the challenge.

If you understood the concept behind it, then let’s move on with the technical details.

1 — Dockerizing the challenge

There are many tutorials to follow-up and dockerize your challenge, depending on which technology stack needed for the challenge.

For instance, I have added very simple docker images in the following repository:

https://github.com/ahmedsherif/CTF-docker-samples

2 — Create a wildcard SSL/TLS certificate for the challenges (optional)

This can be optional whether you need to have all the web challenges over HTTPS or HTTP.

The following screenshot explains the creation of the wildcard certificate and configuring the Nginx to have it running.

A command for the wildcard SSL/TLS certificate

wildcard domain pointing to the DigitalOcean instance

3 — Connecting the challenges with Nginx and publish it on FBCTF platform

I have just added a simple script to connect the dockerized challenges with Nginx.

Now we need to add 2 challenges, first, we get our containers running and check below:

docker ps -a

In this case, we would like to add 2 challenges (flask_vuln and web1), one is listening on port 8443 and the other one is 5000.

Then, we can run the script with the following arguments:

root@challenges:/tmp# python ctf.py /etc/letsencrypt/live/ctf.sherif.ninja/fullchain.pem /etc/letsencrypt/live/ctf.sherif.ninja/privkey.pem ctf.sherif.ninja 8443 new challenge on domain ymvvoehgus.ctf.sherif.ninja added with docker port 8443 root@challenges:/tmp# python ctf.py /etc/letsencrypt/live/ctf.sherif.ninja/fullchain.pem /etc/letsencrypt/live/ctf.sherif.ninja/privkey.pem ctf.sherif.ninja 5000 new challenge on domain cxsxuopsnr.ctf.sherif.ninja added with docker port 5000 root@challenges:/tmp# service nginx restart root@challenges:/tmp#

By going to the following subdomain:

We will get the PHP challenges as below:

By going to the other generated subdomain:

We will get the flask challenge:

Flask challenge

Note: You can change the subdomains as you like instead of the random string.

Now you can add the challenges on the FBCTF portal and also deploy more challenges on your hosting machine.

Hardening

I have not included any best practice or hardening steps in this write-up, hence the reader has to take care of it.

DevOps Engineers

for DevOps engineers, I’m very interested to retrieve their feedback and share with me their thoughts about this deployment.