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

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

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

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

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

Категории

Все категории
Loading categories
cve-2026-47627 — Доказательство концепции эксплуатации для CVE-2026-47627 — уязвимости обхода пути (path traversal) в NVIDIA Triton Inference Server, приводящей к произвольной записи файлов через Zip-Slip. Включает подробный анализ, лабораторную среду и скрипты эксплуатации в один клик. | Kitploit
Инструменты/GitHubGitHub/anekazek/cve-2026-47627
Анализ уязвимостейЭксплуатацияЭксплуатация веб-приложенийТестирование на ПроникновениеОбучение и ОбразованиеЛаборатории и Практика
GitHubanekazek/cve-2026-47627

cve-2026-47627

Доказательство концепции эксплуатации для CVE-2026-47627 — уязвимости обхода пути (path traversal) в NVIDIA Triton Inference Server, приводящей к произвольной записи файлов через Zip-Slip. Включает подробный анализ, лабораторную среду и скрипты эксплуатации в один клик.

Репозиторий
3221 месяц назадЕщё не проверено

Популярное

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

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

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

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

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

CVE-2026-47627 — NVIDIA Triton Inference Server Path Traversal → DoS (Zip-Slip)

Полный writeup результатов исследования и PoC в этом репозитории (образ nvcr.io/nvidia/tritonserver:26.05-py3 / server v2.69.0). Репозиторий настроен на режим explicit, чтобы PoC работал без перезапуска через gRPC.


Содержание

  1. Сводка по CVE
  2. Лабораторная среда
  3. Анатомия уязвимости
  4. Анализ первопричины (Diff 26.05 → 26.06)
  5. Векторы эксплуатации: какие реально срабатывают?
  6. Основной PoC: Zip-Slip через EXECUTION_ENV_PATH
  7. Как запустить PoC (One-Click)
  8. Доказательство Traversal (не фейковый 500)
  9. Влияние DoS
  10. Меры по смягчению
  11. Структура репозитория (после очистки)
  12. Ссылки и таймлайн

1. Сводка по CVE

ПолеЗначение
CVECVE-2026-47627
CNA[email protected]
Публикация2026-08-18 (NVD Awaiting Analysis)
БюллетеньNV 5865 → https://github.com/NVIDIA/product-security/tree/main/2026/5865
CVSS 3.19.8 CRITICAL AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
CWECWE-22 Path Traversal
Затронуто0.0-26.05 (server v2.69.0 / core r26.05)
Исправлено26.06 (server v2.70.0 / core r26.06)
ВоздействиеDoS (описание CNA) — данное исследование доказывает запись файлов за пределами /models через Zip-Slip, что может быть расширено до DoS/истощения ресурсов
АвторMartin Brodeur

Честное примечание: Описание CNA содержит только path traversal → DoS без деталей. Этот writeup реконструирует местоположение бага через diff r26.05..r26.06 и непосредственное тестирование в контейнере 26.05-py3.


2. Лабораторная среда

Образ: nvcr.io/nvidia/tritonserver:26.05-py3 (TRITON_VERSION 2.69.0)

Compose всегда в режиме explicit (уже пропатчен в этом репозитории):

# docker-compose.yml:12
command: ["tritonserver", "--model-repository=/models", "--model-control-mode=explicit", "--log-verbose=0"]

run_triton.bat:10, run_triton.ps1:11, run_triton.sh:12 также в режиме explicit.

Режимы Triton:

  • NONE (по умолчанию upstream) → загрузка один раз при старте, POST /v2/repository/models/.../load → 503, требуется перезапуск для загрузки новой модели.
  • POLL → сканирование репозитория каждую секунду, автозагрузка, но явная загрузка по-прежнему блокируется.
  • EXPLICIT (этот репозиторий) → без сканирования, но открыт gRPC load_model / POST /load → PoC без перезапуска через gRPC.

Порты: | 8000 | HTTP REST | v2/health, v2/models, v2/repository | | 8001 | gRPC | RepositoryModelLoad, ModelInfer | | 8002 | Metrics | Prometheus |

Начальные модели:

model_repository/
├── echo_python/ (python backend, model.py)
│   └── 1/model.py
└── identity_onnx/ (onnxruntime, model.onnx ~1KB)

Быстрый старт:

docker compose up -d
docker compose logs -f
py scripts/client_test.py  # health + infer identity_onnx

3. Анатомия уязвимости

User input (model_name / tar entry) ──► join(parent, child) ──► canonicalize ──► проверка "child внутри parent?" ──► открытие файла
         │                                    │                     │                         │                     │
         └──► "../tmp/pwn"               /models + "/../tmp/pwn" = /models/../tmp/pwn → /tmp/pwn    rfind vs find + '/' check    FileExists / extract
  • Если join без canonicalize или проверка rfind(parent,0)==0 некорректна (частичное совпадение /models vs /models_evil), то ../ может выйти за пределы.
  • DoS возникает, если обходимый файл — это FIFO, /dev/zero, /proc/self/mem, или tar содержит ../../, перезаписывающий системные файлы → зависание / OOM / крах.

Три исследовательских вопроса (из первоначального отчёта):

  1. Где пользователь контролирует путь? → model_name в gRPC RepositoryModelLoad, EXECUTION_ENV_PATH tar entry, file: override, TRITON_BATCH_STRATEGY_PATH.
  2. Как используется путь? → posixpath.join(repo, model_name) / temp_dir + "/" + file_name + IsChildPathEscapingParentPath.
  3. Каково воздействие? → DoS через истощение ресурсов / зависание. В этом репозитории доказана запись файла в /tmp/poc_marker.

4. Анализ первопричины (Diff 26.05 → 26.06)

Репозиторий core (r26.05..r26.06):

  1. src/filesystem/api.cc:407 IsChildPathEscapingParentPath — исправление dcb315d + 72f3d9b:

    // УЯЗВИМО (r26.05):
    absolute_child.rfind(absolute_parent,0) != 0
    // → баг частичного совпадения: префикс "/models" из "/models_evil/file" считается внутренним
    
    // ИСПРАВЛЕНО (r26.06):
    canonical_child.find(canonical_parent,0)==0 &&
    ((child.size() > parent.size() && child[parent.size()]=='/') || child.size()==parent.size())
    // → после префикса должен быть '/', "/models_evil" теперь корректно считается внешним
    

    Используется в src/backend_model.cc:196 (TRITON_BATCH_STRATEGY_PATH) и src/model_repository_manager/model_repository_manager.cc:162 (file:).

  2. src/model_repository_manager/model_repository_manager.cc:62 ValidateModelName — core#472/#481 (март 2026, уже в 26.05, но ужесточено в 26.06):

    if (trimmed==".." || trimmed.find('/')!=npos) return INVALID_ARG "must not contain path traversal"
    

    Именно это заставляет gRPC load_model('../tmp/pwn') → 400 INVALID_ARGUMENT в 26.05 (уже заблокировано). Но %2f (закодированный /) проходит, так как это не литеральный / → 500 литерального опроса.

  3. python_be.cc:292 EXECUTION_ENV_PATH — e520f8c7 тест zipslip_test.py: Tar извлекается без проверки .. / абсолютных путей. Entry ../../poc_marker из /models/poc_exploit/malicious_env.tar.gz извлекается в /tmp/poc_marker (за пределами каталога модели). Исправление в 26.06: использование ARCHIVE_EXTRACT_SECURE_NODOTDOT|NOABSOLUTEPATHS + проверка IsChildPathEscapingParentPath.

Репозиторий server (r26.05..r26.06): только sagemaker_server.cc:1027 (проверка RE2::FullMatch) + http_server.cc:2440 (atoi→stoi), не относится к этому CVE.

Вывод: Путь model_name через HTTP/gRPC уже заблокирован в 26.05 функцией ValidateModelName, но Zip-Slip tar — нет; именно это эксплуатирует PoC данного репозитория.


5. Векторы эксплуатации: какие реально срабатывают?

ВекторPayloadРезультат в 26.05Срабатывает?
HTTP raw ../POST /v2/repository/models/../tmp/pwn/load404 (нормализация маршрутов)❌
HTTP encoded ..%2fPOST /v2/repository/models/..%2ftmp%2fpwn/load500 литеральный, опрос /models/..%2ftmp%2fpwn не существует❌ (фейковый 500, не traversal)
gRPC raw ../tmp/pwnload_model('../tmp/pwn')400 INVALID_ARGUMENT❌ (уже заблокировано)
gRPC encoded ..%2fload_model('..%2ftmp%2fpwn')500 литеральный опрос❌
file: override ../models_evilfile:../models_evil/pwn400/500 в зависимости от частичного совпадения⚠️ (зависит от бага IsChildPathEscapingParentPath, но уже заблокировано ValidateModelName для model_name)
EXECUTION_ENV_PATH tar ../../poc_markermalicious_env.tar.gz entry ../../poc_marker200 + файл в /tmp/poc_marker✅ УЯЗВИМО

Аналогия 500 vs 400 в старом writeup ошибочна: 500 = файл не существует (двери нет), 400 = отклонено валидацией (дверь заперта). Оба не проходят. Только 200 + файл в /tmp является доказательством.


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