This is my third Huntress CTF. The first one, my team finished in the top 50. Last year was a wash, a DNF. This year I came in late again, and I will be honest, when I finally sat down on Saturday night, October 10, I was not thinking about a comeback. I was thinking “how far behind am I?”
Pretty far. Ten days of challenges were already out, 152 of them counting every mode, and the board was full of teams who had been at it since day one.
Then I read what this year’s event actually was, and the math changed.
AI Arena
This is the fourth Huntress CTF, and this year it has a theme: AI Arena. The organizer put the whole idea in one line on the intro page:
“I don’t want you to play this CTF… I want your robot to play the CTF.”
The goal this year is not to be the fastest person at a keyboard. It is to build something deterministic that can play on its own, survive new variants of a challenge, and get faster every time it sees the same idea again. The organizer even asks the question I ended up living with all month: where does a human still have to step in?
I do security for a living. I build automation for a living. An event where the scoring rewards whoever builds the best machine is not a stretch for me. It is the job. Ten days late or not, this one is in my wheelhouse, and I am here to win it.
How the game works
Every morning at 09:00 Eastern a new day unlocks, Day 1 through Day 31. Each day brings the same five lanes:
- Warmups: a blob of text wrapped in stacked encodings that you peel back to a short instruction.
- Metadata forensics: questions about what a file says about itself. Images, PDFs, archives, Office documents, shortcuts, executables.
- Script analysis: a zip of small scripts in half a dozen languages (PowerShell, batch, VBScript, JScript, Bash, Python, Node), each hiding what it would do if you ran it.
- Binary reverse engineering: compiled programs from a different toolchain every day. C on Day 1, then C++, .NET, Go, Rust, Java, Kotlin, and on from there.
- Mobile Android: an APK with a puzzle buried inside it.
Each challenge has three modes, and each one unlocks the next. The Single Solve is one file and no clock. The Time Trial hands you a fresh variant and starts a server clock. The Mastery hands you several variants at once, sometimes mixing in ideas from earlier days, against one shared clock. On Day 1 that clock was 30 seconds. By Day 4 it was six to ten. A person opening a file in a hex editor cannot make that. A program can.
Points are points, but the Hall of Fame board for every timed mode is ranked by time. That is the real scoreboard.
Day 1, the slow way
I started the way most people did, with Homebase: a browser workspace the event provides, with an AI coding assistant already wired up to the Game Master (the event’s API that hands out challenges and grades answers). Between 11:00 and 11:12 that night I worked through most of Day 1 with it, one challenge at a time. A Little Based. You Must Be This Hash to Ride. Power Play. ELF Aware. Exported Trust. Read the question, poke at the file, paste an answer, wait for the verdict.
It worked. And every board I landed on, I landed on the bottom of it.
- Warmups Mastery: 38th of 38, 9.4 seconds.
- Script analysis Mastery: 45th of 45, 16.8 seconds.
- Mobile Mastery: 28th of 28, 7.4 seconds.
My hand-played times ran from 2.8 to 25.8 seconds. The people above me were finishing in a fraction of one. Being right was never the hard part. Being right in a third of a second was.
That told me exactly how the rest of this month had to go.
Building the robot
At 11:47 that night the first call went out from my own desktop instead of Homebase: a Day 1 warmups Time Trial, answered CORRECT. Two minutes later the first commit landed in a fresh private repo. It held a small client for the Game Master, the event’s rules boiled down into a guide the robot reads before every session, and a sandbox that runs anything suspicious with no network and no access to my files. Three commits before midnight. That was the whole foundation.
I set the ground rules that night, and they held for the rest of the event:
- The robot does the work, and explains while working. I set the strategy and the rules; it reads the files, writes the solvers, and tells me what it found and why. After every challenge it writes up the technique, so I come out knowing the trick, not just holding a flag.
- Every solve becomes a solver. If we answer something by hand, that answer goes into code first. Tomorrow’s version of the same idea should already be handled before I wake up.
- Samples stay in the box. Nothing from a challenge runs on my desktop. Files get decoded and parsed, never executed, and if something truly has to run, it goes in the sandbox.
- Tool installs are pre-approved. If the robot needs a disassembler or a decompiler, it installs it. No waiting on me.
I went to bed ten days behind, last on every board I had touched, with a repo that could do exactly one thing. Within a few days every one of those Day 1 boards had moved from last place into the top twelve, most of them into the top five. But that is getting ahead of the story.