Emblem GitLab, опутанный цифровыми щупальцами, на фоне потока данных — концептуальное изображение уязвимости удаленного выполнения кода

Опубликован PoC-эксплойт GitLab RCE для авторизованных пользователей

Исследователь в области кибербезопасности Yuhang Wang из компании depthfirst опубликовал действующий proof-of-concept (PoC) эксплойт, нацеленный на self-managed версию GitLab 18.11.3. Эксплойт позволяет авторизованному пользователю с минимальными привилегиями выполнять произвольные команды с правами системного пользователя git.

Атака реализуется через коммит двух специально подготовленных файлов Jupyter Notebook и последующий запрос на сравнение их различий (diff). При этом злоумышленнику не требуются права администратора, доступ к раннерам непрерывной интеграции (CI), взаимодействие с другими пользователями или доступ к чужим проектам.

Масштаб угрозы и подверженные версии

Уязвимость затрагивает широкий диапазон релизов GitLab Community Edition (CE) и Enterprise Edition (EE): с 15.2.0 по 18.10.7, с 18.11.0 по 18.11.4, а также с 19.0.0 по 19.0.1. Проблема присутствует на всех уровнях лицензирования — Free, Premium и Ultimate.

Корень проблемы скрывается не в самом GitLab, а в библиотеке Oj — высокопроизводительном JSON-парсере для Ruby, интенсивно использующем нативный C-код. Уязвимые версии gem-пакета Oj: с 3.13.0 по 3.17.1. Первый выпуск с полным исправлением — 3.17.3.

GitLab.com был пропатчен 10 июня, клиентам Dedicated не требуется предпринимать каких-либо действий. Однако операторам self-managed инсталляций настоятельно рекомендуется перейти на исправленные релизы:

  • 18.10.8
  • 18.11.5
  • 19.0.2

Пользователям Helm и Operator следует проверять версию GitLab внутри образа Webservice, а не ориентироваться исключительно на версию чарта или оператора.

Технические детали эксплуатации

Механизм атаки основан на взаимодействии двух багов в парсере Oj. Рендерер Jupyter Notebook в GitLab передает содержимое .ipynb-файлов из репозитория напрямую в метод Oj::Parser.usual.parse, выполняющийся внутри долгоживущего воркера Puma. Это направляет контролируемые атакующим данные в состояние нативного парсера внутри процесса приложения.

В техническом анализе depthfirst показано, что одна ошибка позволяет контролировать указатель на callback-функцию, а вторая раскрывает адрес кучи, необходимый для сужения пространства перебора при обходе ASLR (рандомизации адресного пространства).

Oj хранит состояние вложенности в фиксированном стеке размером 1024 байта, никогда не проверяя превышение глубины. Глубоко вложенные массивы могут записывать байты 0x01 в смежные области состояния парсера. Эксплойт повреждает указатель buf.head, заставляя Oj передать поддельный внутренний указатель в функцию realloc(). Позднее аллокация Ruby Array в jemalloc возвращает тот же регион памяти размером 3584 байта и перезаписывает p->start.

Далее Oj выделяет область под ключ объекта размером 65565 байт, усекает длину до 29 в знаковом 16-битном поле и возвращает 29 байт, содержащих живой указатель на выделенную область. GitLab передаёт этот указатель в визуализированный diff блокнота, предоставляя эксплойту необходимую утечку адреса.

На профилированной инсталляции GitLab 18.11.3 с двумя воркерами поиск обычно занимал от пяти до десяти минут. Исследователи оценивают время атаки в наихудшем сценарии в один-два часа. Два лексикографически упорядоченных notebook-файла в одном запросе diffs_stream удерживают обе стадии внутри одного воркера Puma, повторно использующего общий для процесса парсер Oj.

Первый файл повреждает callback и вызывает ошибку, которую GitLab перехватывает перед продолжением diff. Следующий вызов парсинга вызывает перезаписанный указатель и достигает system() через специфичную для сборки цепочку гаджетов.

Публичная демонстрация упаковывает всю цепочку в локальной лабораторной среде GitLab 18.11.3 x86-64 и заставляет воркер Puma выполнить обратное подключение с правами git.

Хронология исправления и раскрытия

Depthfirst сообщила об ошибках в Oj 21 мая, мейнтейнер смержил исправления 27 мая. Релиз Oj 3.17.3 состоялся 4 июня. Отчёт об уязвимости в GitLab исследователи отправили 5 июня; по словам depthfirst, GitLab подтвердил проблему 8 июня. Исправленные версии GitLab вышли 10 июня, отчёт был закрыт 17 июля.

По состоянию на 24 июля depthfirst не располагала данными об использовании уязвимости в реальных атаках. Ни в отчёте depthfirst, ни в примечаниях к релизу GitLab от 10 июня не указаны идентификаторы CVE и оценки CVSS для двух цепочечных багов. Обе стороны не предоставили временных мер обхода — единственной рекомендацией для self-managed операторов остаётся немедленное обновление.

Издание The Hacker News направило запросы в GitLab о статусе CVE, классификации и свидетельствах эксплуатации, а также в depthfirst о переносимости эксплойта и возможных временных смягчающих мерах. Ответы на момент публикации ожидаются.

Стоит отметить, что в том же аудите depthfirst обнаружила ещё девять CVE в других частях библиотеки Oj.

Читайте также: Как компьютерные вирусы проникают в корпоративные системы

Источник: The Hacker News

Похожие записи