
VFS pour Git ab95cf51 - Élevé - À distance - RCE - core.virtualfilesystem enveloppement par guillemet simple
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · vfs-quote-breakout
Classe : RCE Portée : Distante
VFS for Git master ab95cf51 (tag v2.0.26259.1) - Microsoft
CloneVerb.GetCloneRoot prend le dernier segment du chemin de l'URL comme dossier d'enlistement par défaut et ne supprime pas un guillemet. RequiredGitConfig écrit ensuite core.virtualfilesystem comme un chemin de hook naïvement entouré de guillemets simples. microsoft/git exécute cette valeur avec use_shell=1. Le commentaire du produit mentionne même bash.
Une URL de clone dont le dernier segment est pwn';witness;' devient 'C:/temp/pwn';witness;'/src/.git/hooks/GVFS.VirtualFileSystemHook.exe'. bash y voit trois commandes. Celle du milieu s'exécute en tant que l'utilisateur qui a cloné.
| ID | pas encore de CVE |
| Classe | RCE (encapsulation par guillemets simples de core.virtualfilesystem) |
| Portée | Distante (UI:R clone d'une URL attaquante, ou git worktree add local sous un répertoire forgé) |
| CWE | CWE-78, CWE-116 |
| CVSS | Élevé : 8.8 CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H |
| Produit | VFS for Git (nécessite microsoft/git) |
| Affecté | master ab95cf51d6ffd0ee0e2feae7180078fe9ecbbb3a (tag v2.0.26259.1). Windows uniquement. |
| Auth | La victime clone une URL attaquante (ou git worktree add sous un répertoire forgé) |
| Licence | GNU Affero GPL v3.0 |
| Labo | 127.0.0.1 uniquement. how=gadget (pas de VM Windows / ProjFS réel). |
Exécuter du code en tant que l'utilisateur qui a cloné ou lancé git. Pas SYSTEM. Pas de RCE non authentifiée qui contourne « la victime clone cette URL ».
| Privilège | Méthode / sink | Ce que cela accorde | Reconnaissance / intégrité / disponibilité | Prouvé en labo ou déduit |
|---|---|---|---|---|
| Choisir le nom du dossier d'enlistement | Dernier segment de chemin de gvfs clone <url> sans dest (CloneVerb.GetCloneRoot) | Le nom du répertoire est choisi par l'attaquant. Windows autorise ' et ; | Intégrité du chemin de dest | Prouvé en labo sur le helper de dest copié. L'URL .../pwn';witness;' devient C:\temp\pwn';witness;' |
S'échapper de core.virtualfilesystem | RequiredGitConfig encapsule "'" + ConvertPathToGitFormat(hook) + "'" | La valeur de config est trois jetons shell, pas un seul chemin | Intégrité de la config git | Prouvé en labo. L'encapsulation est 'C:/temp/pwn';witness;'/src/.git/hooks/GVFS.VirtualFileSystemHook.exe' |
| Exécuter une commande shell supplémentaire en tant que cloneur | microsoft/git virtualfilesystem.c use_shell=1 (bash -c de la valeur de config) | Commande hôte arbitraire en tant qu'UID du cloneur | Intégrité / disponibilité de la session du cloneur | Prouvé en labo sur le gadget. witness a écrit VFS-VFS-QUOTE-WITNESS. Les premier et troisième jetons sont des chemins manquants (rc 127) |
| Même encapsulation sur worktree | Program.Worktree.cs -c core.virtualfilesystem="'<path>'" | Même évasion sans URL de clone | Intégrité | Déduit du code source épinglé. Non exécuté |
Répétition lors d'un git status / mount ultérieur | InProcessMount.TrySetRequiredGitConfigSettings réapplique l'encapsulation | Un git ultérieur exécute aussi la valeur hostile via le shell | Intégrité | Déduit. Non exécuté |
Fermé sur ce reliquat : ProjFS réel / Microsoft git / gvfs clone (cet hôte est macOS ; how=gadget). SYSTEM. RCE non authentifiée qui contourne « la victime clone cette URL ». Un dest dont le nom ne contient pas de ', et le même chemin hostile encapsulé avec '\'', n'exécutent pas witness.
Mêmes reliquats du pin : vfs-mount-dehydrate, vfs-clone-acl, vfs-service-sid, vfs-hook-impersonate, vfs-install-cwd.
J'ai épinglé VFS for Git master ab95cf51 après le merge du 2026-09-28. Microsoft recommande Scalar pour les nouveaux déploiements. L'arbre est toujours tagué v2.0.26259.1. La liste des exclusions est CVE-2021-47874 (binPath entre guillemets sur ce pin). Dix chasses. L'hydratation ProjFS, les parseurs GPRE, les URLs de cache, FastFetch et gvfs upgrade sont revenus vides dans cette barre.
Puis je me suis attardé sur RequiredGitConfig. Le commentaire documente bash. L'encapsulation n'échappe pas '. CloneVerb utilise le dernier segment de l'URL comme dest. C'est le reliquat.
Fausses pistes déjà consignées : traiter un dest sans guillemet comme le bug (ce n'est pas le cas) ; prétendre SYSTEM ; un reverse shell. Du théâtre. Windows natif manquait, donc le labo est un gadget de cette encapsulation plus bash -c.
python3 vfs-quote-breakout-Abraxas-Labs.py
ou
cd lab
./run.sh
Gadget HTTP sur 127.0.0.1:19630. Copie les helpers d'encapsulation et de dest, puis /bin/bash -c avec un PATH limité à un helper witness qui écrit l'oracle. Une VM Windows native n'était pas disponible. La dernière ligne utilise how=gadget.
SUCCESS vfs-quote-breakout how=gadget who=cloner naive-breakout=yes escaped-hold=yes VFS-VFS-QUOTE-WITNESS
Échapper ' en '\'' avant l'encapsulation, ou cesser d'utiliser use_shell et passer le hook comme argv[0]. Rejeter les chemins de clone et de worktree qui contiennent '.
ab95cf51d6ffd0ee0e2feae7180078fe9ecbbb3a (tag v2.0.26259.1)CloneVerb.cs dest par défautRequiredGitConfig.cs encapsulation qui n'échappe pas 'virtualfilesystem.c use_shell=1ImagePath sans guillemetsGNU Affero GPL v3.0. Voir LICENSE. Labo en boucle locale uniquement. Aucune garantie.