2018-05-10 23:18:35 +00:00
|
|
|
FIC Forensic CTF Platform
|
|
|
|
=========================
|
|
|
|
|
|
|
|
This is a CTF server for distributing and validating challenges. It is design
|
|
|
|
to be robust, so it uses some uncommon technics like client certificate for
|
|
|
|
authentication, lots of state of the art cryptographic methods and aims to be
|
|
|
|
deployed in a DMZ network architecture.
|
|
|
|
|
2021-09-09 13:00:23 +00:00
|
|
|
This is a [monorepo](https://danluu.com/monorepo/), containing several
|
|
|
|
micro-services :
|
|
|
|
|
|
|
|
- `admin` is the web interface and API used to control the challenge
|
|
|
|
and doing synchronization.
|
2023-07-10 07:17:02 +00:00
|
|
|
- `checker` is an inotify reacting service that handles submissions
|
|
|
|
checking.
|
2021-09-09 13:00:23 +00:00
|
|
|
- `dashboard` is a public interface to explain and follow the
|
|
|
|
conquest, aims to animate the challenge for visitors.
|
2023-04-11 06:10:40 +00:00
|
|
|
- `evdist` is an inotify reacting service that handles settings
|
|
|
|
changes during the challenge (eg. a 30 minutes event where hints are
|
|
|
|
free, ...).
|
2023-07-10 07:17:02 +00:00
|
|
|
- `generator` takes care of global and team's files generation.
|
2023-07-09 18:40:53 +00:00
|
|
|
- `qa` is an interface dedicated to challenge development, it stores
|
|
|
|
reports to be treated by challenges creators.
|
|
|
|
- `receiver` is only responsible for receiving submissions. It is the
|
2021-09-09 13:00:23 +00:00
|
|
|
only dynamic part accessibe to players, so it's codebase is reduce
|
|
|
|
to the minimum. It does not parse or try to understand players
|
|
|
|
submissions, it just write it down to a file in the file
|
2023-07-10 08:04:28 +00:00
|
|
|
system. Parsing and treatment is made by the `checker`.
|
2023-04-11 06:10:40 +00:00
|
|
|
- `remote/challenge-sync-airbus` is an inotify reacting service that
|
|
|
|
allows us to synchronize scores and exercice validations with the
|
|
|
|
Airbus scoring platform.
|
2021-09-09 13:00:23 +00:00
|
|
|
- `remote/scores-sync-zqds` is an inotify reacting service that allows
|
|
|
|
us to synchronize scores with the ZQDS scoring platform.
|
|
|
|
- `repochecker` is a side project to check offline for synchronization
|
|
|
|
issues.
|
|
|
|
|
2023-07-27 08:51:41 +00:00
|
|
|
Here is how thoses services speak to each others:
|
|
|
|
|
|
|
|
![Overview of the micro-services](doc/micro-services.png)
|
|
|
|
|
2021-09-09 13:00:23 +00:00
|
|
|
In the production setup, each micro-service runs in a dedicated
|
|
|
|
container, isolated from each other. Moreover, two physical machines
|
|
|
|
should be used:
|
|
|
|
|
2023-04-11 06:10:40 +00:00
|
|
|
- `phobos` communicates with players: displaying the web interface,
|
2021-09-09 13:00:23 +00:00
|
|
|
authenticate teams and players, storing contest files and handling
|
|
|
|
submissions retrieval without understanding them. It can't access
|
2023-04-11 06:10:40 +00:00
|
|
|
`deimos` so its job stops after writing requests on the filesystem.
|
|
|
|
- `deimos` is hidden from players, isolated from the network. It can
|
|
|
|
only access `phobos` via a restricted ssh connection, to retrieve
|
|
|
|
requests from `phobos` filesystem and pushing to it newly generated
|
2021-09-09 13:00:23 +00:00
|
|
|
static files.
|
|
|
|
|
2023-07-27 08:51:41 +00:00
|
|
|
Concretely, the L2 looks like this:
|
|
|
|
|
|
|
|
![Layer 2 connections](doc/l2.png)
|
|
|
|
|
2021-09-09 13:00:23 +00:00
|
|
|
So, the general filesystem is organized this way:
|
|
|
|
|
|
|
|
- `DASHBOARD` contains files structuring the content of the dashboard
|
|
|
|
screen(s).
|
|
|
|
- `FILES` stores the contest file to be downloaded by players. To be
|
|
|
|
accessible without authentication and to avoid bruteforce, each file
|
|
|
|
is placed into a directory with a hashed name (the original file
|
|
|
|
name is preserved). It's rsynced as is to `deimos`.
|
2023-07-10 08:04:28 +00:00
|
|
|
- `GENERATOR` contains a socket to allow other services to communicate
|
|
|
|
with the `generator`.
|
2021-09-09 13:00:23 +00:00
|
|
|
- `PKI` takes care of the PKI used for the client certiciate
|
|
|
|
authorization process, and more generaly, all authentication related
|
|
|
|
files (htpasswd, dexidp config, ...). Only the `shared` subdirectory
|
|
|
|
is shared with `deimos`, private key and teams P12 don't go out.
|
|
|
|
- `SETTINGS` stores the challenge config as wanted by admins. It's not
|
|
|
|
always the config in use: it uses can be delayed waiting for a
|
|
|
|
trigger.
|
|
|
|
- `SETTINGSDIST` is the challenge configuration in use. It is the one
|
|
|
|
shared with players.
|
|
|
|
- `startingblock` keep the `started` state of the challenge. This
|
|
|
|
helps `nginx` to know when it can start distributing exercices
|
|
|
|
related files.
|
2023-07-10 08:04:28 +00:00
|
|
|
- `TEAMS` stores the static files generated by the `generator`, there is
|
2021-09-09 13:00:23 +00:00
|
|
|
one subdirectory by team (id of the team), plus some files at the
|
|
|
|
root, which are common to all teams. There is also symlink pointing
|
|
|
|
to team directory, each symlink represent an authentication
|
|
|
|
association (certificate ID, OpenID username, htpasswd user, ...).
|
2023-07-10 08:04:28 +00:00
|
|
|
- `submissions` is the directory where the `receiver` writes
|
2021-09-09 13:00:23 +00:00
|
|
|
requests. It creates subdirectories at the name of the
|
2023-07-10 08:04:28 +00:00
|
|
|
authentication association, as seen in `TEAMS`, `checker` then
|
2021-09-09 13:00:23 +00:00
|
|
|
resolve the association regarding `TEAMS` directory. There is also a
|
|
|
|
special directory to handle team registration.
|
2018-05-10 23:18:35 +00:00
|
|
|
|
2023-07-27 08:51:41 +00:00
|
|
|
Here is a diagram showing how each micro-service uses directories it has access to (blue for read access, red for write access):
|
|
|
|
|
|
|
|
![Usage of directories by each micro-service](doc/directories.png)
|
|
|
|
|
2018-05-10 23:18:35 +00:00
|
|
|
Local developer setup
|
|
|
|
---------------------
|
|
|
|
|
|
|
|
### Using Docker
|
|
|
|
|
|
|
|
Use `docker-compose build`, then `docker-compose up` to launch the infrastructure.
|
|
|
|
|
|
|
|
After booting, you'll be able to reach the main interface at:
|
2023-07-10 08:04:28 +00:00
|
|
|
<http://localhost:8042/> and the admin one at: <http://localhost:8081/> (or at <http://localhost:8042/admin/>).
|
|
|
|
The dashboard is available at <http://localhost:8042/dashboard/> and the QA service at <http://localhost:8042/qa/>.
|
|
|
|
|
|
|
|
In this setup, there is no authentication. You are identfied [as a team](./configs/nginx/get-team/team-1.conf). On first use you'll need to register.
|
2018-05-10 23:18:35 +00:00
|
|
|
|
2018-05-15 10:54:40 +00:00
|
|
|
#### Import folder
|
|
|
|
|
|
|
|
##### Local import folder
|
|
|
|
The following changes is only required if your are trying to change the local import folder `~/fic` location.
|
|
|
|
|
|
|
|
Make the following changes inside this file `docker-compose.yml`:
|
|
|
|
|
|
|
|
23 volumes:
|
|
|
|
24 - - ~/fic:/mnt/fic:ro
|
|
|
|
24 + - <custom-path-to-import-folder>/fic:/mnt/fic:ro
|
|
|
|
|
2023-04-11 06:10:40 +00:00
|
|
|
##### Git import
|
|
|
|
A git repository can be used:
|
|
|
|
|
|
|
|
29 - command: --baseurl /admin/ -localimport /mnt/fic -localimportsymlink
|
|
|
|
29 + command: --baseurl /admin/ -localimport /mnt/fic -localimportsymlink -git-import-remote git@gitlab.cri.epita.fr:ing/majeures/srs/fic/2042/challenges.git
|
|
|
|
|
2018-05-15 10:54:40 +00:00
|
|
|
##### Owncloud import folder
|
|
|
|
If your are trying to use the folder available with the Owncloud service, make the following changes inside this file `docker-compose.yml`:
|
|
|
|
|
|
|
|
29 - command: --baseurl /admin/ -localimport /mnt/fic -localimportsymlink
|
|
|
|
29 + command: --baseurl /admin/ -clouddav=https://owncloud.srs.epita.fr/remote.php/webdav/FIC%202019/ -clouduser <login_x> -cloudpass '<passwd>'
|
2018-05-10 23:18:35 +00:00
|
|
|
|
|
|
|
### Manual builds
|
|
|
|
|
|
|
|
Running this project requires a web server (configuration is given for nginx),
|
2023-07-10 08:04:28 +00:00
|
|
|
a database (currently supporting only MySQL/MariaDB), a Go compiler for the
|
2023-07-27 08:51:41 +00:00
|
|
|
revision 1.18 at least and a `inotify`-aware system. You'll also need NodeJS to
|
2023-07-10 08:04:28 +00:00
|
|
|
compile some user interfaces.
|
|
|
|
|
|
|
|
1. Above all, you need to build Node projects:
|
2018-05-10 23:18:35 +00:00
|
|
|
|
2023-07-10 08:04:28 +00:00
|
|
|
cd frontend/fic; npm install && npm run build
|
|
|
|
cd qa/ui; npm install && npm run build
|
|
|
|
|
|
|
|
2. First, you'll need to retrieve the dependencies:
|
2018-05-10 23:18:35 +00:00
|
|
|
|
2021-09-09 13:00:23 +00:00
|
|
|
go mod vendor
|
2018-05-10 23:18:35 +00:00
|
|
|
|
|
|
|
2. Then, build the three Go projects:
|
|
|
|
|
2021-09-09 13:00:23 +00:00
|
|
|
go build -o fic-admin ./admin
|
2023-07-10 08:04:28 +00:00
|
|
|
go build -o fic-checker ./checker
|
2021-09-09 13:00:23 +00:00
|
|
|
go build -o fic-dashboard ./dashboard
|
2023-07-10 08:04:28 +00:00
|
|
|
go build -o fic-generator ./generator
|
2021-09-09 13:00:23 +00:00
|
|
|
go build -o fic-qa ./qa
|
2023-07-10 08:04:28 +00:00
|
|
|
go build -o fic-receiver ./receiver
|
2021-09-09 13:00:23 +00:00
|
|
|
go build -o fic-repochecker ./repochecker
|
|
|
|
...
|
2018-05-10 23:18:35 +00:00
|
|
|
|
|
|
|
3. Before launching anything, you need to create a database:
|
|
|
|
|
|
|
|
mysql -u root -p <<EOF
|
|
|
|
CREATE DATABASE fic;
|
|
|
|
CREATE USER fic@localhost IDENTIFIED BY 'fic';
|
|
|
|
GRANT ALL ON fic.* TO fic@localhost;
|
|
|
|
EOF
|
|
|
|
|
|
|
|
By default, expected credentials for development purpose is `fic`,
|
|
|
|
for both username, password and database name. If you want to use
|
|
|
|
other credentials, define the corresponding environment variable:
|
|
|
|
`MYSQL_HOST`, `MYSQL_USER`, `MYSQL_PASSWORD` and
|
|
|
|
`MYSQL_DATABASE`. Those variables are the one used by the `mysql`
|
|
|
|
docker image, so just link them together if you use containers.
|
|
|
|
|
|
|
|
4. Launch it!
|
|
|
|
|
|
|
|
./fic-admin &
|
|
|
|
|
|
|
|
After initializing the database, the server will listen on
|
|
|
|
<http://localhost:8081/>: this is the administration part.
|
|
|
|
|
2023-07-10 08:04:28 +00:00
|
|
|
./fic-generator &
|
2018-05-10 23:18:35 +00:00
|
|
|
|
|
|
|
This daemon generates static and team related files and then waits
|
2023-07-10 08:04:28 +00:00
|
|
|
another process to tell it to regenerate some files.
|
2018-05-10 23:18:35 +00:00
|
|
|
|
2023-07-10 08:04:28 +00:00
|
|
|
./fic-receiver &
|
2018-05-10 23:18:35 +00:00
|
|
|
|
2019-07-05 16:36:20 +00:00
|
|
|
This one exposes an API that gives time synchronization to clients and
|
|
|
|
handle submission reception (but without treating them).
|
|
|
|
|
2023-07-10 08:04:28 +00:00
|
|
|
./fic-checker &
|
|
|
|
|
|
|
|
This service waits for new submissions (expected in `submissions`
|
|
|
|
directory). It only watchs modifications on the file system, it has no web
|
|
|
|
interface.
|
|
|
|
|
2019-07-05 16:36:20 +00:00
|
|
|
./fic-dashboard &
|
|
|
|
|
|
|
|
This last server runs the public dashboard. It serves all file, without the
|
|
|
|
need of a webserver. It listens on port 8082 by default.
|
2018-05-10 23:18:35 +00:00
|
|
|
|
2023-07-10 08:04:28 +00:00
|
|
|
./fic-qa &
|
|
|
|
|
|
|
|
If you need it, this will launch a web interface on the port 8083 by
|
|
|
|
default, to perform quality control.
|
|
|
|
|
2021-09-09 13:00:23 +00:00
|
|
|
For the moment, a web server is mandatory to serve static files, look
|
|
|
|
at the samples given in the `configs/nginx` directory. You need to
|
|
|
|
pick one base configation flavor in the `configs/nginx/base`
|
|
|
|
directory, and associated with an authentication mechanism in
|
|
|
|
`configs/nginx/auth` (named the file `fic-auth.conf` in `/etc/nginx`),
|
|
|
|
and also pick the corresponding `configs/nginx/get-team` file, you
|
|
|
|
named `fic-get-team.conf`.
|