
VFS for Git ab95cf51 - Mittel - Lokal - Verbleibendes Privileg - Dienst-Pipe vertraut JSON OwnerSID
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · vfs-service-sid
Klasse: Privilegien-Überrest Reichweite: Lokal
VFS for Git master ab95cf51 (Tag v2.0.26259.1) - Microsoft
GVFS.Service läuft als LocalSystem. WindowsPlatform.CreatePipeByName gewährt BUILTIN\Users ReadWrite | CreateNewInstance auf GVFS.Service.pipe. RegisterRepoHandler.Run speichert die JSON-OwnerSID unverändert. Nichts ruft ImpersonateNamedPipeClient auf.
Jeder Users-Principal kann einen Angreifer-Pfad unter einer Opfer-SID registrieren. Bei SessionLogon führt der Dienst CreateProcessAsUser mit gvfs mount <Angreifer-Pfad> als das Opfer aus. Das Kindprozess ist nicht NT AUTHORITY\SYSTEM.
| ID | noch keine CVE |
| Klasse | Privilegien-Überrest (fehlende Autorisierung / Cross-User-Ausführung) |
| Reichweite | Lokal |
| CWE | CWE-862, CWE-284 |
| CVSS | Mittel: 6.6 CVSS:3.1/AV:L/AC:L/PR:L/UI:R/S:U/C:H/I:H/A:N |
| Produkt | VFS for Git |
| Betroffen | master ab95cf51d6ffd0ee0e2feae7180078fe9ecbbb3a; GitHub-Tags v2.0.26229.1 / v2.0.26259.1. Nur Windows. |
| Auth | Lokal. Jeder BUILTIN\Users-Principal. Opfer-Anmeldung für Automount. |
| Lizenz | GNU Affero GPL v3.0 |
| Lab | nur 127.0.0.1. how=gadget (kein aktiver Windows-GVFS.Service). |
Git 2.35+ dubious-ownership kann dann git innerhalb eines angreifer-eigenen Verzeichnisbaums fehlschlagen lassen. Der Prozess startet dennoch als das Opfer. Wenn der Pfad opfer-eigen, aber angreifer-beschreibbar ist (vfs-clone-acl), laufen mount git, credential.helper und Hooks als dieser Benutzer.
Jeder BUILTIN\Users-Principal auf einer Maschine, auf der der Dienst installiert ist. Verbindung zu \\.\pipe\GVFS.Service.pipe. Keine zusätzlichen Privilegien.
| Privileg | Methode / Sink | Was es gewährt | Recon / Integrität / Verfügbarkeit | Lab-bewiesen oder abgeleitet |
|---|---|---|---|---|
| Jeden aktiven Enlistment-Root auflisten | GetActiveRepoListRequest ohne SID-Prüfung (TryGetActiveRepos, nicht GetActiveReposForUser) | Pfade, die als Pipe-Name-Oracle für Überrest #2 verwendet werden | Recon | Lab-bewiesen. Gadget listete /lab/repos/victim auf |
| Ein Opfer-Enlistment deaktivieren, damit es nicht automountet | UnregisterRepoRequest {EnlistmentRoot} ohne SID-Prüfung (TryDeactivateRepo) | Opfer-Repos bleiben unmounted | Verfügbarkeit | Lab-bewiesen. Opfer-Zeile aus der aktiven Liste verschwunden |
| Angreifer-Pfad unter Opfer-SID persistieren | RegisterRepoRequest JSON EnlistmentRoot + OwnerSID; TryRegisterRepo speichert beides | Registry-Zeile Angreifer-Pfad + Opfer-SID | Integrität | Lab-bewiesen. Registry-Zeile /lab/repos/attacker + S-1-5-21-1000-2000-3000-1001 |
GVFS.exe mount <Angreifer-Pfad> als das Opfer bei Anmeldung starten | OnSessionChange SessionLogon -> AutoMountRepos(userId) -> TryRunAs / CreateProcessAsUser | Cross-User-Prozesserstellung als der angemeldete Benutzer | Integrität | Lab-bewiesen am Gadget. Spawn-Elternprozess GVFS.Service, argv mount /lab/repos/attacker, uid 1002 victim, Witness geschrieben |
| Als NT AUTHORITY\SYSTEM ausführen | Derselbe Automount | LocalSystem-Kindprozess | Integrität | Geschlossen. Kindprozess whoami ist das Opfer, nicht SYSTEM (child-not-system=yes) |
Git / Hook / credential.helper als das Opfer innerhalb eines angreifer-eigenen Verzeichnisbaums | Prozesserstellung findet weiterhin statt; git 2.35+ safe.directory kann fehlschlagen | Hook-RCE als Opfer, wenn der Baum opfer-eigen, aber angreifer-beschreibbar ist | Integrität | Abgeleitet. Lab hat Microsoft git nicht ausgeführt. Den Pfad als opfer-eigen, aber angreifer-beschreibbar binden für Hook-RCE |
Geschlossen bei diesem Pin: entfernter unauthentifizierter Zugriff (Named Pipe ist lokal). SYSTEM-Shell. Die Standard-Pipe-ACL lässt Users weiterhin herein; ein gepatchtes Register, das die Client-SID bindet (Gadget X-Patched: 1), automountet den Angreifer-Pfad nicht für das Opfer.
Gleiche Pin-Überreste: vfs-quote-breakout, vfs-mount-dehydrate, vfs-clone-acl, vfs-hook-impersonate, vfs-install-cwd.
Ich habe VFSForGit master ab95cf51 nach dem Merge vom 2026-09-28 gepinnt. Die Service-Pipe-ACL ist Users ReadWrite. Register speichert JSON OwnerSID. SessionLogon automountet als diese SID. Nichts impersoniert den Pipe-Client.
Bereits dokumentierte Irrwege: dies als SYSTEM-Shell zu bezeichnen (Automount ist CreateProcessAsUser des Logon-Tokens); git safe.directory als Autorisierung des IPC zu behandeln; eine Reverse Shell. Theater. Native Windows fehlte, daher ist das Lab ein Gadget der Pin-Handler plus ein Unix-TCP-Oracle.
python3 vfs-service-sid-Abraxas-Labs.py
oder
cd lab
./run.sh
Gadget-HTTP auf 127.0.0.1:19660. Witness VFS-SERVICE-SID-WITNESS. Letzte Zeile verwendet how=gadget.
SUCCESS vfs-service-sid how=gadget register-forged-sid=yes automount-as-victim=yes child-not-system=yes VFS-SERVICE-SID-WITNESS
Den Named-Pipe-Client impersonieren (ImpersonateNamedPipeClient / NamedPipeServerStream.RunAsClient). JSON OwnerSID ignorieren; TryRegisterRepo an die Client-SID binden. CreatePipeByName auf den interaktiven Benutzer und LocalSystem beschränken (BuiltinUsersSid ReadWrite / CreateNewInstance entfernen). GetActiveRepoList sollte nur die Repos dieses Clients zurückgeben. UnregisterRepo sollte denselben SID-Abgleich erfordern.