Skip to content
KitploitKITPLOIT
FerramentasExploitsBlog
Log in
Enviar
FerramentasExploitsBlog
Enviar

Ferramentas de Hacking, PenTest e Cibersegurança para o seu Arsenal de Segurança!

Kitploit é um diretório de ferramentas de hacking, cibersegurança e pentesting. Descubra as últimas atualizações de projetos para encontrar vulnerabilidades, analisar sistemas, automatizar testes e fortalecer sua segurança.

FeedsContatoPrivacidade© 2026 Kitploit

Diretório de Ferramentas

Categorias

Ver todas as categorias
Loading categories
cve-2026-47627 — Prova de conceito de exploit para CVE-2026-47627, uma vulnerabilidade de path traversal no NVIDIA Triton Inference Server que leva à escrita arbitrária de arquivos via Zip-Slip. Inclui análise detalhada, ambiente de laboratório e scripts de exploit com um clique. | Kitploit
Ferramentas/GitHubGitHub/anekazek/cve-2026-47627
Análise de VulnerabilidadesExploraçãoExploração de Aplicações WebTestes de PenetraçãoAprendizado e EducaçãoLabs e Prática
GitHubanekazek/cve-2026-47627

cve-2026-47627

Prova de conceito de exploit para CVE-2026-47627, uma vulnerabilidade de path traversal no NVIDIA Triton Inference Server que leva à escrita arbitrária de arquivos via Zip-Slip. Inclui análise detalhada, ambiente de laboratório e scripts de exploit com um clique.

Ver Repositório
322há 1 mêsAinda não revisado

Mais Populares

Ver todos →

Descubra as ferramentas mais usadas pela nossa comunidade.

Explore todas as ferramentas

Navegue pela nossa coleção de ferramentas

Ver todas as ferramentas →
Compartilhar

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

Writeup completo dos resultados da pesquisa & PoC neste repositório (imagem nvcr.io/nvidia/tritonserver:26.05-py3 / server v2.69.0). Repositório configurado para sempre explicit para que o PoC funcione sem restart via gRPC.


Índice

  1. Resumo do CVE
  2. Ambiente de Laboratório
  3. Anatomia da Vulnerabilidade
  4. Análise da Causa Raiz (Diff 26.05 → 26.06)
  5. Caminhos de Exploração: Qual Realmente Atinge?
  6. PoC Principal: Zip-Slip via EXECUTION_ENV_PATH
  7. Como Executar o PoC (One-Click)
  8. Evidência de Traversal (Não é 500 Falso)
  9. Impacto de DoS
  10. Mitigações
  11. Estrutura do Repositório (Após Limpeza)
  12. Referências & Linha do Tempo

1. Resumo do CVE

CampoValor
CVECVE-2026-47627
CNA[email protected]
Publicação2026-08-18 (NVD Aguardando Análise)
BoletimNV 5865 → https://github.com/NVIDIA/product-security/tree/main/2026/5865
CVSS 3.19.8 CRÍTICO AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
CWECWE-22 Path Traversal
Afetado0.0-26.05 (server v2.69.0 / core r26.05)
Corrigido26.06 (server v2.70.0 / core r26.06)
ImpactoDoS (descrição da CNA) — esta pesquisa comprova escrita de arquivo fora de /models via Zip-Slip, que pode ser expandida para DoS/exaustão de recursos
CréditoMartin Brodeur

Nota honesta: A descrição da CNA é apenas path traversal → DoS sem detalhes. Este writeup reconstrói a localização do bug via diff r26.05..r26.06 e testes diretos no container 26.05-py3.


2. Ambiente de Laboratório

Imagem: nvcr.io/nvidia/tritonserver:26.05-py3 (TRITON_VERSION 2.69.0)

Compose sempre explicit (já corrigido neste repositório):

# 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 também já estão explicit.

Modo Triton:

  • NONE (padrão upstream) → carrega uma vez na inicialização, POST /v2/repository/models/.../load → 503, precisa de restart para carregar novo modelo.
  • POLL → verifica o repositório a cada segundo, carrega automaticamente, ainda bloqueia load explícito.
  • EXPLICIT (este repositório) → não verifica, mas abre gRPC load_model / POST /load → PoC sem restart via gRPC.

Portas: | 8000 | HTTP REST | v2/health, v2/models, v2/repository | | 8001 | gRPC | RepositoryModelLoad, ModelInfer | | 8002 | Métricas | Prometheus |

Modelo inicial:

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

Quickstart:

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

3. Anatomia da Vulnerabilidade

User input (model_name / tar entry) ──► join(parent, child) ──► canonicalize ──► cek "child di dalam parent?" ──► buka file
         │                                    │                     │                         │                     │
         └──► "../tmp/pwn"               /models + "/../tmp/pwn" = /models/../tmp/pwn → /tmp/pwn    rfind vs find + '/' check    FileExists / extract
  • Se join sem canonicalize ou verificação rfind(parent,0)==0 incorreta (correspondência parcial /models vs /models_evil), então ../ pode escapar.
  • DoS ocorre se o arquivo atravessado for um FIFO, /dev/zero, /proc/self/mem, ou um tar contendo ../../ que sobrescreve arquivos do sistema → hang / OOM / crash.

Três perguntas de pesquisa (do relatório inicial):

  1. Onde o usuário controla o caminho? → model_name no gRPC RepositoryModelLoad, EXECUTION_ENV_PATH tar entry, override file:, TRITON_BATCH_STRATEGY_PATH.
  2. Como o caminho é usado? → posixpath.join(repo, model_name) / temp_dir + "/" + file_name + IsChildPathEscapingParentPath.
  3. Qual o impacto? → DoS via exaustão de recursos / hang. Neste repositório é comprovada escrita de arquivo em /tmp/poc_marker.

4. Análise da Causa Raiz (Diff 26.05 → 26.06)

Repositório core (r26.05..r26.06):

  1. src/filesystem/api.cc:407 IsChildPathEscapingParentPath — correção dcb315d + 72f3d9b:

    // VULNERÁVEL (r26.05):
    absolute_child.rfind(absolute_parent,0) != 0
    // → bug de correspondência parcial: prefixo "/models" de "/models_evil/file" considerado interno
    
    // CORRIGIDO (r26.06):
    canonical_child.find(canonical_parent,0)==0 &&
    ((child.size() > parent.size() && child[parent.size()]=='/') || child.size()==parent.size())
    // → deve ter '/' após o prefixo, "/models_evil" agora corretamente fora
    

    Usado em src/backend_model.cc:196 (TRITON_BATCH_STRATEGY_PATH) e src/model_repository_manager/model_repository_manager.cc:162 (file:).

  2. src/model_repository_manager/model_repository_manager.cc:62 ValidateModelName — core#472/#481 (março de 2026, já em 26.05 mas reforçado em 26.06):

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

    Isso faz gRPC load_model('../tmp/pwn') → 400 INVALID_ARGUMENT em 26.05 (já bloqueado). Mas %2f (/ codificado) passa porque não é / literal → 500 poll literal.

  3. python_be.cc:292 EXECUTION_ENV_PATH — e520f8c7 teste zipslip_test.py: Tar extraído sem verificação de .. / caminho absoluto. Entry ../../poc_marker de /models/poc_exploit/malicious_env.tar.gz é extraído para /tmp/poc_marker (fora do diretório do modelo). Correção em 26.06: usa ARCHIVE_EXTRACT_SECURE_NODOTDOT|NOABSOLUTEPATHS + verificação IsChildPathEscapingParentPath.

Repositório server (r26.05..r26.06): apenas sagemaker_server.cc:1027 (verificação RE2::FullMatch) + http_server.cc:2440 (atoi→stoi), não é o caminho deste CVE.

Conclusão: O caminho model_name via HTTP/gRPC já estava bloqueado em 26.05 pelo ValidateModelName, mas o Zip-Slip do tar não — é isso que o PoC deste repositório explora.


5. Caminhos de Exploração: Qual Realmente Atinge?

VetorPayloadResultado 26.05Atinge?
HTTP raw ../POST /v2/repository/models/../tmp/pwn/load404 (normalização de rota)❌
HTTP codificado ..%2fPOST /v2/repository/models/..%2ftmp%2fpwn/load500 literal, poll /models/..%2ftmp%2fpwn não existe❌ (500 falso, não é traversal)
gRPC raw ../tmp/pwnload_model('../tmp/pwn')400 INVALID_ARGUMENT❌ (já bloqueado)
gRPC codificado ..%2fload_model('..%2ftmp%2fpwn')500 poll literal❌
Override file: ../models_evilfile:../models_evil/pwn400/500 dependendo da correspondência parcial⚠️ (depende do bug IsChildPathEscapingParentPath, mas já bloqueado pelo ValidateModelName para model_name)
EXECUTION_ENV_PATH tar ../../poc_markermalicious_env.tar.gz entry ../../poc_marker200 + arquivo em /tmp/poc_marker✅ VULNERÁVEL

A analogia 500 vs 400 no writeup antigo estava errada: 500 = arquivo não existe (porta não existe), 400 = rejeitado pela validação (porta trancada). Nenhum dos dois entra. Apenas 200 + arquivo em /tmp é evidência.


6. PoC Principal: Zip-Slip via EXECUTION_ENV_PATH

Baixar ferramenta