
VFS for Git ab95cf51 - Hoch - Lokal - Verbleibendes Privileg - Hook CreateFileW SecurityImpersonation
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · vfs-hook-impersonate
Klasse: Privilegien-Überrest Reichweite: Lokal
VFS for Git master ab95cf51 (Tag v2.0.26259.1) - Microsoft
Native Git-Hooks (read-object, virtual-filesystem, post-index-changed) öffnen die Mount-Pipe pro Enlistment mit CreateFileW und dwFlagsAndAttributes = 0. Dadurch fehlt SECURITY_SQOS_PRESENT, sodass Windows den Client standardmäßig auf SecurityImpersonation setzt. Dieselbe Pipe-ACL, die Überrest #2 verwendet, gewährt BUILTIN\Users ReadWrite | CreateNewInstance.
Ein zweiter lokaler Benutzer kann eine zusätzliche Instanz von \\.\pipe\GVFS_<ENLISTMENT> erzeugen oder diese besetzen, ImpersonateNamedPipeClient aufrufen und als das Opfer schreiben.
| ID | noch keine CVE |
| Klasse | Privilegien-Überrest (Named-Pipe-Impersonation) |
| Reichweite | Lokal |
| CWE | CWE-284, CWE-300 |
| CVSS | Hoch: 7.1 CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N |
| Produkt | VFS for Git |
| Betroffen | master ab95cf51d6ffd0ee0e2feae7180078fe9ecbbb3a (auch aktuell gegenüber Release v2.0.26259.1). Nur Windows. |
| Auth | Lokal. Das Opfer besitzt ein GVFS-Enlistment. Angreifer ist ein beliebiges BUILTIN\Users-Principal. Das Opfer führt später git aus. |
| Lizenz | GNU Affero GPL v3.0 |
| Lab | nur 127.0.0.1. how=gadget (keine Live-Windows-VM / kein installiertes VFS for Git). |
Dies ist lokal. Es ist kein SYSTEM. Automount in Überrest #4 ist eine andere Pipe (GVFS.Service.pipe). Dehydrate/Unmount auf derselben Mount-Pipe ist Überrest #2.
Das Opfer besitzt ein GVFS-Enlistment. Der Angreifer ist ein beliebiges BUILTIN\Users-Principal. Das Opfer führt später git aus (status, checkout, alles, was die VFS-Hooks auslöst).
| Privileg | Methode / Sink | Was es gewährt | Recon / Integrität / Verfügbarkeit | Im Lab bewiesen oder abgeleitet |
|---|---|---|---|---|
| Das Opfer imitieren und in dessen Profil schreiben | Zusätzliche Instanz / Besetzen von \\.\pipe\GVFS_C_\REPOS\FOO; Hook CreateFileW flags=0; ImpersonateNamedPipeClient; %USERPROFILE%\VFS-HOOK-IMPERSONATE-WITNESS anlegen | Schreiben als die UID des Opfers | Integrität | Im Lab an einem Gadget bewiesen. Der Besitzer der Witness-Datei ist die UID des Opfers. Standard-Flags sind SecurityImpersonation. Die UID des Angreifers kann ohne Impersonation nicht in dieses Home schreiben |
| Git nach dem Besetzen weiterlaufen lassen | Auf MPL|1 mit S|\x03 antworten, damit GVFS.VirtualFileSystemHook nicht hängt | Git läuft weiter | Verfügbarkeit des Git des Opfers | Im Lab bewiesen. Hook reply_ok sowohl auf dem verwundbaren als auch auf dem gepatchten Pfad |
| Den Pipe-Namen aus dem Enlistment-Root erraten | GetGVFSPipeName läuft vom CWD zu .gvfs, CharUpper, : -> _, Präfix \\.\pipe\GVFS_ | Erratbarer IPC-Name | Recon | Im Lab bewiesen. C:\Repos\Foo\src -> \\.\pipe\GVFS_C_\REPOS\FOO |
| Die Pipe umlenken, ohne die laufende Instanz zu übernehmen | Ein getracktes src\.gvfs-Verzeichnis platzieren, sodass der Walk-up einen anderen Namen bindet | Besetzen ohne Wettlauf mit dem Mount | Integrität | Abgeleitet aus dem Walk-up in common.windows.cpp. Im Lab wurde das echte Enlistment-.gvfs verwendet |
Auch auf DLO / PICN antworten, nicht nur auf MPL | Dieselbe Pipe, ReadObjectHook / PostIndexChangedHook | Über Objekte lügen / skip-worktree | Integrität | Abgeleitet. Im Lab wurde nur MPL|1 gesendet |
Den Hook mit einem zwei Byte großen S\x03 zum Absturz bringen | VirtualFileSystemHook messageLength -= 2, dann -= 1 Unterlauf und fwrite von ~4GiB | Absturz / OOB-Read | Verfügbarkeit | Abgeleitet aus main.cpp 69-90. Nicht das Orakel. Diesen Absturz nicht ausliefern |
Hier ausgeschlossen: SYSTEM (der Mount ist der Enlistment-Benutzer). Remote unauthentifizierte RCE. Live-Windows-VM / installiertes VFS for Git (dieses Lab ist ein Gadget der kopierten Funktionen).
Überreste desselben Pins: vfs-quote-breakout, vfs-mount-dehydrate, vfs-clone-acl, vfs-service-sid, vfs-install-cwd.
Ich habe VFSForGit master ab95cf51 nach dem Merge vom 2026-09-28 gepinnt. Native Hooks rufen CreateFileW mit Flags 0 auf. Windows setzt dann standardmäßig auf SecurityImpersonation. Die Mount-Pipe erlaubt Users bereits eine zusätzliche Instanz. Das ist der Überrest.
Bereits festgehaltene Irrwege: dies als Überrest #2 Dehydrate zu behandeln (gleiche ACL, anderer Sink: Token, nicht MoveDirectory); SYSTEM zu behaupten; den 4GiB-Unterlauf als Orakel auszuliefern. Theater. Echtes Windows fehlte, daher ist das Lab ein Gadget dieser Funktionen. Unix-Sockets stehen stellvertretend für Named Pipes.
python3 vfs-hook-impersonate-Abraxas-Labs.py
oder
cd lab
./run.sh
Gadget-HTTP auf 127.0.0.1:19670. Kopiert GetGVFSPipeName, die CreatePipeToGVFS-Flags, die Users-CreateNewInstance-ACL und das MPL|1 / S|-Hook-Protokoll. Ein gepatchter Client mit SQOS-Identifikation schreibt die Witness-Datei nicht. Die letzte Zeile verwendet how=gadget.
SUCCESS vfs-hook-impersonate how=gadget createfile-flags=0 impersonation=SecurityImpersonation extra-instance=yes owner=victim patched-sqos-ident-no-write=yes VFS-HOOK-IMPERSONATE-WITNESS
Beim Hook CreateFileW SECURITY_SQOS_PRESENT | SECURITY_IDENTIFICATION übergeben. CreatePipeByName auf die SID des Enlistment-Besitzers plus LocalSystem beschränken. CreateNewInstance für Users entfernen. Antwortlängen der Hooks mit Bounds-Checks versehen.
ab95cf51d6ffd0ee0e2feae7180078fe9ecbbb3acommon.windows.cpp CreatePipeToGVFSWindowsPlatform.cs CreatePipeByNameGNU Affero GPL v3.0. Siehe LICENSE. Nur Loopback-Lab. Keine Gewährleistung.