
VFS pour Git ab95cf51 - Élevé - Local - Privilège résiduel - hook CreateFileW SecurityImpersonation
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · vfs-hook-impersonate
Classe : Reliquat de privilège Portée : Locale
VFS for Git master ab95cf51 (tag v2.0.26259.1) - Microsoft
Les hooks git natifs (read-object, virtual-filesystem, post-index-changed) ouvrent le pipe de montage par enlistment avec CreateFileW et dwFlagsAndAttributes = 0. Cela omet SECURITY_SQOS_PRESENT, donc Windows applique par défaut SecurityImpersonation au client. La même ACL de pipe qu'utilise le reliquat #2 accorde à BUILTIN\Users ReadWrite | CreateNewInstance.
Un second utilisateur local peut créer une instance supplémentaire ou squatter \\.\pipe\GVFS_<ENLISTMENT>, ImpersonateNamedPipeClient, et écrire en tant que la victime.
| ID | pas encore de CVE |
| Classe | Reliquat de privilège (usurpation de named-pipe) |
| Portée | Locale |
| CWE | CWE-284, CWE-300 |
| CVSS | Élevé : 7.1 CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N |
| Produit | VFS for Git |
| Affecté | master ab95cf51d6ffd0ee0e2feae7180078fe9ecbbb3a (également la version actuelle vs release v2.0.26259.1). Windows uniquement. |
| Auth | Local. La victime possède un enlistment GVFS. L'attaquant est n'importe quel principal BUILTIN\Users. La victime exécute git plus tard. |
| Licence | GNU Affero GPL v3.0 |
| Lab | 127.0.0.1 uniquement. how=gadget (pas de VM Windows live / VFS for Git installé). |
Ceci est local. Ce n'est pas SYSTEM. L'automount du reliquat #4 est un pipe différent (GVFS.Service.pipe). Dehydrate/unmount sur ce même pipe de montage est le reliquat #2.
La victime possède un enlistment GVFS. L'attaquant est n'importe quel principal BUILTIN\Users. La victime exécute git plus tard (status, checkout, tout ce qui déclenche les hooks VFS).
| Privilège | Méthode / sink | Ce que cela accorde | Recon / intégrité / disponibilité | Prouvé en lab ou déduit |
|---|---|---|---|---|
| Usurper la victime et écrire dans son profil | Instance supplémentaire / squat \\.\pipe\GVFS_C_\REPOS\FOO ; hook CreateFileW flags=0 ; ImpersonateNamedPipeClient ; créer %USERPROFILE%\VFS-HOOK-IMPERSONATE-WITNESS | Écrire en tant que l'UID de la victime | Intégrité | Prouvé en lab sur un gadget. Le propriétaire du witness est l'uid de la victime. Les flags par défaut sont SecurityImpersonation. L'uid de l'attaquant ne peut pas écrire dans ce home sans usurpation |
| Maintenir git fonctionnel après le squat | Répondre S|\x03 à MPL|1 pour que GVFS.VirtualFileSystemHook ne bloque pas | Git continue | Disponibilité du git de la victime | Prouvé en lab. Hook reply_ok sur les chemins vulnérable et patché |
| Deviner le nom du pipe depuis la racine de l'enlistment | GetGVFSPipeName remonte le CWD jusqu'à .gvfs, CharUpper, : -> _, préfixe \\.\pipe\GVFS_ | Nom IPC devinable | Recon | Prouvé en lab. C:\Repos\Foo\src -> \\.\pipe\GVFS_C_\REPOS\FOO |
| Recibler le pipe sans gagner l'instance live | Placer un répertoire src\.gvfs suivi pour que la remontée lie un nom différent | Squatter sans courir après le montage | Intégrité | Déduit de la remontée dans common.windows.cpp. Le lab a utilisé le vrai .gvfs de l'enlistment |
Répondre à DLO / PICN ainsi qu'à MPL | Même pipe, ReadObjectHook / PostIndexChangedHook | Mentir sur les objets / skip-worktree | Intégrité | Déduit. Le lab n'a envoyé que MPL|1 |
Faire planter le hook avec un S\x03 de deux octets | VirtualFileSystemHook messageLength -= 2 puis -= 1 sous-déborde et fwrite ~4GiB | Crash / lecture hors limites | Disponibilité | Déduit de main.cpp 69-90. Ce n'est pas l'oracle. Ne pas livrer ce crash |
Exclus ici : SYSTEM (le montage est l'utilisateur de l'enlistment). RCE distant non authentifié. VM Windows live / VFS for Git installé (ce lab est un gadget des fonctions copiées).
Mêmes reliquats épinglés : vfs-quote-breakout, vfs-mount-dehydrate, vfs-clone-acl, vfs-service-sid, vfs-install-cwd.
J'ai épinglé VFSForGit master ab95cf51 après le merge du 2026-09-28. Les hooks natifs CreateFileW avec flags 0. Windows applique alors par défaut SecurityImpersonation. Le pipe de montage permet déjà aux Users de créer une instance supplémentaire. C'est le reliquat.
Fausses pistes déjà consignées : traiter ceci comme le dehydrate du reliquat #2 (même ACL, sink différent : token, pas MoveDirectory) ; prétendre SYSTEM ; livrer le sous-débordement de 4GiB comme oracle. Du théâtre. Windows natif manquait, donc le lab est un gadget de ces fonctions. Les sockets Unix remplacent les named pipes.
python3 vfs-hook-impersonate-Abraxas-Labs.py
ou
cd lab
./run.sh
Gadget HTTP sur 127.0.0.1:19670. Copie GetGVFSPipeName, les flags CreatePipeToGVFS, l'ACL CreateNewInstance des Users, et le protocole de hook MPL|1 / S|. Un client patché avec identification SQOS n'écrit pas le witness. La dernière ligne utilise 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
Sur le hook CreateFileW, passer SECURITY_SQOS_PRESENT | SECURITY_IDENTIFICATION. Restreindre CreatePipeByName au SID du propriétaire de l'enlistment plus LocalSystem. Retirer CreateNewInstance pour les Users. Vérifier les bornes des longueurs de réponse des hooks.
ab95cf51d6ffd0ee0e2feae7180078fe9ecbbb3acommon.windows.cpp CreatePipeToGVFSWindowsPlatform.cs CreatePipeByNameGNU Affero GPL v3.0. Voir LICENSE. Lab en loopback uniquement. Aucune garantie.