I grew up playing capture the flag both outside with friends and in Unreal Tournament, but a CTF competition in cybersecurity was new to me until hearing about the CyberDrain CTF. CTF competitions are designed to test a variety of cybersecurity skills, in purposefully-vulnerable setups. Flags, which are just bits of text could be hidden in all sorts of places, buried deep in source code, disguised within an encrypted message or behind vulnerable web applications, maybe lost in a corrupt database we don’t have the password for. The concept reminded me of Hack This Site and other hacking wargame sites I spent too much time on 20 years ago.

The CyberDrain CTF differs from most CTF competitions because it focuses on system administration and engineering. This is fitting as CyberDrain is the company behind the very popular CyberDrain Improved Partner Portal (CIPP), a tool for multi-tenant Microsoft 365 administration.

Before the competition started, there was a pre-registration event. This included recycled challenges from previous years, the categories of these challenges were in DevOps, Knowledge Questions, Linux, M365, Server and Workstation. Since this was my first year, these challenges would be new to me, and could give me some much needed insight into where flags might and might not be, and also what type of environment I should have ready for the real challenges.

There was a problem though, the pre-registration event was locked with a CTF code we required to complete the registration form. I guess this was the real first flag. The event organizer Kelvin Tegelaar opened the pre-registration event with this message:

We are bringing 6 weeks of challenges to you before we start with 3 challenges a week.
These challenges are classic CTF challenges ranging all the way to CTF v1! Public
registration will open in two weeks, but if you're a smart-cookie you'll already be
able to register today.

Go check out https://ctf.cyberdrain.com/go get started and try to get registered.

And after all of that is said and done, I wish you much luck and we'll see you with an
update when we open the first Classic challenge on Monday. Allow me to leave you with
these words. Jellybean-Pickle-Groove

So, lets check that page out. I viewed the source of that page and others on the site… after not finding a useful flag or clue, I re-visited the above URL and decided to look through the only thing interesting on this page. A single PNG file. In fact, it was this image:

A seemingly plain looking image, until you look at the metadata. I did this by opening the image in a text editor, and seeing the human-readable text here:

<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="XMP Core 4.4.0-Exiv2">
 <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
  <rdf:Description rdf:about=""
   ...
   >
   <xmpMM:History>
    <rdf:Seq>
     <rdf:li
      stEvt:action="saved"
      stEvt:changed="/metadata"
      stEvt:instanceID="xmp.iid:dcb34457-93a0-4ae0-9643-a936fd1db358"
      stEvt:softwareAgent="Gimp 2.10 (Mac OS)"
      stEvt:when="2024-07-26T16:57:18-04:00"/>
     ...
    </rdf:Seq>
   </xmpMM:History>
   <dc:description>
    <rdf:Alt>
     <rdf:li xml:lang="x-default">https://engine.rewst.io/webhooks/custom/trigger/0190f099-cdf9-7388-ac7e-6ab9e02b3eba/f6789f77-7cce-4b10-9be6-89b99f2a36ac</rdf:li>
    </rdf:Alt>
   </dc:description>
  </rdf:Description>
 </rdf:RDF>
</x:xmpmeta>

An application like Phil Harvey’s ExifTool would reveal this information just as quickly:

> exiftool CyberDrain-CTF_letsgo.png
ExifTool Version Number         : 13.02
File Name                       : CyberDrain-CTF_letsgo.png
...
Orientation                     : Horizontal (normal)
X Resolution                    : 72
Y Resolution                    : 72
Resolution Unit                 : inches
Software                        : GIMP 2.10.38
Color Space                     : sRGB
GPS Altitude                    : 0 m
Caption-Abstract                : https://engine.rewst.io/webhooks/custom/trigger/0190f099-cdf9-7388-ac7e-6ab9e02b3eba/f6789f77-7cce-4b10-9be6-89b99f2a36ac
...

I see that the image was made with GIMP v2.10 for Mac OS… and an unexpected webook URL to rewst.io, a popular process automation platform.

Let’s take a look at this new Rewst URL a bit more, and see what happens when we make a GET request with curl:

> REWST_URL="https://engine.rewst.io/webhooks/custom/trigger/0190f099-cdf9-7388-ac7e-6ab9e02b3eba/f6789f77-7cce-4b10-9be6-89b99f2a36ac"
> curl -L "$URL"
{"error":"x-rewst-secret header not provided."}

It’s response states we’re missing a secret header, I wonder if that’s what the Pickle-Jellybean-Groove message was about. Let’s try adding an x-rewst-secret header with that as the value:

> REWST_SECRET="Jellybean-Pickle-Groove"
> curl -L "$REWST_URL" -H "x-rewst-secret: $REWST_SECRET"
{"results":{"message":"Ready to post a record-breaking time on this challenge?"}}

If I’ve learned anything from developing software, it’s that a different error message is progress. Let’s change this to make a POST request, since the message contains this word:

> curl -L "$REWST_URL" -H "x-rewst-secret: $REWST_SECRET" -d "test"
{"results":{"message":"Invalid user"}}

This looks very promising, it mentions an invalid user which makes sense since I didn’t include one in the body of our request. Let’s add a user and see where it gets us, I used the same username I planned on registering with to the CTF with:

> curl -L "$REWST_URL" -H "x-rewst-secret: $REWST_SECRET" -F "user=rdkempt"
{"results":{"code":"letmeiniwannaplay!","message":"Success! You can now register for the CTF."}}

Success! We found the registration code. Using this code let me sign up for an account to get access to the pre-registration event.

I performed well during the pre-registration event, especially considering I was competing against hundreds of skilled administrators, many of who had already solved these exact challenges. After completing all of the practice challenges, I felt well-prepared for the actual CTF competition.

Scoring worked the same for the pre-registration event and the actual CTF competition. You are rewarded points for finding the correct flag, and the first one with the most points at the end wins. 10 points for a knowledge question and 100-200 points for flags, depending on their difficulty. The flags were hidden in Microsoft 365 tenants, Linux, Windows 10 and Windows Server virtual machines, SQL Server, Exchange, and GitHub workflows.

As challenges were released, there was a hurry to solve them as quickly as possible, trying to maintain your position in the leaderboards and to not get too far behind. Although I had consistently held a top position, I was not the first to solve any of the challenges because they were being released during work hours. That is until the last challenge, which I knew could determine the final winners of the competition. I turned on notifications and had prepared everything as best I could the morning of to handle any challenge thrown at us during the day. I was logged into each system they had provided us, all of the virtual machines were booted, and then it happened, the final challenge was unlocked.

It was recovering a deleted password from a Hudu instance I had discovered in the Microsoft 365 tenant from a previous challenge. I solved the last challenge instantly and secured my title as the winner of the 2024 CyberDrain CTF.

The competition offered first place a Meta Quest 3, fully decked out with a carry case, charging dock and $100 gift card, though I opted for the cash value since I already have a PS VR2 which doesn’t get used as often as I’d like. It was a fantastic experience overall, with a strong sense of community among participants. I’m grateful for the chance to compete alongside such talented individuals, and am already looking forward to seeing how CyberDrain will challenge us all next year.

Oh, and a special thanks to the CyberDrain team including Kelvin Tegelaar, Gavin Stone, Luke Whitelock and John Duprey. As well as the event sponsors Ninja One, OITVoip, HaloPSA, Rising Tide Group and Hudu!