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-14361 — O helper writeToFile do Consul Template abria diretamente um destino fornecido pelo operador e seguia componentes de caminho com link, permitindo que a saída renderizada escapasse do diretório pretendido e sobrescrevesse um arquivo pré-existente. | Kitploit
Ferramentas/GitHubGitHub/0xmrma/cve-2026-14361
Análise de VulnerabilidadesAnálise de CódigoExploraçãoAprendizado e Educação
GitHub0xmrma/cve-2026-14361

CVE-2026-14361

O helper writeToFile do Consul Template abria diretamente um destino fornecido pelo operador e seguia componentes de caminho com link, permitindo que a saída renderizada escapasse do diretório pretendido e sobrescrevesse um arquivo pré-existente.

Ver Repositório
2há 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-14361

O helper writeToFile do Consul Template abria diretamente um destino fornecido pelo operador e seguia componentes de caminho vinculados, permitindo que a saída renderizada escapasse do diretório pretendido e sobrescrevesse um arquivo preexistente.

Introdução

Encontrei este problema ao revisar o HashiCorp Consul Template, com uma pergunta direta de segurança de filesystem em mente:

Se writeToFile receber um caminho que parece estar dentro do diretório pretendido, ele verifica onde o filesystem realmente gravará os dados?

Neste caso, a resposta foi não.

O helper de template writeToFile abria o caminho final fornecido pelo usuário diretamente por meio de os.Create() ou os.OpenFile().

Essas operações seguiam links simbólicos, junções de diretório e redirecionamentos equivalentes de filesystem já presentes no caminho de destino.

Isso significava que a string de caminho podia permanecer sob a raiz pretendida pelo operador enquanto a gravação real ocorria em outro lugar.

Na minha prova de conceito controlada, um diretório pai vinculado redirecionou a saída renderizada para fora da árvore pretendida e fez com que um arquivo de destino preexistente fosse sobrescrito.

Esse problema tornou-se CVE-2026-14361.

Boletim da HashiCorp:

HCSEC-2026-20

Boletim da IBM:
Boletim de segurança CVE-2026-14361

CVE:
CVE-2026-14361

Corrigido em:
0.42.1

photo0


Cadeia de Ataque

o destino fornecido pelo operador parece estar dentro da raiz pretendida -> o atacante pré-posiciona o componente pai ou final vinculado -> writeToFile abre o caminho diretamente -> o filesystem resolve a gravação fora do diretório pretendido -> o segredo renderizado é redirecionado -> o destino preexistente pode ser sobrescrito


O Que o writeToFile Faz

O Consul Template renderiza dados de fontes como Consul e Vault.

O helper writeToFile permite que um template grave conteúdo selecionado em um arquivo local separado, aplicando um proprietário, grupo e modo de permissão solicitados.

A documentação da HashiCorp demonstra especificamente o helper com material de PKI:

root@kitploit:~
private key -> writeToFile /my/path/to/cert.key
certificate authority -> writeToFile /my/path/to/cert.pem
certificate -> append to /my/path/to/cert.pem

Isso faz dele mais do que um helper de saída comum.

O conteúdo que cruza esse limite pode incluir:

  • chaves privadas
  • certificados
  • segredos obtidos do Vault
  • valores de configuração
  • credenciais de serviço

A pergunta importante não era se o writeToFile poderia criar um nome de arquivo solicitado.

A pergunta real era:

O processo grava no local de filesystem pretendido pelo operador, ou meramente em qualquer objeto para o qual o caminho resolva no momento da abertura?

Em versões vulneráveis, ele confiava na segunda opção.


Por Que Esta Superfície Merecia Atenção

Helpers de gravação são superfícies de segurança de alto valor porque fazem a transição de dados de aplicação para mutação do filesystem.

As falhas interessantes geralmente não são a travessia clássica de ../.

São falhas de resolução:

  • a string parece segura
  • a árvore de diretórios parece controlada pelo operador
  • um componente vinculado altera o destino real
  • a chamada de abertura segue esse redirecionamento automaticamente

Isso é especialmente importante quando o processo executa com mais privilégios de filesystem do que o atacante.

Um atacante local com baixos privilégios pode não conseguir sobrescrever diretamente um arquivo sensível.

Mas se ele puder influenciar um componente de caminho sob um diretório de gravação pretendido, um processo do Consul Template com mais privilégios pode realizar a gravação por ele.

Essa foi a fronteira na qual me concentrei.


A Fronteira na Qual Me Concentrei

Não abordei isso como uma revisão genérica de travessia de caminho.

O caminho fornecido não precisava de segmentos ...

Ele podia permanecer lexicalmente dentro da raiz pretendida durante todo o tempo.

A pergunta mais forte era:

Os componentes de destino vinculados são rejeitados antes que o conteúdo sensível seja gravado?

Essa pergunta importa para ambos os casos:

  • um nome de arquivo final vinculado
  • um componente de diretório vinculado que redireciona todo o caminho restante

O segundo caso é especialmente útil porque logs e configuração ainda mostram um caminho de aparência inofensiva sob o diretório esperado.

O filesystem o resolve em outro lugar.


Causa Raiz

A causa raiz era a criação direta de arquivos baseada em caminho, sem validação ciente de links.

Na revisão testada, writeToFile() selecionava um de dois caminhos de abertura.

O modo de anexação usava:

root@kitploit:~
f, err = os.OpenFile(
    path,
    os.O_APPEND|os.O_WRONLY|os.O_CREATE,
    perm,
)

O modo de gravação normal usava:

root@kitploit:~
dirPath := filepath.Dir(path)

if _, err := os.Stat(dirPath); err != nil {
    err := os.MkdirAll(dirPath, os.ModePerm)
    if err != nil {
        return "", err
    }
}

f, err = os.Create(path)

Nenhum dos dois caminhos rejeitava componentes de destino vinculados antes que o arquivo fosse aberto.

Isso importa porque:

  • os.Create(path) segue redirecionamentos de filesystem existentes e trunca o arquivo resolvido
  • os.OpenFile(path, ...) segue componentes de caminho vinculados durante o modo de anexação
  • um diretório vinculado altera onde o nome de arquivo final é resolvido
  • um componente final vinculado pode redirecionar a abertura para um arquivo existente diferente

A mesma suposição baseada em caminho continuava após a gravação.

Proprietário e permissões eram aplicados usando o caminho novamente:

root@kitploit:~
err = os.Chown(path, uid, gid)
err = os.Chmod(path, perm)

Isso significava que as operações de metadados também estavam vinculadas a um nome de caminho mutável, em vez do descritor de arquivo já aberto.

Por que isso é explorável

Porque o atacante pode preparar o redirecionamento antes que o writeToFile execute.

Nenhuma condição de corrida (race) probabilística é necessária para o ataque básico.

A sequência é direta:

  • o operador configura um destino sob uma raiz esperada
  • o atacante obtém acesso local suficiente para criar ou substituir um componente vinculado abaixo desse local de gravação
  • a string de caminho ainda parece permanecer sob a raiz pretendida
  • writeToFile o abre diretamente
  • o sistema operacional segue o link ou a junção
  • a saída renderizada chega ao destino resolvido
  • se esse destino já existir, o modo de criação normal o trunca e sobrescreve

Essa é a vulnerabilidade por completo.


O Que Torna Isso um Problema de Segurança, e Não Apenas Comportamento Normal de Symlink

É verdade que sistemas operacionais normalmente seguem symlinks ao abrir arquivos por caminho.

Isso não torna esse comportamento de aplicação seguro.

A pergunta de segurança não é:

"O Go se comportou como documentado?"

A pergunta real é:

Um helper que grava dados sensíveis renderizados verificou se o destino resolvido correspondia ao local pretendido pelo operador?

Em versões vulneráveis, não verificou.

Essa distinção importa porque o Consul Template pode executar:

  • como um serviço de longa duração
  • com acesso a segredos derivados do Vault
  • sob uma conta com privilégios elevados
  • com acesso de gravação que o atacante local não possui diretamente

Seguir redirecionamentos de filesystem posicionados pelo atacante nesse contexto cria um problema real de privilégio e de fronteira de confiança.


Prova de Conceito

Construí um reprodutor independente em torno do comportamento exato do writeToFile no commit testado.

A configuração controlada usava:

  • uma raiz de saída pretendida
  • um diretório externo fora dessa raiz
  • um componente pai vinculado abaixo da raiz pretendida
  • um arquivo de destino preexistente no diretório redirecionado
  • conteúdo secreto controlado passado para o writeToFile

O fluxo de reprodução era:

  1. Criar a raiz de saída pretendida.
  2. Criar um diretório de destino externo separado.
  3. Colocar um arquivo de destino preexistente no diretório externo.
  4. Criar um diretório pai vinculado sob a raiz pretendida que resolva para o diretório externo.
  5. Construir o caminho de destino final usando o diretório pai vinculado, mantendo a string de caminho sob a raiz pretendida.
  6. Invocar o caminho de gravação vulnerável com conteúdo secreto controlado.
  7. Resolver e inspecionar o destino real.
  8. Comparar os bytes do arquivo final e o SHA-256 com a entrada secreta.

O comportamento observado foi:

  • a string de destino pretendida permaneceu sob a raiz pretendida
  • o diretório pai vinculado redirecionou a gravação real para fora dessa raiz
  • writeToFile seguiu o redirecionamento
  • o destino externo preexistente foi sobrescrito
  • o arquivo externo final correspondeu exatamente à entrada secreta por SHA-256

Isso estabeleceu ambas as partes da alegação:

  • a saída podia escapar da árvore de diretórios pretendida
  • um arquivo existente no destino resolvido podia ser sobrescrito

Por Que o PoC Foi Escolhido Dessa Forma

Um symlink no componente final já demonstraria o seguimento inseguro de links.

Mas um componente pai vinculado prova um ponto operacional mais forte:

  • o nome de arquivo configurado pode parecer completamente normal
  • o caminho pode permanecer lexicalmente sob a raiz pretendida
  • o redirecionamento pode ocorrer mais acima no caminho
  • a gravação final ainda pode cair em outro lugar

O destino preexistente também importava.

Sem ele, o PoC mostraria apenas criação inesperada de arquivos.

Ao começar com um arquivo existente e verificar seu hash final, a reprodução provou diretamente o comportamento de sobrescrita.

Isso tornou o resultado mais concreto do que uma alegação baseada apenas no código-fonte.


Requisitos e Escopo de Exploração

Este problema exige influência local sobre o filesystem.

Um atacante precisa de acesso suficiente para criar ou modificar um symlink, uma junção de diretório ou um redirecionamento equivalente dentro ou abaixo do local de gravação pretendido.

O processo do Consul Template deve então gravar através desse caminho.

O impacto depende fortemente dos privilégios do processo e do conteúdo renderizado.

Os resultados práticos incluem:

  • redirecionar a saída do template para fora do diretório pretendido pelo operador
  • colocar dados sensíveis renderizados em um local legível pelo atacante
  • sobrescrever um arquivo preexistente no destino resolvido
  • aumentar o impacto quando o processo executa com privilégios elevados
  • aumentar o risco de confidencialidade quando o conteúdo contém chaves, certificados ou segredos

Isso não era uma gravação arbitrária remota não autenticada a partir de uma instalação padrão.

Mas era uma clara falha local de fronteira de confiança, com impacto significativo em implantações privilegiadas ou com filesystem compartilhado.


Severidade e Classificação

A HashiCorp classificou o problema como:

  • CWE-59: Improper Link Resolution Before File Access
  • CVSS 3.1:
root@kitploit:~
CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:H/I:N/A:N

A pontuação base publicada é:

root@kitploit:~
4.7 / Medium

Esse vetor reflete:

  • acesso de atacante local
  • baixos privilégios necessários para influenciar o caminho
  • alta complexidade de ataque
  • nenhuma interação do usuário
  • potencial alto impacto de confidencialidade quando a saída sensível renderizada é redirecionada

Os boletins oficiais também documentam explicitamente que a gravação redirecionada pode sobrescrever um arquivo preexistente.

A pontuação é moderada porque a exploração depende de condições locais de controle de caminho, não porque o efeito no filesystem seja teórico.


Versões Afetadas

O boletim da HashiCorp lista:

root@kitploit:~
Affected: consul-template up to and including 0.42.0
Fixed:    consul-template 0.42.1

A correção foi lançada na versão 0.42.1 em 8 de julho de 2026.


Análise da Correção

O patch 0.42.1 endureceu o caminho de gravação em várias camadas.

1. Rejeitar componentes de destino vinculados

O helper corrigido usa os.Lstat() para inspecionar:

  • o diretório pai imediato
  • o componente de destino final

e rejeita esses componentes quando são links.

Isso encerra os casos de redirecionamento direto pelo diretório pai e de symlink no arquivo final cobertos pelo relatório e pelos testes de regressão.

2. Usar O_NOFOLLOW na abertura final onde houver suporte

Em plataformas Unix com suporte, o destino é aberto com O_NOFOLLOW.

Isso faz a própria abertura falhar se o componente final se tornar um symlink entre a pré-verificação e a abertura.

Isso é importante porque uma pré-verificação isolada pode criar outra janela de TOCTOU.

A implementação específica de plataforma é um no-op no Windows, onde O_NOFOLLOW não está disponível pelo mesmo mecanismo.

3. Aplicar metadados através do descritor aberto

O patch substituiu as operações de proprietário e modo baseadas em caminho por operações baseadas no descritor:

root@kitploit:~
f.Chown(uid, gid)
f.Chmod(perm)

Isso vincula as alterações de metadados ao arquivo que foi realmente aberto, em vez de resolver o caminho novamente mais tarde.

4. Falhar de forma segura (fail closed) em erros inesperados de stat

O helper agora cria o diretório pai somente quando a falha de stat é genuinamente os.IsNotExist.

Outros erros, como falhas de permissão, são retornados em vez de continuar no caminho de gravação.

Cobertura de regressão

O patch adicionou testes focados para:

  • rejeição de symlink no componente final
  • rejeição de diretório pai vinculado
  • sucesso em caminho normal
  • rejeição de symlink final no modo de anexação
  • verificação de bytes confirmando que o alvo sensível permanece inalterado

Um Limite Importante da Correção

A discussão pública do patch documenta uma limitação importante com clareza.

A nova validação verifica:

  • o diretório pai imediato
  • o componente final do caminho

Ela não percorre e rejeita todos os componentes ancestrais superiores.

Os mantenedores escolheram esse limite porque o writeToFile não tem uma raiz de sandbox configurada para ancorar uma verificação completa de contenção, e sistemas operacionais comuns podem incluir links gerenciados legítimos em prefixos de caminho, como /var -> /private/var no macOS.

O_NOFOLLOW também protege o componente final, não todos os diretórios ancestrais.

Isso não altera o status da vulnerabilidade reportada nem a versão corrigida oficial.

Mas esclarece a propriedade de segurança exata entregue pelo patch:

  • os caminhos de redirecionamento reportados, via pai imediato e componente final, são rejeitados
  • as operações de metadados são vinculadas ao descritor aberto
  • o helper não alega fornecer um sandbox genérico de filesystem para todos os caminhos ancestrais

Essa distinção vale a pena preservar em um writeup técnico.


Divulgação

Reportei este problema em particular à HashiCorp Security em 21 de março de 2026, como uma segunda descoberta independente no Consul Template.

O relatório incluía:

  • análise de causa raiz no nível do código-fonte
  • uma prova de conceito independente
  • saída de execução
  • evidências do caminho pretendido e do caminho resolvido
  • comportamento do arquivo antes/depois
  • confirmação por SHA-256 de que o alvo redirecionado correspondia à entrada secreta
  • detalhes da revisão afetada

O e-mail de acompanhamento original não estava presente na fila de relatórios da equipe de segurança, provavelmente por ter sido capturado por um filtro de spam da lista de discussão.

Depois que reencaminhei o relatório completo, a HashiCorp contatou a equipe de engenharia e investigou o problema separadamente da primeira questão do Consul Template.

A HashiCorp corrigiu a vulnerabilidade em 0.42.1 e publicou o HCSEC-2026-20 em 8 de julho de 2026.

A IBM publicou um boletim de segurança correspondente para o mesmo CVE.

Ambos os boletins oficiais creditaram o relatório a:

Mohamed Abdelaal (0xmrma)


O Que Este Bug Realmente Ensina

A lição principal é simples:

uma string de caminho não é a mesma coisa que o objeto de filesystem que ela nomeia

Essa distinção importa sempre que código privilegiado grava caminhos influenciados pelo atacante.

Verificar se uma string começa com um diretório pretendido não é suficiente.

Até um caminho limpo, sem sequências de travessia, pode resolver para outro lugar através de:

  • links simbólicos
  • junções de diretório
  • redirecionamentos de montagem (mount)
  • componentes de caminho mutáveis

A operação sensível deve ser vinculada a um destino cuja identidade tenha sido validada na fronteira correta.

Este problema também reforça uma regra mais ampla:

quando você já tem um descritor de arquivo aberto, aplique operações sensíveis à segurança através desse descritor, em vez de resolver o caminho novamente

É exatamente por isso que as alterações de Chown e Chmod baseadas no descritor importam.


Pontos-Chave

  • o writeToFile é documentado para material sensível, como certificados e chaves privadas
  • versões vulneráveis abriam o destino diretamente com os.Create ou os.OpenFile
  • componentes pai e final vinculados podiam redirecionar a gravação real
  • o caminho configurado podia permanecer sob a raiz pretendida enquanto o alvo resolvido estava fora dela
  • o modo de criação normal podia truncar e sobrescrever um destino preexistente
  • Chown e Chmod baseados em caminho introduziam confiança adicional em caminhos mutáveis
  • o PoC provou o redirecionamento e a sobrescrita com comparação byte a byte exata (SHA-256)
  • a versão 0.42.1 adicionou verificações de links, O_NOFOLLOW onde houver suporte, operações de metadados baseadas no descritor e testes de regressão

Considerações Finais

Esta vulnerabilidade não era sobre travessia de ../.

A string de caminho parecia correta.

O destino no filesystem não era.

O Consul Template aceitou o caminho pretendido pelo operador, seguiu um redirecionamento posicionado pelo atacante e gravou o conteúdo renderizado em um arquivo diferente.

É por isso que isso se tornou CVE-2026-14361.

Corrigido em consul-template 0.42.1.

Baixar ferramenta