abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · vfs-hook-impersonate
类别: 权限残留 可达性: 本地
VFS for Git master ab95cf51(标签 v2.0.26259.1)- Microsoft
原生 git 钩子(read-object、virtual-filesystem、post-index-changed)使用 CreateFileW 打开每个 enlistment 的挂载管道,且 dwFlagsAndAttributes = 0。这省略了 SECURITY_SQOS_PRESENT,因此 Windows 将客户端默认为 SecurityImpersonation。与残留 #2 使用的相同管道 ACL 授予 BUILTIN\Users ReadWrite | CreateNewInstance。
第二个本地用户可以额外实例化或抢占 \\.\pipe\GVFS_<ENLISTMENT>,调用 ImpersonateNamedPipeClient,并以受害者身份写入。
| ID | 暂无 CVE |
| 类别 | 权限残留(命名管道模拟) |
| 可达性 | 本地 |
| CWE | CWE-284、CWE-300 |
| CVSS | 高危:7.1 CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N |
| 产品 | VFS for Git |
| 受影响版本 | master ab95cf51d6ffd0ee0e2feae7180078fe9ecbbb3a(相对于发布版 v2.0.26259.1 也是当前版本)。仅限 Windows。 |
| 认证 | 本地。受害者拥有 GVFS enlistment。攻击者是任意 BUILTIN\Users 主体。受害者随后运行 git。 |
| 许可证 | GNU Affero GPL v3.0 |
| 实验环境 | 仅 127.0.0.1。how=gadget(无实时 Windows VM / 未安装 VFS for Git)。 |
这是本地漏洞。不是 SYSTEM。残留 #4 中的 Automount 是另一个管道(GVFS.Service.pipe)。同一挂载管道上的 Dehydrate/unmount 是残留 #2。
受害者拥有 GVFS enlistment。攻击者是任意 BUILTIN\Users 主体。受害者随后运行 git(status、checkout,任何触发 VFS 钩子的操作)。
| 权限 | 方法 / 汇聚点 | 授予内容 | 侦察 / 完整性 / 可用性 | 实验验证或推断 |
|---|---|---|---|---|
| 模拟受害者并写入其配置文件 | 额外实例化 / 抢占 \\.\pipe\GVFS_C_\REPOS\FOO;钩子 CreateFileW flags=0;ImpersonateNamedPipeClient;创建 %USERPROFILE%\VFS-HOOK-IMPERSONATE-WITNESS | 以受害者 UID 写入 | 完整性 | 在 gadget 上实验验证。Witness 所有者为受害者 uid。默认标志为 SecurityImpersonation。攻击者 uid 无法在没有模拟的情况下写入该主目录 |
| 抢占后保持 git 正常工作 | 对 MPL|1 回复 S|\x03,使 GVFS.VirtualFileSystemHook 不挂起 | Git 继续运行 | 受害者 git 的可用性 | 实验验证。在漏洞路径和修补路径上钩子 reply_ok |
| 从 enlistment 根目录猜测管道名称 | GetGVFSPipeName 从 CWD 向上遍历到 .gvfs,CharUpper,: -> _,前缀 \\.\pipe\GVFS_ | 可猜测的 IPC 名称 | 侦察 | 实验验证。C:\Repos\Foo\src -> \\.\pipe\GVFS_C_\REPOS\FOO |
| 在不赢得活动实例的情况下重定向管道 | 放置一个受跟踪的 src\.gvfs 目录,使向上遍历绑定到不同的名称 | 无需竞争挂载即可抢占 | 完整性 | 从 common.windows.cpp 的向上遍历推断。实验使用了真实的 enlistment .gvfs |
同时应答 DLO / PICN 和 MPL | 同一管道,ReadObjectHook / PostIndexChangedHook | 对对象撒谎 / skip-worktree | 完整性 | 推断。实验仅发送了 MPL|1 |
用两字节 S\x03 使钩子崩溃 | VirtualFileSystemHook 的 messageLength -= 2 然后 -= 1 下溢并 fwrite 约 4GiB | 崩溃 / 越界读取 | 可用性 | 从 main.cpp 69-90 推断。不是 oracle。不要发布该崩溃 |
此处已排除:SYSTEM(挂载是 enlistment 用户)。远程未认证 RCE。实时 Windows VM / 已安装 VFS for Git(本实验是复制函数的 gadget)。
相同 pin 的残留:vfs-quote-breakout、vfs-mount-dehydrate、vfs-clone-acl、vfs-service-sid、vfs-install-cwd。
在 2026-09-28 合并后,我固定了 VFSForGit master ab95cf51。原生钩子以 flags 0 调用 CreateFileW。Windows 随后默认为 SecurityImpersonation。挂载管道已经允许 Users 额外实例化。这就是残留。
已记录的弯路:将其视为残留 #2 dehydrate(相同 ACL,不同汇聚点:token,而非 MoveDirectory);声称 SYSTEM;将 4GiB 下溢作为 oracle 发布。都是表演。缺少原生 Windows,因此实验是这些函数的 gadget。Unix 套接字代替命名管道。
python3 vfs-hook-impersonate-Abraxas-Labs.py
或
cd lab
./run.sh
Gadget HTTP 位于 127.0.0.1:19670。复制了 GetGVFSPipeName、CreatePipeToGVFS 标志、Users 的 CreateNewInstance ACL,以及 MPL|1 / S| 钩子协议。带有 SQOS identification 的修补客户端不会写入 witness。最后一行使用 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
在钩子 CreateFileW 上传递 SECURITY_SQOS_PRESENT | SECURITY_IDENTIFICATION。将 CreatePipeByName 限制为 enlistment 所有者 SID 加上 LocalSystem。移除 Users 的 CreateNewInstance。对钩子回复长度进行边界检查。
ab95cf51d6ffd0ee0e2feae7180078fe9ecbbb3acommon.windows.cpp CreatePipeToGVFSWindowsPlatform.cs CreatePipeByNameGNU Affero GPL v3.0。参见 LICENSE。仅限回环实验。无担保。