How the Coinbase Security team deployed CTFd to Power our First Capture the Flag contest at Defcon 27 Coinbase Follow Oct 21, 2019 · 6 min read

By Nishil Shah and Peter Kacherginsky

We recently ran Coinbase’s first Capture the Flag (CTF) competition called Capture the Coin. As part of running the CTF, we needed to setup the underlying infrastructure. In this guide we’ll describe our process from choosing a CTF platform to getting it production ready. This CTF definitely would not have been possible without all the open source contributors, projects, tutorials, and free services we leveraged, so we’re making this guide as a small contribution back to the community. Overall, the process took us a few weeks to setup, but with this guide, you’ll only spend a few days.

Choosing a CTF Platform

We chose CTFd as our CTF platform based on the following criteria:

Challenge Input Interface

Support for Types of Challenges

Free Response (Static and Pattern-Based)

Dynamic Value

Multiple Choice

Custom Plugins

Public Scoreboard

User and Team Registration

Admin Panel

Player Communications

Hints

Active Maintainers

CTFd had support for most of our requirements except for multiple choice questions. However, requirements like having active maintainers was useful when the maintainers quickly patched a bug in a few hours. We also wanted to write challenges that forced users to interact with a real blockchain. This would require some custom development, so we also wanted the ability to build our own custom modules. Anecdotally, a few other CTFs had run successfully on CTFd. Given these requirements, CTFd matched our needs the closest.

CTFd mostly worked out of the box by following the README instructions; however, we did run into one issue. Out of the box, CTFd started running really slow. We did some basic debugging like looking at memory and CPU utilization to see if we needed to upgrade our EC2 instance. In general, resource consumption was generally less than 1%. We eventually found out that using Sync workers was inefficient. We changed the settings to use async gevent workers and correctly setting worker_connections and workers using the advice from this post. This solved our issue and CTFd worked great with very little latency.

Capture the Coin Infrastructure

Setting up and running this CTF was a great learning experience in getting hands-on with AWS and debugging real issues. As appsec engineers reviewing code or infrastructure, we often times can become unsympathetic to how hard an engineers’ job can be when defining security requirements even in a #SecurityFirst engineering culture. Just for something as simple as a CTF, the bill of materials starts to pile up as you can see below.

EC2

IAM

Lambda

RDS Aurora

S3

SES

Here’s a network diagram of what our AWS infrastructure looked like at a high level.