by on under projects

CTFedu: Updating the CTFd Framework for the Classroom

Background and Motivation

CTFd (https://ctfd.io) is an open source capture the flag web service scoreboard framework written by Kevin Chung. It is a very easy to use, generic framework for "jeopardy"-style computer security competitions. The framework supports team management, puzzle/challenge organization, real-time tracking, and many other features supportive of normative CTF competitions.

Relatedly, there has been a recent interest in using CTF-style competitions in the classroom for giving students an opportunity to practice in a realistic, but simulated environment. However, and perhaps unsurprisingly, the requirements and metrics for success differ between a competition and a learning environment. These include: tracking per-student progress, enforcing scaffolding the difficulty of challenges so students don't self-intimidate themselves, protecting student privacy (as required by FERPA), and running multiple, parallel competitions (e.g. supporting multiple sections of a course in a single quarter.)

To this end, we were motivated to rework the CTFd framework so that it could be more easily used in the classroom. This post discusses some of the changes we made and how you can use our fork in your own classroom.

The Web Service

Here we are the changes we made in order top adapt it to a classroom environment.

Database Structure Changes

  • Students are now used as the way in which scores are tracked instead of Teams.
  • Teams are now less complex and much of their responsibilities were moved to Students. Teams are now a collection of Students.
  • Sections were added as a collection of Teams.
  • In short: wherever a model used Teams, it now uses Students.
  • Challenges now have a level (useful for learning units) and a requisite field.

Web View Changes

  • Users can only view information relevant to their section.
  • Challenges are now arranged according their level instead of by category.
  • You need to complete all the challenges on the previous level before you can see the next level. After completing a level the user needs to refresh the page in order for the next level to appear.
  • The admin challenge page is now arranged by level.
  • Team scores are now calculated from the scores of all the student’s scores.
  • Students cannot see information about other students in compliance with FERPA
  • The administrator can now see detailed information about the progress on each challenge
  • The administrator can upload a xlsx file with information about students to create a new section
  • The administrator can manually add individual students
  • Passwords are randomly generated and displayed for each student immediately and only after creating a new section or adding a new student
  • The administrator can independently create new teams
  • The administrator can change what teams students are on
  • The administrator can switch between the different sections via a dropdown menu on the navigation bar at the top
  • The option to has users register was removed
  • Credits were added

Installation and Build Instructions for the Server on a Linux Machine

  1. Make sure the machine you want to run on has Python 2.7 installed.
  2. Make sure the machine you want to run on has git installed
  3. Clone this repository from github.
  4. Run the prepare.sh file in the top directory of the project to install all the dependencies for the project.
  5. Run this command to install deployment package

    pip install gunicorn
  6. Run this command to start the server on a linux machine.

    sudo service gunicorn start
  7. Run this command to stop the service.

    sudo server gunicorn stop

Externalizing CTFd

In addition to modifying the CTFd project for classroom use, we also created an Android application that works with the CTFd server for triggering events (e.g. flag submissions) external to the framework proper. The original motivation of the application is to simulate a kinesthetic, “cat and mouse” element to the game. As an example, students equipped with Bluetooth Low Energy beacons attempt to avoid “bad guys” who carries the Android application. When students get too close to the bad guy, she can use the application to penalize the student by removing points from their CTFd account.

The Beacons

For the Bluetooth beacons we chose to use Gimbal devices (http://gimbal.com). Although these devices are not iBeacon devices, they can be configured as iBeacons in order to be detected by the mobile application. Configuring the devices can be pretty tedious however. First the beacon must be registered on the Gimbal portal online. Then the developer can make an iBeacon configuration for the device and assign it to the beacon. These configurations allow for a bit of customizability. Each one supplies the beacon with three unique values: UUID, major, and minor. For our purposes we will only use the UUID and minor however. The UUID is the same universal identifier for each beacon to mark it as one of ours, while the minor will note which student is holding the beacon. Unfortunately, the portal cannot apply the configuration itself, but can only assign the configuration. In order to actually push the configuration, the developer must use a separate Gimbal iOS application that can detect and manage beacons once the beacon’s batteries have been taken out and placed back in.

Detecting the beacons themselves proved to be especially difficult due to the lack of feedback while setting the configuration. The Gimbal devices don’t have any visual display to show whether they are activated or not. Additionally the Gimbal portal doesn’t clearly mark whether or not a beacon is activated so the only real reason is to detect and activate the beacon using the iOS app. The combination of these two things made it difficult to get the first beacon working but once we figured out the process it was more tedious than difficult.

Detecting Beacons

The first hurdle in creating the android application was detecting the nearest Bluetooth beacon and displaying the information from it. Luckily the Android Beacon Library exists to ease some of the pain of finding these devices. With this library we set up a beacon manager and range notifier. Combined, these objects fire an event that emits the list of beacons in range along with their distance and beacon values. Upon beacon emission, we update the UI of the app to display the closest beacon we can find. Unfortunately this process can be fairly inaccurate and shows a margin of error of about a meter or so for the beacon. On top of that, the beacons only emit in a circle of about a three meter radius so the user must be relatively close to the beacons to detect them. For our purposes however, accuracy is not a huge concern as the "monster" should be as close to the player as possible in order to simulate the game better.

Hooking It Up To CTFedu

Hooking the application up to the CTFd server proved to be the most difficult part of its development. Most of the CTFd endpoints currently return HTML pages that then call JavaScript code to make meaningful changes on the server. This specifically became a problem when trying to post an award to the server because posting an award can only be done by an admin. However because the login endpoint returned an HTML page, we had to create a new endpoint that would log the user in and return JSON instead of HTML. Combining both of these the application can login as an admin and then post a new award using the data from the nearest beacon.

App Overview

Currently the app displays the major, minor, UUID, and distance values for the nearest Bluetooth LE device it finds. Then the user can "capture" a student by pressing a button below the beacon information. This will take the minor value for the closest Bluetooth device and assign an award to the user with the same userId on the CTFd server. This means each student will need a Bluetooth device that corresponds to their account on the CTFd server.

The award by default is called "Monster" and has a value of -15, however this is configurable by pressing a button on the top right on the menu bar. The corresponding dialogue allows the user to change the name, value, and description of the award to whatever is appropriate. Additionally the user must input valid admin login credentials in this dialogue in order to post awards. Lack of valid login will result in a failed award upload and the application will notify the user of this using a toast. The login credentials along with the last award used will be saved to local preferences so that the user doesn't have to input them each time.

Installation and Build Instructions for the Android Application

  1. Make sure the machine your using has Android Studio installed
  2. Make sure the Android device you intend to use has Android version 4.4 or higher
  3. Make sure your Android device has USB debugging set on
  4. Clone this repository from github.
  5. Open the project in Android Studio
  6. Run the project with your android device as the given target
  7. When running the application be sure to modify the following configurations by pressing the cog icon on the menu bar:
    • Award Name
    • Award Value
    • Award Description
    • Username
    • Password
  8. Note that an invalid username and password will result in a failure to post the award

How to Configure a Gimbal Beacon

  1. Go to the Gimbal Manager portal found at https://manager.gimbal.com
  2. Register for an account if you do not already have one
  3. Activate the Beacon on the Manager
    1. Click "Beacons" on the left side of the manager
    2. Click on "Beacon Management"
    3. Click on "Add Beacon"
    4. Fill out the information and click "Activate Gimbal Beacon"
    5. Note that the factory id is found on the inside of the Beacon, which is opened using a coin or flat head screwdriver
  4. Create the Beacon Configuration
    1. Click "Beacons" on the left side of the manager
    2. Click on "Beacon Configurations"
    3. Click on "New Configuration"
    4. Make sure to change the configuration type to "iBeacon"
    5. For proximity UUID input "A87EEA45-E597-3C62-6413-6DA093F90FA5"
    6. For minor input the userId for the given user on the CTFd server
    7. Click "Update Configurations"
  5. Assign the Configuration to the Beacon
    1. Click "Beacons" on the left side of the manager
    2. Click on "Beacon Management"
    3. Click on the Beacon you want to configure
    4. Click on "Configuration"
    5. Click on the drop down for "Assigned Configuration" and choose the configuration that you made for the Beacon
    6. Click "Save"
  6. Push the Configuration to the Beacon using an iOS device
    1. Download the Gimbal Beacon Manager application
    2. Activate the beacon from "Activate Beacon" choice in the navigation drawer by scanning the QR code found on the inside of the beacon
    3. Configure the device from the "Configure" choice in the navigation drawer by removing and reinserting the batteries on the beacon and then choosing the configuration of choice

A Final Note

The most recent version of CTFd now supports "plug-ins" to support more back-end customization of the framework, perhaps obviating the need for our fork. Our hope is to eventually roll our changes back into the main CTFd branch as a set of plug-in services.

security, education, CTF