Skip to content
KitploitKITPLOIT
ToolsExploitsBlog
Log in
Einreichen
ToolsExploitsBlog
Einreichen

Hacking-, PenTest- und Cybersicherheits-Tools für Ihr Sicherheitsarsenal!

Kitploit ist ein Verzeichnis von Hacking-, Cybersicherheits- und Pentesting-Tools. Entdecken Sie die neuesten Projekt-Updates, um Schwachstellen zu finden, Systeme zu analysieren, Tests zu automatisieren und Ihre Sicherheit zu stärken.

FeedsKontaktDatenschutz© 2026 Kitploit

Tool-Verzeichnis

Kategorien

Alle Kategorien anzeigen
Loading categories
gortex-PoC — PoC — Symlink-Verfolgung zur Offenlegung von Inhalten außerhalb des Repos über search_text in Gortex (GHSA-6vhf-4wcm-2r83, CVE-2026-87003, CVSS 5.5). | Kitploit
Tools/GitHubGitHub/squeeze440/gortex-poc
Statische AnalyseSchwachstellenanalyseCode-AnalyseExploitationInformationsbeschaffungWebsicherheitPapers & Forschung
GitHubsqueeze440/gortex-poc

gortex-PoC

PoC — Symlink-Verfolgung zur Offenlegung von Inhalten außerhalb des Repos über search_text in Gortex (GHSA-6vhf-4wcm-2r83, CVE-2026-87003, CVSS 5.5).

Repository anzeigen
27vor 19 TagenNoch nicht geprüft

Beliebteste

Alle anzeigen →

Entdecken Sie die meistgenutzten Tools unserer Community.

Alle Tools erkunden

Durchsuchen Sie unsere Tool-Sammlung

Alle Tools anzeigen →
Teilen

Symlink-Verfolgung im Indexer-Datei-Walk → Offenlegung von Inhalten außerhalb des Repos über search_text

CVE-Status: beantragt, Zuweisung ausstehend. Dieser Befund wird als GHSA-6vhf-4wcm-2r83 veröffentlicht. Bei CVE-Zuweisung wird dieses Repository in CVE-YYYY-NNNNN-gortex-PoC umbenannt und dieses Banner durch den CVE-Link ersetzt.

ForscherDostxodjayev Abdullox (@squeeze440)
AdvisoryGHSA-6vhf-4wcm-2r83
CVSS 3.15.5 (Mittel)
SchwächeCWE-59, CWE-200

Symlink-Verfolgung im Indexer-Datei-Walk → Offenlegung von Inhalten außerhalb des Repos über search_text

Zusammenfassung

Ein Fehler bei der unsachgemäßen Link-Auflösung (CWE-59) im Repository-Indexer von gortex ermöglicht es, dass ein symlinkter Datei-Eintrag, der auf ein Ziel außerhalb des indizierten Repository-Roots zeigt, stillschweigend durchlaufen, in den Index aufgenommen und später wörtlich ausgeliefert wird — einschließlich an ein vollständig außerhalb des Roots liegendes Ziel — durch die Live-Re-Read-Senke des MCP-Tools search_text, die niemals die eigene guardSymlinkWithinRepo-Eingrenzungsprüfung des Projekts anwendet.

Produkt

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

Getestete Version

Commit b5a63e25c0719c8ce935e59abf85618e2b4b1e64 (git describe: v0.62.0-35-gb5a63e25), der Repository-HEAD zum Zeitpunkt des Audits. Bestätigt weiterhin vorhanden im neuesten getaggten Release v0.62.0, d. h. nachdem der Fix für das unabhängige GHSA-w42c-h7hr-f67p (v0.55.0) eingeflossen ist.

Geschätzte CVSS v3.1

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

  • AV:L — entspricht dem eigenen Scoring-Präzedenzfall dieses Projekts für seine MCP-Oberfläche (GHSA-w42c-h7hr-f67p verwendete ebenfalls AV:L): Die Standardbereitstellung ist ein lokaler MCP-Daemon, der über stdio vom Agent-Prozess auf demselben Host erreicht wird; AV:N würde nur für den optionalen --http-addr-Modus gelten.
  • UI:R — erfordert, dass der MCP-Client (ein LLM-Agent oder ein Mensch über gortex call) einen search_text- / search_text regexp:true-Aufruf ausführt. Ein breites Literal (z. B. ein einzelnes häufiges Zeichen) oder eine passende Regex (.) gegen ein indiziertes Repo, das den platzierten Symlink enthält, reicht aus, um die Zieldatei auszugeben — kein geheimes Wissen über deren Inhalt erforderlich —, also eine niedrige Hürde, aber dennoch eine eigenständige Aktion gegenüber dem bloßen Indexieren.
  • C:H — Offenlegung beliebiger Dateiinhalte, unbegrenzt durch Repo-Grenzen, von allem, was der OS-Benutzer des Daemons lesen kann (SSH-Schlüssel, Cloud-Credential-Dateien, Repos benachbarter Tenants in einem Multi-Repo-Daemon usw.), wörtlich in der Tool-Antwort zurückgegeben.
  • I:N / A:N — dies ist ein reiner Lesepfad-Fehler; nichts wird geschrieben oder unverfügbar gemacht.

Details

Ursache 1 — der Indexer-Walk prüft niemals auf symlinkte Datei-Einträge

internal/indexer/indexer.go:2549-2604, der primäre Korpus-Aufnahme-Walk:

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 verwendet Lstat-Semantik, sodass ein symlinktes Verzeichnis natürlicherweise geschützt ist — d.IsDir() ist dafür false und es wird nie rekursiv betreten. Ein symlinkter Datei-Eintrag erhält keinen äquivalenten Schutz: Nichts hier (noch in shouldExclude/shouldPruneDir, internal/indexer/indexer.go:5724-5813, die nur gitignore-artige Pfadmuster abgleichen) ruft d.Type()&os.ModeSymlink, os.Lstat oder filepath.EvalSymlinks für den Datei-Eintrag auf, bevor er in die Warteschlange gestellt wird. Eine Datei namens z. B. pwn.go, deren Ziel /etc/passwd, ~/.ssh/id_rsa oder ein Repo eines benachbarten Tenants ist, wird allein deshalb aufgenommen, weil ihr Name auf eine registrierte Erweiterung passt (effectiveLanguage, internal/parser DetectLanguageContent, pfadbasiert). Genau diese walked-file-Liste wird zu idx.fileMtimes (internal/indexer/indexer.go:3760: idx.fileMtimes[idx.relKey(f.path)] = f.mtimeNano).

Ursache 2 — die search_text-Senke liest Live-Dateien ohne Eingrenzungsschutz erneut

internal/indexer/grep.go:17-64 (GrepText / warmTrigramSearcher) baut den Trigram-Searcher direkt aus den Schlüsseln von 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) und :55-86/:102-176 (Grep/GrepRegexp) tun dann:

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 folgen standardmäßig Symlinks (kein O_NOFOLLOW). Weder diese Funktionen noch internal/mcp/tools_search_text.go:35-126 (handleSearchText, der MCP-Handler, der s.indexer.GrepText/GrepRegexp aufruft) rufen jemals resolveFilePath oder guardSymlinkWithinRepo auf. Diese beiden Eingrenzungsfunktionen existieren und sind korrekt in jeden anderen inhaltsausliefernden Pfad eingebunden — internal/mcp/tools_fileops.go (read_file, write_file/edit_file seit dem v0.55.0-Fix), internal/mcp/tools_coding.go:919 (get_symbol_source), internal/mcp/tools_lsp.go:264, internal/mcp/tools_export.go:95 —, aber der Trigram-Grep-Pfad von search_text ist eine separate Senke, die nie denselben Schutz erhalten hat. grep -rn guardSymlinkWithinRepo über den gesamten Baum bestätigt null Referenzen in tools_search_text.go, grep.go oder trigram/searcher.go.

Prüfung auf Duplikatrisiko / Eigenständigkeit

Dies ist tatsächlich eigenständig gegenüber GHSA-w42c-h7hr-f67p:

  • Jene Advisory: Schreibpfad, resolveFilePath nimmt absolute Pfade aus + write_file/edit_file/move_inline rufen nie guardSymlinkWithinRepo auf (behoben in v0.55.0).
  • Dieser Befund: Lesepfad, der eigene Discovery-Walk des Indexers (nicht irgendein MCP-Handler) nimmt eine symlinkte Datei ohne Lstat-Prüfung auf, und ein anderes MCP-Tool (search_text, nicht read_file/get_symbol_source) liefert deren Inhalt über eine Senke (internal/search/trigram) aus, die unabhängig davon nie guardSymlinkWithinRepo aufruft. Der Schreibpfad-Fix hat keinen dieser beiden Orte berührt. Dies entspricht dem bereits in ozgurcd/gograph (GHSA-6h6w-vhgr-2hp6) und vitali87/code-graph-rag (GHSA-85gg-2gfq-q95m) bestätigten Schwester-Tool-Muster: ein Datei-Discovery-Walk ohne Symlink-Schutz, gepaart mit einer inhaltsausliefernden Senke, der unabhängig davon ein Eingrenzungsschutz fehlt.

Proof of Concept

Statische Spur (Datei:Zeile-Referenzen oben) ist vollständig und durch Inspektion reproduzierbar. Dynamische Verifikation wurde versucht und wird tatsächlich durch eine Toolchain-Lücke in dieser Sandbox blockiert, ehrlich dokumentiert statt übertüncht:

Tool herunterladen