Skip to content
KitploitKITPLOIT
ИнструментыБлог
Отправить
ИнструментыБлог
Отправить

Инструменты для хакинга, пентеста и кибербезопасности — ваш арсенал защиты!

Kitploit — это каталог инструментов для хакинга, кибербезопасности и пентестинга. Находите последние обновления проектов для поиска уязвимостей, анализа систем, автоматизации тестирования и усиления вашей безопасности.

··Ленты·Контакты·Конфиденциальность·© 2026 Kitploit

Каталог инструментов

Категории

Все категории
Loading categories
CVE-2024-27198 — Подробный анализ CVE-2024-27198: обход аутентификации в JetBrains TeamCity, приводящий к удаленному выполнению кода, с объяснением на уровне кода и демонстрацией эксплуатации. | Kitploit
Инструменты/GitHubGitHub/hpt-intern-task-submission/cve-2024-27198
Анализ уязвимостейЭксплуатацияЭксплуатация веб-приложенийТестирование на ПроникновениеАутентификацияОбучение и Образование
GitHubhpt-intern-task-submission/cve-2024-27198

CVE-2024-27198

Подробный анализ CVE-2024-27198: обход аутентификации в JetBrains TeamCity, приводящий к удаленному выполнению кода, с объяснением на уровне кода и демонстрацией эксплуатации.

Популярное

Смотреть все →

Откройте для себя самые используемые инструменты нашего сообщества.

Изучить все инструменты

Просмотрите нашу коллекцию инструментов

Смотреть все инструменты →
Поделиться
Репозиторий
2 лет назадЕщё не проверено

CVE-2024-27198: Обход аутентификации в Jetbrain TeamCity приводит к удаленному выполнению кода

Обзор

TeamCity — это сервер непрерывной интеграции и развертывания, который предоставляет встроенное непрерывное модульное тестирование, анализ качества кода и раннюю отчетность о проблемах сборки.

Уязвимость находится в библиотеке, которая позволяет злоумышленникам получать доступ к произвольным неаутентифицированным конечным точкам.

Анализ кода

Уязвимый код находится в библиотеке web-openapi.jar в каталоге directory to the lib.

Класс jetbrains.buildServer.controllers.BaseController отвечает за обработку запросов и ответов, но реализован некорректно. Посмотрим, как выглядит код:

root@kitploit:~
public abstract class BaseController extends AbstractController {
//////
public final ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception {  
    try {  
        ModelAndView modelAndView = this.doHandle(request, response);  
        if (modelAndView != null) {  
            if (modelAndView.getView() instanceof RedirectView) {  
                modelAndView.getModel().clear();  
            } else {  
                this.updateViewIfRequestHasJspParameter(request, modelAndView);  
            }  
        }

Основная цель метода ModelAndView — отобразить запрошенную страницу в пользовательском интерфейсе. Здесь начинается ошибка. Обратите внимание, что updateViewIfRequestHasJspParameter будет вызван, если наш запрос не перенаправляется. Чтобы найти первопричину уязвимости, необходимо изучить код глубже.

root@kitploit:~
private void updateViewIfRequestHasJspParameter(@NotNull HttpServletRequest request, @NotNull ModelAndView modelAndView) {  
    boolean isControllerRequestWithViewName = modelAndView.getViewName() != null && !request.getServletPath().endsWith(".jsp");  
    String jspFromRequest = this.getJspFromRequest(request);  
    if (isControllerRequestWithViewName && StringUtil.isNotEmpty(jspFromRequest) && !modelAndView.getViewName().equals(jspFromRequest)) {  
        modelAndView.setViewName(jspFromRequest);  
    }  
  
}

Этот метод используется для обновления имени представления объекта ModelAndView при выполнении определенных условий. isControllerRequestWithViewName будет True, если объект modelAndView имеет имя и путь в URL не заканчивается на .jsp. Например, URL, удовлетворяющий этим условиям: http://localhost:8111/random_string, а неверный — http://localhost:8111/admin/admin.html или http://localhost:8111/admin.jsp. Как обсуждалось выше, мы не должны обращаться к страницам, которые вызывают перенаправление, обычно это страницы, требующие авторизации. Затем программа присваивает переменную с именем jspFromRequest, которая вызывает метод getJspFromRequest(). Теперь перейдем к этому методу, а остальной код объясню позже. Там есть оператор if, который проверяет, что истинно, результат вызова метода не пуст, и имя объекта не должно равняться странице, к которой мы хотим обратиться через

root@kitploit:~
protected String getJspFromRequest(@NotNull HttpServletRequest request) { String  jspFromRequest  = request.getParameter("jsp"); return  jspFromRequest  == null || jspFromRequest.endsWith(".jsp") && !jspFromRequest.contains("admin/") ? jspFromRequest : null; }

Эта функция сначала получает значение параметра запроса с именем jsp. Проверка гарантирует, что jsp должен заканчиваться на .jsp и не должен содержать /admin. В сочетании с оператором if выше:

root@kitploit:~
if (isControllerRequestWithViewName && StringUtil.isNotEmpty(jspFromRequest) && !modelAndView.getViewName().equals(jspFromRequest)) {  
        modelAndView.setViewName(jspFromRequest);  
    }  

Мы получаем общую картину того, как должен выглядеть URL:

  1. Путь не должен вызывать перенаправление и не должен содержать .jsp.
  2. Параметр запроса jsp не должен равняться пути. Например, /random?jsp=/random будет недействителен.
  3. Самое главное, jsp должен заканчиваться на .jsp.

TeamCity предоставляет REST API для интеграции внешних приложений и создания скриптовых взаимодействий с сервером TeamCity. Он позволяет получать доступ к ресурсам через пути URL. Вы можете начать работу с REST API, открыв в браузере URL http://<хост сервера TeamCity>:<порт>/app/rest/server: эта страница содержит несколько указателей для изучения API.

TeamCity предлагает REST API, который позволяет нам получать доступ к конфиденциальным ресурсам, если мы можем обойти аутентификацию. В данном случае, например, мы попытаемся получить доступ к /app/rest/server.

unauthenticated_request

Как обычно, сервер перенаправит нас на /login.html, когда мы запрашиваем /app/rest/server. Давайте создадим идеальный URL для обхода этого ограничения. Во-первых, наш путь может быть любым, если он возвращает код состояния 404 или даже 200, например login.html. Затем мы используем jsp для запроса к /app/rest/server, но он должен заканчиваться на .jsp. В этой ситуации есть даже два трюка, которые мы можем использовать для обхода этой проверки. Мы можем использовать точку с запятой ; в качестве разделителя параметров: /app/rest/server;.jsp — в этом случае .jsp будет рассматриваться как второй параметр. Второй способ обхода — использовать фрагмент URI #: /app/rest/server%23.jsp. То, что находится после фрагмента URI, не будет использоваться для маршрутизации, оно используется только для навигации по странице. Обратите внимание, что символ должен быть URL-кодирован, иначе браузер сначала проигнорирует его.

unauthenticated_request_bypass.png

С помощью этой техники мы можем даже создать нового пользователя с привилегиями администратора. Документация TeamCity говорит, что мы можем создать нового пользователя через эту конечную точку /app/rest/users.

create_new_user

Перейдем в панель администратора и проверим, был ли создан новый пользователь.

confirmed

Как и ожидалось, новый пользователь с привилегиями администратора создан. С правами администратора мы можем полностью контролировать сервер. Однако мы можем пойти еще дальше, получив удаленное выполнение кода. Эта CVE уязвима для всех версий до 2023.11.4, но это RCE возможно только для версий до 2023.11. Существует недокументированная конечная точка /app/rest/debug/processes, которая позволяет пользователю с правами администратора выполнять произвольные команды. Мы отправим POST-запрос с двумя параметрами запроса в URL-адресе. Для Windows это будет ?exePath=cmd.exe&params=/c%20[наша команда], а для Linux — ?exePath=/bin/sh&params=-c%20[наша команда]. Я запускаю TeamCity на Windows, поэтому полный путь будет /app/rest/debug/processes?exePath=cmd.exe&params=/c%20whoami

failed_attempt

Сервер возвращает ошибку 403, указывающую, что в запросе отсутствует csrf token. Документация TeamCity также предоставляет нам конечную точку для получения токена: /authenticationTest.html?csrf.

После получения токена мы добавим его в заголовок запроса X-TC-CSRF-Token или в HTTP-параметр tc-csrf-token. Здесь я выбираю X-TC-CSRF-Token.

done

После предоставления csrf token мы успешно выполнили команду удаленно, получив полный контроль над сервером.

В этой CVE недостаток безопасности заключался не в проверке ввода, а в логике кода. Это приложение действительно сложное, и разработчики могут допускать ошибки. Мы также узнали новую технику обхода аутентификации. Надеюсь, вы узнали что-то полезное из этого анализа. Удачного хакинга!!!

Скачать инструмент
isControllerRequestWithViewName
getJspFromRequest()
modelAndView