Skip to content

How to setup an Embedded CTF Competition

Robert Clark edited this page Jan 26, 2021 · 3 revisions

Accessing the console on Dokku

In order to run these commands, you will need access to the console on Dokku. In order to do this you will need to run:

dokku enter <scoreboard-name>

Resetting the Scoreboard

You'll need to delete the information from the previous year. First, ensure that you have a copy of the SQL database, in case you need to old data. Next, you can run the following command to delete all users, challenges, flags, etc.

rails ectf:reset

Creating the Admin User

First, create a folder for persistent storage of secrets (this README will use the summer2020 folder. Next, run the following command to create the administrator user:

rails db:create_admin

Note the username and password you used in the summer2020/admin.json

Setup the Scoreboard Settings

First, create the file settings.json in the persistent folder that you have created (summer2020 for this example).

{
  // The name of the game; will appear on the scoreboard
  "game_name": "2020 MITRE Summer eCTF",
  // The description of the competition
  "description": "The 2020 Summer Embedded Capture the Flag",
  // The time (in UTC) that the competition starts at
  "start_time": "June 17, 2020 13:00",
  // The time (in UTC) that the competition ends at
  "stop_time": "August 12, 2020 3:59",
  // The format that the above times are in
  "time_format_string": "%B %d, %Y %H:%M",

  // Scoring settings

  // The number of points each flag starts at
  "point_value": 500,
  // The number of points awarded to the first team to capture the flag
  "first_capture_point_bonus": 50,

  // The number of shares the first team to capture the flag will get.
  // This will decrease by SHARE_DECREMENT number of shares every
  // ELAPSED_TIME hours. This must be at least
  // `SHARE_DECREMENT * (time-of-competition / ELAPSED_TIME)`
  // to prevent negative share values
  "share_increment": 800,

  // how many fewer shares each team gets after each elapsed time unit from
  // first capture
  "share_decrement": 1,
  // time in hours at which point shares are decremented
  "elapsed_time": 1,

  // number of points a challenge will raise by after not being solved
  "point_increment": 24,
  // time between the total number of points raising if it hasn't been solved
  "point_elapsed_time": 24,

  // amount of time (in hours) before giving the team defense points
  "defense_elapsed_time": 24,
  // number of points awarded to a team if they successfully defend
  "defense_point_increment": 24,

  // Set this variable to True if you want to have optional implementation flags
  // Used this is 2020 for things like larger file sizes, high quality audio, etc.
  "optional_implementation_features": false
}

If you would like to change the scoring settings, tweak the settings before running any commands.

Team Creation and Scoreboard Initialization

First, open the persistent folder you are using and create teams.json with the names of the teams for this year, in the form:

[
  {
    "team_name": "Resilient Available Intelligent Drones",
    "email": "[email protected]",
    "affiliation": "MITRE",
    "state": "FL"
  },
  {
    "team_name": "Team Clare",
    "email": "[email protected]",
    "affiliation": "MITRE Clare",
    "state": "FL"
  }
]

Next, create the Design Phase challenges JSON file. An example of the format of this file is below. It is recommended that this file be in the same persistent folder that you have been using (summer2020 for this example). If there are any optional commands, their type should be "optional".

{
  "Read the Rules": {
    "values": ["ectf{readtherules_flag}"],
    "description": "If you read the rules, you'll know",
    "points": 100
  },
  "Boot Reference": {
    "values": ["ectf{boot_flag}"],
    "description": "Provision and boot the scewl_echo_server and the flag_sed SEDs to receive a flag.",
    "points": 100
  },
  "Design Document": {
    "values": ["ectf{document_flag}"],
    "description": "Submit a design document containing descriptions of how each command will work on your system ",
    "points": 100
  },
  "Test SED": {
    "values": ["ectf{testsed_flag}"],
    "description": "Submit an SED that performs valid tests (within the expected use) of SCEWL. ",
    "points": 100
  }
}

Next, create the challenges JSON file. An example of this file is below. Again, it is recommended that this file be in the same persistent folder (summer2020).

{
  "Intercept Broadcast": {
    "description": "Obtain the flag from the broadcasting device"
  },
  "Intercept Send": {
    "description": "Obtain the flag from the transmitting device"
  },
  "Device Spoof": {
    "description": "Have a checkpoint SED accept a packet with a device ID it does not recognize and read the flag from the insecure channel"
  },
  "Invalid Message": {
    "description": "Have the user code of any deployed UAV SED receive a message from a checkpoint SED that is anything other than the clear airway confirmed message  and read the flag from the insecure channel"
  },
  "Custom Message": {
    "description": "Have the user code of any deployed UAV SED receive the drop package message10 and read the flag from the insecure channel"
  },
  "Code Execution": {
    "description": "Gain code execution to call the function at 0xf000 and read the flag from the insecure channel"
  }
}

Next, run the following commands to mount the configuration files you have created to the Docker container

dokku storage:mount <scoreboard-name> /path/to/summer2020:/config
dokku ps:restart <scoreboard-name>
dokku enter <scoreboard-name>

Finally, run the commands

rails 'ectf:initialize_game[/path/to/settings.json]'
rails 'ectf:setup_teams[/path/to/teams.json]' > /path/to/output.teams.json
rails 'ectf:setup_design_phase[/path/to/design_phase_challenges.json]'
rails 'ectf:setup_attack_phase[/path/to/settings.json, /path/to/challenges.json]'

Adding Teams to the Attack Phase

When it is time to add a team to the Attack Phase, simply run the following command with the appropriate values (note that the date must be in UTC!) (also note: do not quote the parameter strings here, just separate them by commas!):

rails 'ectf:add_team_to_attack_phase[<team display name>, <date string, example: 2020-06-19 00:28:00>] > /path/to/teamname.json

Running Arbitrary SQL Commands

ActiveRecord::Base.connection.execute("SQL COMMAND")