← All work

Training platform · Detection scoring

The Gauntlet

A scored campaign layered over the range. Nineteen challenges that run from network reconnaissance to a full domain compromise, each with a flag that cannot be looked up online — and a scoring model that cares whether the defenders saw you coming.

Role Designer and developer
Stack Flask, SQLite, vanilla JS
Content 19 challenges across 9 chapters
Status Built and verified, not yet deployed

The gap it fills

The range came with two written guidebooks — good exercises, exact commands, real objectives. But a document cannot tell you whether you actually did the thing. You read it, you nod, you move on, and nothing checks.

The Gauntlet turns those same exercises into something that verifies. Same content, same techniques, but now completing a challenge requires producing evidence the system can check, and the system is watching how loudly you did it.

Flags that cannot be googled

Public CTF answers leak. Any challenge with a fixed flag has a shelf life measured in how long it takes someone to paste it into a forum.

Each flag here is derived from a keyed hash of the challenge identifier and a secret unique to that installation of the range. A planting tool derives the same value and places it behind the challenge's real win condition — inside a file you can only read after privilege escalation, in a database row you can only reach through injection, as the password on an account you have to actually crack. The backend recomputes it to verify.

Two people running the same challenge on two different ranges get different flags. There is nothing to share and nothing to search for. The only way through is the technique.

Scoring the blue team, not just the red

This is the part I actually built it for. Capture-the-flag scoring rewards getting in. Real security work is also about whether getting in was noticed.

When a run ends, the backend queries the SIEM's index over that run's exact time window and compares what fired against what each challenge expected to fire.

  • Offensive challenges pay a stealth bonus only if no matching detection alerted during the window. Complete the objective loudly and you still score — you just score less.
  • Defender missions invert it entirely. You clear them by making a rule fire: write detection logic for a technique that currently slips through, trigger it, and the alert appearing in the index is the win condition.

That second category is the one I have not seen elsewhere, and it is the closest thing in the whole project to what a detection engineer's day actually looks like.

Design decision

The game engine contains no addresses. Challenges reference logical target keys, and a single configuration file is the only range-specific piece — which is what makes the campaign portable to a range that is not mine.

Degrading gracefully

A platform that only works when every dependency is healthy is a platform nobody can pick up. The Gauntlet was built to lose capabilities without losing playability:

  • No target configuration present, flag verification falls back to a local check.
  • No SIEM reachable, stealth bonuses are skipped and defender missions fall back to honest self-confirmation.
  • Both missing, it is still a fully playable red-team campaign, offline.

The planting tool follows the same principle from the other direction: it defaults to a dry run and shows you exactly what it intends to place on which machine before it touches anything. Tooling that modifies live systems should have to be told twice.

The frame around it

The nine chapters follow the structure of the second guidebook, which is themed on Dante's descent — reconnaissance at the surface, domain compromise at the bottom, each chapter unlocking only when the previous one's final challenge falls. There are ranks, a hint economy where hints cost a fraction of the challenge's value with a floor so a hinted solve is never worth nothing, and achievements.

The theming is restrained on purpose. It is there to give the progression a shape you can feel; the challenges underneath are real techniques against real misconfigurations, and that is what has to carry it.

Why the game design is not an accident

I hold six college certificates in simulation and game development, earned before I moved into security. Difficulty curves, unlock gating, and scoring that rewards the behaviour you actually want are the things that coursework was about. This project is that training pointed at a security range instead of at entertainment.

Where it stands

The engine, frontend, and backend are complete and verified end to end in a browser — flag submission, experience award, rank progression, chapter unlocking, and persistence across restarts all confirmed against the real backend. Test artifacts were cleaned out afterward so the checkout is pristine.

It has not been planted on the live range yet. That is a deliberate stop: it means writing real flags onto production lab machines, and it waits for a considered go-ahead rather than happening as a side effect of finishing the code.

What it proves

I can design a verification scheme that resists the obvious cheat; build a scoring model around detection rather than exploitation alone; keep game logic decoupled from the environment it runs against; and ship tooling that touches production systems conservatively by default.