abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · vfs-service-sid
类别: 权限残留 可达性: 本地
VFS for Git master ab95cf51(标签 v2.0.26259.1)- Microsoft
GVFS.Service 以 LocalSystem 身份运行。WindowsPlatform.CreatePipeByName 授予 BUILTIN\Users 对 GVFS.Service.pipe 的 ReadWrite | CreateNewInstance 权限。RegisterRepoHandler.Run 原样存储 JSON 中的 OwnerSID。没有任何地方调用 ImpersonateNamedPipeClient。
任何 Users 主体都可以在受害者 SID 下注册攻击者路径。在 SessionLogon 时,服务以受害者身份 CreateProcessAsUser 执行 gvfs mount <攻击者路径>。子进程不是 NT AUTHORITY\SYSTEM。
| ID | 暂无 CVE |
| 类别 | 权限残留(缺少授权 / 跨用户执行) |
| 可达性 | 本地 |
| CWE | CWE-862、CWE-284 |
| CVSS | 中危:6.6 CVSS:3.1/AV:L/AC:L/PR:L/UI:R/S:U/C:H/I:H/A:N |
| 产品 | VFS for Git |
| 受影响版本 | master ab95cf51d6ffd0ee0e2feae7180078fe9ecbbb3a;GitHub 标签 v2.0.26229.1 / v2.0.26259.1。仅限 Windows。 |
| 认证 | 本地。任意 BUILTIN\Users 主体。自动挂载需要受害者登录。 |
| 许可证 | GNU Affero GPL v3.0 |
| 实验环境 | 仅 127.0.0.1。how=gadget(无实时 Windows GVFS.Service)。 |
Git 2.35+ 的 dubious-ownership 检查随后可能导致在攻击者拥有的目录树内 git 失败。进程仍以受害者身份启动。如果路径归受害者所有但攻击者可写(vfs-clone-acl),则 mount git、credential.helper 和 hooks 均以该用户身份运行。
在安装了该服务的机器上的任意 BUILTIN\Users 主体。连接到 \\.\pipe\GVFS.Service.pipe。无需额外权限。
| 权限 | 方法 / 汇聚点 | 授予的能力 | 侦察 / 完整性 / 可用性 | 实验验证或推断 |
|---|---|---|---|---|
| 列出所有活动 enlistment 根目录 | GetActiveRepoListRequest 无 SID 检查(TryGetActiveRepos,而非 GetActiveReposForUser) | 路径被用作残留 #2 的管道名预言机 | 侦察 | 实验验证。Gadget 列出了 /lab/repos/victim |
| 停用受害者 enlistment 使其不自动挂载 | UnregisterRepoRequest {EnlistmentRoot} 无 SID 检查(TryDeactivateRepo) | 受害者仓库保持未挂载 | 可用性 | 实验验证。受害者行从活动列表中消失 |
| 在受害者 SID 下持久化攻击者路径 | RegisterRepoRequest JSON EnlistmentRoot + OwnerSID;TryRegisterRepo 存储两者 | 注册表行:攻击者路径 + 受害者 SID | 完整性 | 实验验证。注册表行 /lab/repos/attacker + S-1-5-21-1000-2000-3000-1001 |
在登录时以受害者身份启动 GVFS.exe mount <攻击者路径> | OnSessionChange SessionLogon -> AutoMountRepos(userId) -> TryRunAs / CreateProcessAsUser | 以登录用户身份跨用户创建进程 | 完整性 | 在 gadget 上实验验证。生成的父进程 GVFS.Service,argv mount /lab/repos/attacker,uid 1002 victim,写入见证 |
| 以 NT AUTHORITY\SYSTEM 身份运行 | 同一自动挂载 | LocalSystem 子进程 | 完整性 | 已排除。子进程 whoami 是受害者,而非 SYSTEM(child-not-system=yes) |
在攻击者拥有的目录树内以受害者身份运行 Git / hook / credential.helper | 进程创建仍会发生;git 2.35+ safe.directory 可能失败 | 若目录树归受害者所有但攻击者可写,则以受害者身份实现 Hook RCE | 完整性 | 推断。实验未运行 Microsoft git。将路径绑定为受害者所有但攻击者可写以实现 Hook RCE |
在此 pin 上已排除:远程未认证访问(命名管道为本地)。SYSTEM shell。默认管道 ACL 仍允许 Users 进入;一个绑定客户端 SID 的修补版 register(gadget X-Patched: 1)不会为受害者自动挂载攻击者路径。
同一 pin 的其他残留:vfs-quote-breakout、vfs-mount-dehydrate、vfs-clone-acl、vfs-hook-impersonate、vfs-install-cwd。
我在 2026-09-28 合并后 pin 了 VFSForGit master ab95cf51。服务管道 ACL 为 Users ReadWrite。Register 存储 JSON OwnerSID。SessionLogon 以该 SID 自动挂载。没有任何地方模拟管道客户端。
已记录的弯路:将其称为 SYSTEM shell(自动挂载是对登录令牌的 CreateProcessAsUser);将 git safe.directory 视为 IPC 的授权;反向 shell。都是表演。缺少原生 Windows,因此实验环境是 pin 处理程序的 gadget 加上一个 Unix TCP 预言机。
python3 vfs-service-sid-Abraxas-Labs.py
或
cd lab
./run.sh
Gadget HTTP 位于 127.0.0.1:19660。见证 VFS-SERVICE-SID-WITNESS。最后一行使用 how=gadget。
SUCCESS vfs-service-sid how=gadget register-forged-sid=yes automount-as-victim=yes child-not-system=yes VFS-SERVICE-SID-WITNESS
模拟命名管道客户端(ImpersonateNamedPipeClient / NamedPipeServerStream.RunAsClient)。忽略 JSON OwnerSID;将 TryRegisterRepo 绑定到客户端 SID。将 CreatePipeByName 限制为交互式用户和 LocalSystem(移除 BuiltinUsersSid 的 ReadWrite / CreateNewInstance)。GetActiveRepoList 应仅返回该客户端的仓库。UnregisterRepo 应要求相同的 SID 匹配。
ab95cf51d6ffd0ee0e2feae7180078fe9ecbbb3aWindowsPlatform.cs Users ACL 和 {serviceName}.pipeRegisterRepoHandler.csNamedPipeMessages.cs 客户端提供的 SID 字段RepoRegistry.cs 持久化和 AutoMountReposGVFSMountProcess.cs TryRunAs(..., "mount", repoRoot, ...)GNU Affero GPL v3.0。参见 LICENSE。仅限回环实验环境。无担保。