Hack the Hague 2026
Hack the Hague 2026 started with a reception and opening, with an introduction to the people involved. We learned about the rules of engagement and got a short overview of the awards that would be given out at the end of the event.
Following this, we were brought to the tables that had been set out in the atrium of the city hall. We could find the full scope and guidelines on printed papers on our tables. After reading these, we could finally start hacking.
Or so we thought...
Getting started
According to the briefing, we should use the provided network, so traffic could be monitored properly. Either via cable or wireless.
However, this day and age, none of our laptops have a cable plug anymore, and the wireless password had not been provided at the event yet.
Hackers as we are, we quickly set up our own wireless networks and started working anyway. We started mapping out the scope quickly and semi-passively.
Then, shortly after, we received an email containing the Wi-Fi password and a link where we could file our reports.
At this point, most of us were well on our way to finding our first bugs. This wasn't all highs and crits yet, but the beginning was there.
At least for the people sitting around me.
For me, I was still trying to figure out what part of the scope would be most interesting to dive into.
Finding a target
At this point, someone from the organization came by our table to provide us with a scope update. One of the provided staging domains was incorrect. We needed to go for the main domain.
So there it was. I too had my target of focus selected.
There was a good deal of data that had been collected during the initial recon phase, so it seemed to be a good choice.
The app itself did not reveal much except for a login page, but the full client-side code was accessible, including ".map" files. These allowed me to go from minified code back to the fully recovered source files and folder structure.
Based on this intel alone, I had been able to recover a good deal of leads.
But, alas!
All leads required a session to be able to prove them.
All except perhaps one.
One interesting lead
There was one lead that stood out. One that could be enough to prove without a working session.
Many in one, actually.
In the case of this locked-down app, the client-side source revealed some state-changing actions performed explicitly over "GET" requests.
This means a malicious actor can force a legitimate user to visit a link and perform an action unknowingly.
There were multiple actions that could potentially be triggered this way.
While it might be too few to be accepted, due to the nature of the app, I decided to report it anyway.
We'll see what the triage team will decide regarding this issue.
Changing tactics
Now that half the day had passed, I decided to look into other assets throughout the scope.
This time I went for a different method: finding pre-auth 0-days in any of the in-scope WordPress assets.
This ended up being a good decision.
While results from the reports aren't back yet, I can give a brief description of my approach.
First things first, I needed a clear overview of all assets using WordPress.
That's easy enough.
Writing some straightforward fingerprinting commands using HTTPX and the regex match parameter gave me a list of assets.
Now I needed to know which plugins were being used.
At this stage, I don't care much about hidden plugins. Just parsing out the ones used on the homepages is good enough for now.
Once I had a list of plugins, it was a good time for me to give good old Claude a task to help me prioritize.
I let it download each plugin and prioritize them based on which plugins exposed the most pre-auth surface.
Once shortlisted, I let it help me set up a local Docker environment with the plugins pre-installed.
This allowed me to quickly audit the code and locally test any assumptions before trying this against the production environments of The Hague.
Two more vulnerabilities
After going through a couple of the plugins, I finally landed another pair of vulnerabilities.
Comparing them to the live instance, they actually worked!
But wait!
The version of the live instance is still lower than mine!
Claude took the task seriously and only downloaded the latest releases.
That means I now have two more reports that might not be accepted due to them being 0-days.
I reported them anyway.
Let's see how it goes!
The end of the day
With that came the end of the day.
After submissions closed, there was still a raffle where five lucky people won a Flipper Zero, a neat little device that can be used to test wireless protocols.
This gave the triage team enough time to go through the submissions and decide who would win the awards.
Alas! I was not one of them.
Three of the people sharing my table were, though, so congratulations to Erik, Jonathan and Max!
It was a great opportunity to learn from them by talking about their skills.
After the awards were handed out, we had time for some networking and pizza.
Final thoughts
All in all, a great event.
For me, the day was a good reminder that you don't necessarily have to stick with one approach when hunting for bugs.
I started by mapping the scope and then focused on an application where the client-side source code gave me a good deal of leads. When most of those required authentication, I switched tactics and started looking at the WordPress assets instead.
That ended up being a good decision.
Sometimes it's not about finding a better payload or a more clever trick. Sometimes it's simply about recognizing when one approach isn't giving you enough to work with and moving on to something else.
Thanks to the City of The Hague for organizing and for keeping their citizens safe!
YouGina
Software engineer and security researcher. I write about bug bounty hunting, application security, and the craft of building software that is harder to break.
Get in touch
@yougina
For research questions, disclosure conversations, or a second opinion on something you are working through.