
VFS per Git ab95cf51 - Alto - Remoto - RCE - core.virtualfilesystem wrap con virgolette singole
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · vfs-quote-breakout
Classe: RCE Portata: Remota
VFS for Git master ab95cf51 (tag v2.0.26259.1) - Microsoft
CloneVerb.GetCloneRoot prende l'ultimo segmento del percorso dell'URL come cartella di enlistment predefinita e non rimuove un apice. RequiredGitConfig scrive poi core.virtualfilesystem come un ingenuo percorso di hook racchiuso tra apici singoli. microsoft/git esegue quel valore con use_shell=1. Il commento del prodotto nomina persino bash.
Un URL di clone il cui ultimo segmento è pwn';witness;' diventa 'C:/temp/pwn';witness;'/src/.git/hooks/GVFS.VirtualFileSystemHook.exe'. bash vede tre comandi. Quello centrale viene eseguito come l'utente che ha clonato.
| ID | nessuna CVE al momento |
| Classe | RCE (racchiusura tra apici singoli di core.virtualfilesystem) |
| Portata | Remota (UI:R clone di un URL dell'attaccante, o git worktree add locale sotto una directory manipolata) |
| CWE | CWE-78, CWE-116 |
| CVSS | Alto: 8.8 CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H |
| Prodotto | VFS for Git (richiede microsoft/git) |
| Affetto | master ab95cf51d6ffd0ee0e2feae7180078fe9ecbbb3a (tag v2.0.26259.1). Solo Windows. |
| Auth | La vittima clona un URL dell'attaccante (o git worktree add sotto una directory manipolata) |
| Licenza | GNU Affero GPL v3.0 |
| Lab | solo 127.0.0.1. how=gadget (nessuna VM Windows / ProjFS live). |
Eseguire codice come l'utente che ha clonato o eseguito git. Non SYSTEM. Non RCE non autenticata che salta "la vittima clona questo URL".
| Privilegio | Metodo / sink | Cosa concede | Recon / integrità / disponibilità | Provato in lab o dedotto |
|---|---|---|---|---|
| Scegliere il nome della cartella di enlistment | Ultimo segmento del percorso di gvfs clone <url> senza dest (CloneVerb.GetCloneRoot) | Il nome della directory è scelto dall'attaccante. Windows consente ' e ; | Integrità del percorso dest | Provato in lab sull'helper dest copiato. L'URL .../pwn';witness;' diventa C:\temp\pwn';witness;' |
Uscire da core.virtualfilesystem | RequiredGitConfig racchiude "'" + ConvertPathToGitFormat(hook) + "'" | Il valore di configurazione è tre token shell, non un percorso | Integrità della configurazione git | Provato in lab. La racchiusura è 'C:/temp/pwn';witness;'/src/.git/hooks/GVFS.VirtualFileSystemHook.exe' |
| Eseguire un comando shell aggiuntivo come il cloner | microsoft/git virtualfilesystem.c use_shell=1 (bash -c del valore di configurazione) | Comando host arbitrario come UID del cloner | Integrità / disponibilità della sessione del cloner | Provato in lab sul gadget. witness ha scritto VFS-VFS-QUOTE-WITNESS. Il primo e il terzo token sono percorsi mancanti (rc 127) |
| Stessa racchiusura su worktree | Program.Worktree.cs -c core.virtualfilesystem="'<path>'" | Stessa breakout senza un URL di clone | Integrità | Dedotto dal sorgente del pin. Non eseguito |
Ripetizione su successivi git status / mount | InProcessMount.TrySetRequiredGitConfigSettings riapplica la racchiusura | Anche git successivi eseguono via shell il valore ostile | Integrità | Dedotto. Non eseguito |
Chiuso su questo residuo: ProjFS live / Microsoft git / gvfs clone (questo host è macOS; how=gadget). SYSTEM. RCE non autenticata che salta "la vittima clona questo URL". Un dest il cui nome non contiene ', e lo stesso percorso ostile racchiuso con '\'', non eseguono witness.
Altri residui dello stesso pin: vfs-mount-dehydrate, vfs-clone-acl, vfs-service-sid, vfs-hook-impersonate, vfs-install-cwd.
Ho fissato VFS for Git master ab95cf51 dopo il merge del 2026-09-28. Microsoft raccomanda Scalar per i nuovi deployment. L'albero è ancora taggato v2.0.26259.1. La skip list è CVE-2021-47874 (binPath tra apici su questo pin). Dieci ricerche. ProjFS hydration, parser GPRE, URL di cache, FastFetch e gvfs upgrade sono risultati vuoti in questo ambito.
Poi mi sono soffermato su RequiredGitConfig. Il commento documenta bash. La racchiusura non fa escape di '. CloneVerb usa l'ultimo segmento dell'URL come dest. Questo è il residuo.
Vicoli ciechi già registrati: trattare un dest senza apice come il bug (non lo è); dichiarare SYSTEM; una reverse shell. Teatro. Windows nativo era assente, quindi il lab è un gadget di quella racchiusura più bash -c.
python3 vfs-quote-breakout-Abraxas-Labs.py
oppure
cd lab
./run.sh
Gadget HTTP su 127.0.0.1:19630. Copia gli helper della racchiusura e del dest, poi /bin/bash -c con PATH limitato a un helper witness che scrive l'oracolo. Una VM Windows nativa non era disponibile. L'ultima riga usa how=gadget.
SUCCESS vfs-quote-breakout how=gadget who=cloner naive-breakout=yes escaped-hold=yes VFS-VFS-QUOTE-WITNESS
Fare escape di ' come '\'' prima della racchiusura, oppure smettere di usare use_shell e passare l'hook come argv[0]. Rifiutare percorsi di clone e worktree che contengono '.
ab95cf51d6ffd0ee0e2feae7180078fe9ecbbb3a (tag v2.0.26259.1)CloneVerb.cs dest predefinitoRequiredGitConfig.cs racchiusura che non fa escape di 'virtualfilesystem.c use_shell=1ImagePath senza apiciGNU Affero GPL v3.0. Vedi LICENSE. Solo lab su loopback. Nessuna garanzia.