Wow. Hacktober CTF was a wild ride! We had over 2,700 players worldwide attend this year's event in support of National Cyber Security Awareness Month - the most this event has seen in its 4-year history.
This blog is a follow-up to the Hacktober 2020 CTF blog I wrote back in August. We anticipated about 300 players this year and - as mentioned in the previous paragraph - we far exceeded that. In this blog, I'll go over some of the successes and lessons learned from this event.
One of the major factors that contributed to this year's success was that we began planning the event back in early June. Normally, planning for Hacktober doesn't begin until about August. Having an extra two months allowed the team to better plan out the event and produce a higher amount of new challenges than previous years.
I won't sugarcoat it. The unfortunate reality of these events is that volunteers are difficult to come by. Based on my personal experience, many people are reluctant to volunteer because they would rather play or because they lack confidence in their abilities to create worthwhile challenges. My response to anyone that is thinking about volunteering but doubting their abilities is to just make the leap and go for it! Having more volunteers will help guarantee success for these events.
As far as lessons learned go: have a robust team. As many of you that were in the Slack channel could tell - I (@syyntax) and Jason Killam (@Killam) were humorously outnumbered compared to the sheer amount of players we had looking for help and clarity. Going forward, we'll do our best to encourage others to volunteer and help.
One thing that really helped us this year was coordinating and documenting our processes. We used Trello to keep track of the story, the challenges, the environment, everything! Trello is an incredible tool and it helped us tremendously.
One thing CTFs commonly overlook is documenting their challenges and the solutions to them. This year, we used Trello to keep track of all challenges, their solutions, and their flags. That way, if someone needed help on a challenge, we could give them a nudge and make sure the flag was configured correctly.
We learned a LOT about how to correctly scope and build a CTF environment. As one Slack member so eloquently kept repeating during the first hour: ⭐INFRASTRUCTURE⭐.
The Scoring Server
As I mentioned earlier, we originally projected about 300 players based on our Eventbrite sign-ups. So, based on that, we stood up a Digital Ocean droplet to host our CTFd docker container. We only purchased 2 CPUs and 8GB RAM. As we found out, 2 CPUs isn't enough to support 2,000+ people trying to access the scoring site. Thankfully, it was back up and running within an hour after I resized it to 8 CPUs and 16GB RAM.
Another lesson learned is to ensure HTTPS is running on the scoring site. When we originally built the scoring site, we built it in a docker container and used docker-proxy to map the host TCP port 80 to the container's (CTFd's) TCP port 8000. Because we did it this way, we couldn't run nginx on the host since port 80 wasn't free. The only solution was to spin down the CTFd docker container, run nginx on the host, then spin the CTFd container back up.
This solution sounds easy enough and would likely have worked; however, we didn't consider it until the night before the event. We didn't want to risk having to troubleshoot the new CTFd instance and potentially have it not working in time for the CTF, while simultaneously preventing new users from being able to access the site and register. For our next CTF, we'll definitely make sure we configure HTTPS well in advance.
Many of the challenges provided in this CTF were a hit! Based on feedback from the players, the following challenges were some of their favorites:
- Whispers in the Dark (Steganography)
- What Lies in the Shadows (Web)
- Coins (Web)
Challenges with Problems
Most of the challenges had no issues whatsoever, but there were two of the 67 challenges that had to be modified during the event.
Calisota was, by far, the challenge I regretted most. In this challenge, players had to submit the SQL command that yielded a specific result. As I learned, never ever ask players to produce a command that can have tons of variations. I should have scrapped the challenge altogether, but instead I opted to allow players to submit their results and commands to me individually which took up a lot of my time and attention.
Jigsaw was another challenge I had to rewrite. This challenge asked players to find a result based on very specific criteria. I failed to be specific enough, so players ended up finding the wrong results. Next time, if I include a challenge similar to Jigsaw in the future, I'll be sure to sanity-check my regular expressions with the staff.
Red Rum and Stairway to Hell were actually very popular and well-received challenges, but with a caveat. These challenges required users to write a program to fulfill the challenge request and then submit it via netcat to the server. The server script I wrote did not always take the input correctly, so it wouldn't return the flag. Sometimes, players had to add an extra newline to their string. Other times, they had to update their netcat versions. I programmed the script to take the literal string and compare it with the variable in the server script, but there's still something wrong with it that I will fix for the next event.
Most of the players that participated in Hacktober CTF came from seeing our event posted on ctftime. This turned out to be one of the biggest contributors to the success of this event (and also the biggest contributor to our scaling issues). Because we advertised the event on CTFtime, we saw participants from all around the world join our event! This was truly a humbling experience to build an event that so many people from all over the world enjoyed.
One thing I learned about CTFtime though is that CTFd doesn't export its scoreboard JSON in a schema compatible with CTFtime. That meant I had to programmatically convert the JSON schema or use a CTFd plugin that did the work for me.
After the Event
After the event, we issued out digital badges from Badgr.io. The feedback for these badges was great! A bunch of players hit me up almost hourly asking about the badges. Awarding badges is something not often seen in CTFs and helped garner interest in participating. By awarding badges, everyone feels like they left with something to show they played, encouraging people to participate.
The feedback from the CTF was overwhelmingly positive! Based on feedback from the players, one thing they really enjoyed was how the challenges related to each other and how the environment played a role. In order to solve one challenge, you had to have discovered information from a previous challenge. Not a lot of CTFs do that.
Another very important piece of feedback we received was how well the competition catered to various skill levels. Many players new to CTFs said they enjoyed being able to solve more than one challenge (compared to other CTFs). Most CTFs are absurdly difficult because they only focus on challenging pro-level players.
This was the most fun I had developing and running a CTF. From start to finish, this CTF was the best developed and best received by players than my previous CTFs. I am truly humbled by the positive feedback received from the players. Watching the players solve the challenges and help each other out was an amazing experience. I can't wait to host the next CTF!
CyberUp recorded our post-Hacktober CTF awards video where I and the team talk about the event and what went into building it. You can watch the video here: https://www.pscp.tv/w/1jMJgXmvVZMxL.