
VFS para Git ab95cf51 - Alta - Remoto - RCE - core.virtualfilesystem envoltura de comillas simples
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · vfs-quote-breakout
Clase: RCE Alcance: Remoto
VFS for Git master ab95cf51 (tag v2.0.26259.1) - Microsoft
CloneVerb.GetCloneRoot toma el último segmento de la ruta de la URL como carpeta de enlistamiento predeterminada y no elimina una comilla. RequiredGitConfig luego escribe core.virtualfilesystem como una ruta de hook ingenua entre comillas simples. microsoft/git ejecuta ese valor con use_shell=1. El comentario del producto incluso menciona bash.
Una URL de clonación cuyo último segmento es pwn';witness;' se convierte en 'C:/temp/pwn';witness;'/src/.git/hooks/GVFS.VirtualFileSystemHook.exe'. bash ve tres comandos. El del medio se ejecuta como el usuario que clonó.
| ID | aún sin CVE |
| Clase | RCE (envoltura entre comillas simples de core.virtualfilesystem) |
| Alcance | Remoto (UI:R clonación de una URL del atacante, o git worktree add local bajo un directorio manipulado) |
| 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 |
| Producto | VFS for Git (necesita microsoft/git) |
| Afectado | master ab95cf51d6ffd0ee0e2feae7180078fe9ecbbb3a (tag v2.0.26259.1). Solo Windows. |
| Auth | La víctima clona una URL del atacante (o git worktree add bajo un directorio manipulado) |
| Licencia | GNU Affero GPL v3.0 |
| Laboratorio | solo 127.0.0.1. how=gadget (sin VM de Windows / ProjFS en vivo). |
Ejecutar código en el host como el usuario que clonó o ejecutó git. No SYSTEM. No es RCE no autenticado que se salte "la víctima clona esta URL".
| Privilegio | Método / sink | Qué otorga | Reconocimiento / integridad / disponibilidad | Probado en laboratorio o inferido |
|---|---|---|---|---|
| Elegir el nombre de la carpeta de enlistamiento | Último segmento de ruta de gvfs clone <url> sin dest (CloneVerb.GetCloneRoot) | El nombre del directorio lo elige el atacante. Windows permite ' y ; | Integridad de la ruta dest | Probado en laboratorio sobre el helper dest copiado. La URL .../pwn';witness;' se convierte en C:\temp\pwn';witness;' |
Escapar de core.virtualfilesystem | RequiredGitConfig envuelve "'" + ConvertPathToGitFormat(hook) + "'" | El valor de configuración son tres tokens de shell, no una ruta | Integridad de la configuración de git | Probado en laboratorio. La envoltura es 'C:/temp/pwn';witness;'/src/.git/hooks/GVFS.VirtualFileSystemHook.exe' |
| Ejecutar un comando de shell adicional como el clonador | microsoft/git virtualfilesystem.c use_shell=1 (bash -c del valor de configuración) | Comando arbitrario en el host como el UID del clonador | Integridad / disponibilidad de la sesión del clonador | Probado en laboratorio sobre el gadget. witness escribió VFS-VFS-QUOTE-WITNESS. El primer y tercer token son rutas inexistentes (rc 127) |
| La misma envoltura en worktree | Program.Worktree.cs -c core.virtualfilesystem="'<path>'" | El mismo escape sin una URL de clonación | Integridad | Inferido del código fijado. No ejecutado |
Repetir en un git status / mount posterior | InProcessMount.TrySetRequiredGitConfigSettings vuelve a aplicar la envoltura | Un git posterior también ejecuta el valor hostil mediante shell | Integridad | Inferido. No ejecutado |
Cerrado en este remanente: ProjFS en vivo / Microsoft git / gvfs clone (este host es macOS; how=gadget). SYSTEM. RCE no autenticado que se salte "la víctima clona esta URL". Un dest cuyo nombre no tiene ', y la misma ruta hostil envuelta con '\'', no ejecutan witness.
Otros remanentes del mismo pin: vfs-mount-dehydrate, vfs-clone-acl, vfs-service-sid, vfs-hook-impersonate, vfs-install-cwd.
Fijé VFS for Git master ab95cf51 después del merge del 2026-09-28. Microsoft recomienda Scalar para nuevas implementaciones. El árbol sigue etiquetado como v2.0.26259.1. La lista de omisiones es CVE-2021-47874 (binPath entre comillas en este pin). Diez búsquedas. ProjFS hydration, parsers GPRE, URLs de caché, FastFetch y gvfs upgrade volvieron vacíos en este listón.
Luego me detuve en RequiredGitConfig. El comentario documenta bash. La envoltura no escapa '. CloneVerb usa el último segmento de la URL como dest. Ese es el remanente.
Malos caminos ya registrados: tratar un dest sin comilla como el bug (no lo es); afirmar SYSTEM; una reverse shell. Teatro. Faltaba Windows nativo, así que el laboratorio es un gadget de esa envoltura más bash -c.
python3 vfs-quote-breakout-Abraxas-Labs.py
o
cd lab
./run.sh
Gadget HTTP en 127.0.0.1:19630. Copia los helpers de envoltura y dest, luego /bin/bash -c con PATH limitado a un helper witness que escribe el oráculo. No había VM de Windows nativa disponible. La última línea usa how=gadget.
SUCCESS vfs-quote-breakout how=gadget who=cloner naive-breakout=yes escaped-hold=yes VFS-VFS-QUOTE-WITNESS
Escapar ' como '\'' antes de envolver, o dejar de usar use_shell y pasar el hook como argv[0]. Rechazar rutas de clonación y worktree que contengan '.
ab95cf51d6ffd0ee0e2feae7180078fe9ecbbb3a (tag v2.0.26259.1)CloneVerb.cs dest predeterminadoRequiredGitConfig.cs envoltura que no escapa 'virtualfilesystem.c use_shell=1ImagePath sin comillasGNU Affero GPL v3.0. Ver LICENSE. Solo laboratorio en loopback. Sin garantía.