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
gortex-PoC — PoC — seguir link simbólico para divulgação de conteúdo fora do repositório via search_text no Gortex (GHSA-6vhf-4wcm-2r83, CVE-2026-87003, CVSS 5.5). | Kitploit
Ferramentas/GitHubGitHub/squeeze440/gortex-poc
Análise EstáticaAnálise de VulnerabilidadesAnálise de CódigoExploraçãoColeta de InformaçõesSegurança WebPapers e Pesquisa
GitHubsqueeze440/gortex-poc

gortex-PoC

PoC — seguir link simbólico para divulgação de conteúdo fora do repositório via search_text no Gortex (GHSA-6vhf-4wcm-2r83, CVE-2026-87003, CVSS 5.5).

Ver Repositório
27há 20 diasAinda 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

Seguimento de Symlink na Caminhada de Arquivos do Indexador → Divulgação de Conteúdo Fora do Repositório via search_text

Status do CVE: solicitado, aguardando atribuição. Esta descoberta é publicada como GHSA-6vhf-4wcm-2r83. Após a atribuição do CVE, este repositório é renomeado CVE-YYYY-NNNNN-gortex-PoC e este banner é substituído pelo link do CVE.

PesquisadorDostxodjayev Abdullox (@squeeze440)
AvisoGHSA-6vhf-4wcm-2r83
CVSS 3.15.5 (Médio)
FraquezaCWE-59, CWE-200

Seguimento de Symlink na Caminhada de Arquivos do Indexador → Divulgação de Conteúdo Fora do Repositório via search_text

Resumo

Uma falha de resolução inadequada de links (CWE-59) no indexador de repositório do gortex permite que uma entrada de arquivo com symlink apontando para fora da raiz do repositório indexado seja silenciosamente percorrida, indexada em conteúdo e posteriormente servida literalmente — inclusive para um alvo totalmente fora da raiz — pelo sink de releitura ao vivo da ferramenta MCP search_text, que nunca aplica a verificação de confinamento guardSymlinkWithinRepo do próprio projeto.

Produto

zzet/gortex — https://github.com/zzet/gortex

Versão Testada

Commit b5a63e25c0719c8ce935e59abf85618e2b4b1e64 (git describe: v0.62.0-35-gb5a63e25), o HEAD do repositório no momento da auditoria. Confirmado ainda presente na última versão marcada v0.62.0, ou seja, após a correção do não relacionado GHSA-w42c-h7hr-f67p (v0.55.0) ter sido aplicada.

CVSS v3.1 Estimado

CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:N/A:N — 5.5 (Médio)

  • AV:L — corresponde ao próprio precedente de pontuação deste projeto para sua superfície MCP (GHSA-w42c-h7hr-f67p também usou AV:L): a implantação padrão é um daemon MCP local acessado via stdio pelo processo do agente no mesmo host; AV:N só se aplicaria ao modo opt-in --http-addr.
  • UI:R — requer que o cliente MCP (um agente LLM, ou um humano via gortex call) emita uma chamada search_text / search_text regexp:true. Um literal amplo (por exemplo, um único caractere comum) ou uma regex correspondente (.) contra um repositório indexado contendo o symlink plantado é suficiente para despejar o arquivo alvo — sem necessidade de conhecimento secreto de seu conteúdo — então é uma barra baixa, mas é uma ação distinta da mera indexação.
  • C:H — divulgação de conteúdo de arquivo arbitrário, sem limites pelas fronteiras do repositório, de qualquer coisa que o usuário do SO do daemon possa ler (chaves SSH, arquivos de credenciais de nuvem, repositórios de inquilinos irmãos em um daemon multi-repo, etc.), retornado literalmente na resposta da ferramenta.
  • I:N / A:N — este é um bug puramente de caminho de leitura; nada é escrito ou tornado indisponível.

Detalhes

Causa raiz 1 — a caminhada do indexador nunca verifica entradas de arquivo com symlink

internal/indexer/indexer.go:2549-2604, a caminhada primária de admissão de corpus:

err = filepath.WalkDir(absRoot, func(path string, d os.DirEntry, err error) error {
    if err != nil { return nil }
    if d.IsDir() {
        if idx.shouldPruneDir(path, absRoot) { return filepath.SkipDir }
        return nil
    }
    lang, ok := idx.effectiveLanguage(path, nil)   // detects by extension; symlink name is enough
    if !ok { return nil }
    if idx.shouldExclude(path, absRoot, false) { return nil }
    info, statErr := d.Info()                      // Lstat'd DirEntry.Info() — no ModeSymlink check
    ...
    files = append(files, walkedFile{path: path, lang: lang, size: info.Size(), mtimeNano: info.ModTime().UnixNano()})
    return nil
})

filepath.WalkDir usa semântica de Lstat, então um diretório com symlink é naturalmente protegido — d.IsDir() é falso para ele e nunca é recursado. Uma entrada de arquivo com symlink não recebe proteção equivalente: nada aqui (nem em shouldExclude/shouldPruneDir, internal/indexer/indexer.go:5724-5813, que apenas correspondem a padrões de caminho no estilo gitignore) chama d.Type()&os.ModeSymlink, os.Lstat ou filepath.EvalSymlinks na entrada de arquivo antes de enfileirá-la. Um arquivo chamado, por exemplo, pwn.go cujo alvo é /etc/passwd, ~/.ssh/id_rsa ou um repositório de inquilino irmão é admitido puramente porque seu nome corresponde a uma extensão registrada (effectiveLanguage, internal/parser DetectLanguageContent, baseado em caminho). Essa lista exata de arquivos percorridos torna-se idx.fileMtimes (internal/indexer/indexer.go:3760: idx.fileMtimes[idx.relKey(f.path)] = f.mtimeNano).

Causa raiz 2 — o sink search_text relê arquivos ao vivo sem guarda de confinamento

internal/indexer/grep.go:17-64 (GrepText / warmTrigramSearcher) constrói o buscador de trigramas diretamente a partir das chaves de idx.fileMtimes:

rels := ... // from idx.fileMtimes, i.e. includes the symlinked file's rel path
idx.trigramSearcher = trigram.Build(root, rels)

internal/search/trigram/searcher.go:32-48 (Build) e :55-86/:102-176 (Grep/GrepRegexp) então fazem:

content, err := os.ReadFile(filepath.Join(root, filepath.FromSlash(rel)))  // Build — follows symlink
...
f, err := os.Open(filepath.Join(s.root, filepath.FromSlash(rel)))          // Grep/GrepRegexp — follows symlink

os.ReadFile/os.Open seguem symlinks por padrão (sem O_NOFOLLOW). Nem essas funções, nem internal/mcp/tools_search_text.go:35-126 (handleSearchText, o handler MCP que chama s.indexer.GrepText/GrepRegexp), jamais chamam resolveFilePath ou guardSymlinkWithinRepo. Essas duas funções de confinamento existem e estão corretamente conectadas a todos os outros caminhos de serviço de conteúdo — internal/mcp/tools_fileops.go (read_file, write_file/edit_file a partir da correção v0.55.0), internal/mcp/tools_coding.go:919 (get_symbol_source), internal/mcp/tools_lsp.go:264, internal/mcp/tools_export.go:95 — mas o caminho de grep de trigramas do search_text é um sink separado que nunca recebeu a mesma guarda. grep -rn guardSymlinkWithinRepo em toda a árvore confirma zero referências em tools_search_text.go, grep.go ou trigram/searcher.go.

Verificação de risco de duplicata / distinção

Isto é genuinamente distinto de GHSA-w42c-h7hr-f67p:

  • Aquele aviso: caminho de escrita, resolveFilePath isentando caminhos absolutos + write_file/edit_file/move_inline nunca chamando guardSymlinkWithinRepo (corrigido em v0.55.0).
  • Esta descoberta: caminho de leitura, a própria caminhada de descoberta do indexador (não qualquer handler MCP) admite um arquivo com symlink sem verificação de Lstat, e uma ferramenta MCP diferente (search_text, não read_file/get_symbol_source) serve seu conteúdo através de um sink (internal/search/trigram) que independentemente nunca chama guardSymlinkWithinRepo. A correção do caminho de escrita não tocou em nenhum desses dois locais. Isto corresponde ao padrão de ferramenta irmã já confirmado em ozgurcd/gograph (GHSA-6h6w-vhgr-2hp6) e vitali87/code-graph-rag (GHSA-85gg-2gfq-q95m): uma caminhada de descoberta de arquivos sem proteção de symlink, emparelhada com um sink de serviço de conteúdo que independentemente carece de uma guarda de confinamento.

Prova de Conceito

Rastreamento estático (referências arquivo:linha acima) está completo e é reproduzível por inspeção. A verificação dinâmica foi tentada e está genuinamente bloqueada por uma lacuna de toolchain neste sandbox, documentada honestamente em vez de mascarada:

Baixar ferramenta