PoC funcional do CVE-2026-52715 (GeoLeak): SQLi não autenticada no GEO my WordPress <= 4.5.5 via swlatlng/nelatlng. Laboratório Docker + exploit time-based/boolean-based + exfiltração sem vírgulas no payload.
Proof of Concept educativa de GeoLeak (CVE-2026-52715), injeção SQL não autenticada (CVSS 9.3) no plugin GEO my WordPress <= 4.5.5 para WordPress. Os parâmetros
swlatlngenelatlngdos limites do mapa são interpolados sem saneamento na cláusula WHERE. Laboratório Docker autocontido + exploit com técnicas time-based, boolean-based e exfiltração caractere a caractere.
CVE-2026-52715 é uma injeção SQL (CWE-89) na função gmw_get_locations_within_boundaries_sql() do plugin GEO my WordPress, que afeta todas as versões <= 4.5.5 e está corrigida desde a 4.5.5.1 (15 de junho de 2026). Foi descoberta pelo pesquisador alvarodh5 e publicada via Patchstack.
A cadeia batizada GeoLeak demonstra como, partindo apenas de acesso de leitura a qualquer página pública que contenha o shortcode [gmw], um atacante pode:
swlatlng (ou nelatlng) do query string, sem cookies, sem nonce e sem autenticação.SLEEP() (time-based blind) avaliado por cada linha do INNER JOIN contra wp_gmw_locations."total_results":N que o próprio plugin incorpora no JSON de configuração do mapa para inferir condições booleanas (boolean-based blind).explode(',', ...)), mediante CASE WHEN e SUBSTRING(x FROM n FOR 1).O resultado é leitura arbitrária da base de dados do WordPress: tabela wp_users (hashes de senhas), opções de configuração, chaves e dados de terceiros armazenados em plugins.
Na PoC, verifica-se a extração completa de VERSION() do MariaDB apenas com requisições GET.
Este repositório contém material estritamente educativo e defensivo.
┌─────────────────────────────────────────────────────────────────────┐
│ 1. Requisição pública sem autenticação │
│ GET /?page_id=5&form=1&action=fs&swlatlng=<payload>&nelatlng=… │
│ página pública com shortcode [gmw form="1"] │
└──────────────────────────────────────────────────┬──────────────────┘
▼
┌─────────────────────────────────────────────────────────────────────┐
│ 2. GMW_Form::set_default_values() │
│ action=fs => formulário marcado como enviado │
│ get_form_values() obtém $_SERVER['QUERY_STRING'] │
└──────────────────────────────────────────────────┬──────────────────┘
▼
┌─────────────────────────────────────────────────────────────────────┐
│ 3. gmw_get_form_values() (gmw-functions.php:512) │
│ parse_str($query_string, $output) sem lista de permitidos │
│ $output['swlatlng'] chega intacto │
└──────────────────────────────────────────────────┬──────────────────┘
▼
┌─────────────────────────────────────────────────────────────────────┐
│ 4. parse_query_args() (class-gmw-form-core.php:794) │
│ gmw_swlatlng / gmw_nelatlng copiados para os argumentos de busca│
└──────────────────────────────────────────────────┬──────────────────┘
▼
┌─────────────────────────────────────────────────────────────────────┐
│ 5. gmw_get_locations_within_boundaries_sql() (gmw-functions:669) │
│ $sw = explode(',', $southwest); │
│ "AND ( gmw_locations.latitude BETWEEN {$sw[0]} AND {$ne[0]} )" │
│ interpolação direta: sem prepare, sem validação │
└──────────────────────────────────────────────────┬──────────────────┘
▼
┌─────────────────────────────────────────────────────────────────────┐
│ 6. WP_Query -> $wpdb->get_results() │
│ SQL: ... AND ( gmw_locations.latitude BETWEEN │
│ 1 AND SLEEP(5) AND 40.416775 AND 41 ) ... │
│ resposta atrasada 5s / total_results = oráculo │
└─────────────────────────────────────────────────────────────────────┘
curl e awk para o exploitdocker-compose.yml)POC-GeoLeak-CVE-2026-52715/
├── docker-compose.yml WordPress 6.8 (PHP 8.2) + MariaDB 11
├── docker/
│ ├── Dockerfile Imagem WP + WP-CLI + entrypoint do laboratório
│ ├── lab-entrypoint.sh Inicialização + semeadura automática no primeiro boot
│ ├── seed.sh Instalação WP, formulário, post geolocalizado
│ └── geo-my-wp/ Plugin GEO my WordPress 4.5.5 (código vulnerável)
├── poc/
│ └── poc.sh Exploit: time-based + boolean-based + exfiltração
├── docs/
│ ├── analise-tecnica.md Cadeia completa request -> SQL, com código
│ └── diff-patch-4.5.5.1-gmw-functions.php.diff Patch oficial real
├── LICENSE
└── README.md
# 1. Subir o laboratório (primeira inicialização: 60-90 s)
docker compose up -d --build
# 2. Verificar se a semeadura terminou
docker compose logs wordpress | grep lab-entrypoint
# [lab-entrypoint] laboratório pronto
# 3. Executar a PoC
./poc/poc.sh
# 4. Destruir o laboratório
docker compose down -v
Parâmetros configuráveis do exploit:
TARGET=http://localhost:3080 PAGE_ID=5 FORM_ID=1 SLEEP=5 ./poc/poc.sh
Acesso ao WordPress: http://localhost:3080 com admin/admin. A página com o formulário vulnerável é http://localhost:3080/?page_id=5.
Nota: a linha semeadura em
wp_gmw_locationsé imprescindível. A consulta usa INNER JOIN contra essa tabela: sem linhas, o WHERE injetado não é avaliado eSLEEP()não dorme.
Saída real da última execução contra o laboratório (14 de agosto de 2026):