Skip to content
KitploitKITPLOIT
ToolsBlog
Submit
ToolsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

··Feeds·Contact·Privacy·© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
POC-GeoLeak-CVE-2026-52715 — PoC funcional de CVE-2026-52715 (GeoLeak): SQLi no autenticada en GEO my WordPress <= 4.5.5 via swlatlng/nelatlng. Laboratorio Docker + exploit time-based/boolean-based + exfiltracion sin comas en payload. | Kitploit
Tools/GitHubGitHub/686f6c61/poc-geoleak-cve-2026-52715
Vulnerability AnalysisExploitationWeb Application ExploitationPenetration TestingLearning & EducationPayload DevelopmentLabs & Practice
GitHub686f6c61/poc-geoleak-cve-2026-52715

POC-GeoLeak-CVE-2026-52715

PoC funcional de CVE-2026-52715 (GeoLeak): SQLi no autenticada en GEO my WordPress <= 4.5.5 via swlatlng/nelatlng. Laboratorio Docker + exploit time-based/boolean-based + exfiltracion sin comas en payload.

View Repository
326 days agoNot yet reviewed

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share

GeoLeak — PoC for CVE-2026-52715

Educational Proof of Concept for GeoLeak (CVE-2026-52715), an unauthenticated SQL injection (CVSS 9.3) in the GEO my WordPress <= 4.5.5 plugin for WordPress. The swlatlng and nelatlng map boundary parameters are interpolated without sanitization into the WHERE clause. Self-contained Docker lab + exploit featuring time-based, boolean-based, and character-by-character exfiltration techniques.


Table of Contents

  1. Executive Summary
  2. Legal Notice
  3. Chain Architecture
  4. Requirements
  5. Repository Structure
  6. Quick Start Guide
  7. Exploitation Verification
  8. Technical Analysis
  9. The Official Patch (4.5.5.1)
  10. Mitigation
  11. Credits
  12. License

Executive Summary

CVE-2026-52715 is an SQL injection (CWE-89) in the function of the GEO my WordPress plugin, affecting all versions and patched since (June 15, 2026). It was discovered by researcher and published via Patchstack.

gmw_get_locations_within_boundaries_sql()
<= 4.5.5
4.5.5.1
alvarodh5

The chain dubbed GeoLeak demonstrates how, starting from read-only access to any public page containing the [gmw] shortcode, an attacker can:

  1. Inject arbitrary SQL through the swlatlng (or nelatlng) query string parameter, without cookies, nonce, or authentication.
  2. Force measurable delays with SLEEP() (time-based blind) evaluated for each row of the INNER JOIN against wp_gmw_locations.
  3. Use the "total_results":N oracle that the plugin itself embeds in the map configuration JSON to infer boolean conditions (boolean-based blind).
  4. Exfiltrate the entire database character by character, bypassing the restriction that the payload cannot contain commas (PHP splits the value with explode(',', ...)), using CASE WHEN and SUBSTRING(x FROM n FOR 1).

The result is arbitrary read access to the WordPress database: the wp_users table (password hashes), configuration options, keys, and third-party data stored in plugins.

The PoC verifies the complete extraction of MariaDB's VERSION() using only GET requests.


Legal Notice

This repository contains strictly educational and defensive material.

  • Purpose: demonstrate the exploitation chain for training, self-auditing, and patch validation purposes.
  • Authorized use: run it only against systems you own or for which you have explicit written authorization. The included Docker lab is the only intended environment.
  • Prohibited: any use against third-party systems without consent. The repository author is not responsible for misuse of the material included here.
  • Responsibility: the operator is solely responsible for compliance with applicable legislation (LOPD/GDPR in Spain, CFAA in the US, etc.).

Chain Architecture

root@kitploit:~
┌─────────────────────────────────────────────────────────────────────┐
│  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                │
└─────────────────────────────────────────────────────────────────────┘

Requirements

  • Docker and Docker Compose (tested with Docker 29.4.1 / Compose v5.2.0)
  • curl and awk for the exploit
  • Port 3080 free (or change the mapping in docker-compose.yml)

Repository Structure

root@kitploit:~
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

Quick Start Guide

root@kitploit:~
# 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

Configurable exploit parameters:

root@kitploit:~
TARGET=http://localhost:3080 PAGE_ID=5 FORM_ID=1 SLEEP=5 ./poc/poc.sh

WordPress access: http://localhost:3080 with admin/admin. The page with the vulnerable form is http://localhost:3080/?page_id=5.

Note: the seed row in wp_gmw_locations is essential. The query uses INNER JOIN against that table: without rows the injected WHERE is not evaluated and SLEEP() does not sleep.


Exploitation Verification

Real output from the last run against the lab (August 14, 2026):

root@kitploit:~
$ ./poc/poc.sh
===================================================
 CVE-2026-52715 | GEO my WordPress <= 4.5.5
 SQLi no autenticada via swlatlng/nelatlng
 Objetivo: http://localhost:3080
===================================================
[*] Prueba time-based (SLEEP 5s)...
    Peticion benigna : 0.037000s
    Payload SLEEP    : 5.034984s
[+] VULNERABLE: retardo de 5.034984s confirma la inyeccion SQL
[*] Prueba boolean-based (oraculo total_results)...
    Condicion TRUE  -> total_results=1
    Condicion FALSE -> total_results=0
[+] VULNERABLE: el numero de resultados depende de la condicion inyectada
[*] Extraccion de VERSION() caracter a caracter...
[+] VERSION() = 11.8.8-MariaDB-ubu2404
[*] PoC completado

Cross-check directly against the database:

root@kitploit:~
$ docker exec cve-2026-52715-db mariadb -u wordpress -pwordpress wordpress \
    -N -e "SELECT VERSION();"
11.8.8-MariaDB-ubu2404

Against the patched version (>= 4.5.5.1) the time-based phase responds in milliseconds and the PoC ends with [-] No se detecto retardo (objetivo posiblemente parcheado >= 4.5.5.1).


Technical Analysis

Complete detail, with code snippets and exact lines, in docs/analisis-tecnico.md. Key points:

  • Sink: gmw_get_locations_within_boundaries_sql() interpolates {$sw[0]}, {$sw[1]}, {$ne[0]}, {$ne[1]} directly into the WHERE (all four points are injectable).
  • Source: gmw_get_form_values() processes the entire query string with parse_str() without an allowlist.
  • Exploit restriction: the payload cannot contain commas because PHP does explode(',', $southwest). The PoC uses CASE WHEN a THEN b ELSE c END instead of IF(a,b,c) and SUBSTRING(x FROM n FOR 1) instead of SUBSTRING(x,n,1).
  • Boolean oracle: the map's embedded JSON exposes "total_results":N; the exploit calibrates the length range (-10..1) so the seed row survives when the condition is true.
  • Techniques: time-based and boolean-based verified; UNION-based theoretical (the wp_posts.* columns plus the gmw fields must be aligned); error-based impractical (wpdb silences errors).
  • Discarded AJAX endpoints: the plugin's three wp_ajax_nopriv_* handlers either do not execute SQL (free version) or are protected by a nonce. The CVE vector in the free version is the form GET.

The Official Patch (4.5.5.1)

Complete real diff in docs/diff-parche-4.5.5.1-gmw-functions.php.diff. Between 4.5.5 and 4.5.5.1 only three files differ (geo-my-wp.php for the version, readme.txt for the changelog, and includes/gmw-functions.php):

  1. New validator function gmw_parse_latlng_boundary(): requires exactly 2 finite numeric parts with |lat| <= 90 and |lng| <= 180.
  2. gmw_get_form_values() discards non-validating values with unset().
  3. The sink is rewritten with $wpdb->prepare() and %f placeholders.

Current plugin version: 4.5.5.3 (July 2026), patched.


Mitigation

  1. Update to GEO my WordPress >= 4.5.5.1 (main measure).
  2. If it cannot be updated immediately: WAF rule blocking non-numeric values in swlatlng/nelatlng, or virtual patching (Patchstack and similar).
  3. Review whether public [gmw] forms need map-boundary search.
  4. Monitor accesses with abnormal swlatlng/nelatlng patterns in the logs.
  5. If the site was exposed: rotate secrets and reconsider wp_users hashes — the injection allows reading them.

Credits

  • Discovery: researcher alvarodh5 (reported on April 10, 2026, published on June 15, 2026 via Patchstack).
  • Patchstack entry
  • NVD record for CVE-2026-52715
  • GEO my WordPress on wordpress.org

License

MIT

Download Tool