
VFS for Git ab95cf51 - 높음 - 로컬 - 권한 잔여 - 후크 CreateFileW SecurityImpersonation
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와 dwFlagsAndAttributes = 0으로 enlistment별 마운트 파이프를 연다. 이는 SECURITY_SQOS_PRESENT를 생략하므로, Windows는 클라이언트를 기본적으로 SecurityImpersonation으로 설정한다. 잔여물 #2가 사용하는 것과 동일한 파이프 ACL이 BUILTIN\Users에게 ReadWrite | CreateNewInstance를 부여한다.
두 번째 로컬 사용자가 \\.\pipe\GVFS_<ENLISTMENT>를 추가 인스턴스로 만들거나 점거하고, ImpersonateNamedPipeClient를 호출하여 피해자로서 쓸 수 있다.
| ID | 아직 CVE 없음 |
| 분류 | 권한 잔여물 (named-pipe impersonation) |
| 도달 범위 | 로컬 |
| CWE | CWE-284, CWE-300 |
| CVSS | High: 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을 실행(VFS 훅을 발동시키는 status, checkout 등 무엇이든).
| 권한 | 메서드 / 싱크 | 부여하는 것 | 정찰 / 무결성 / 가용성 | 랩 입증 또는 추론 |
|---|---|---|---|---|
| 피해자를 임퍼소네이트하여 그들의 프로필에 쓰기 | 추가 인스턴스 / 점거 \\.\pipe\GVFS_C_\REPOS\FOO; 훅 CreateFileW flags=0; ImpersonateNamedPipeClient; %USERPROFILE%\VFS-HOOK-IMPERSONATE-WITNESS 생성 | 피해자 UID로서 쓰기 | 무결성 | 가젯에서 랩 입증. 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 디렉터리를 심어 walk-up이 다른 이름에 바인딩되게 함 | 마운트와 경쟁하지 않고 점거 | 무결성 | common.windows.cpp walk-up에서 추론. 랩은 실제 enlistment .gvfs를 사용 |
MPL뿐 아니라 DLO / PICN에도 응답 | 동일 파이프, ReadObjectHook / PostIndexChangedHook | 객체에 대해 거짓말 / skip-worktree | 무결성 | 추론. 랩은 MPL|1만 전송 |
2바이트 S\x03로 훅 크래시 | VirtualFileSystemHook messageLength -= 2 후 -= 1 언더플로우 및 fwrite ~4GiB | 크래시 / OOB 읽기 | 가용성 | main.cpp 69-90에서 추론. 오라클 아님. 그 크래시를 배포하지 말 것 |
여기서 배제: SYSTEM (마운트는 enlistment 사용자). 원격 비인증 RCE. 실제 Windows VM / 설치된 VFS for Git (이 랩은 복사된 함수들의 가젯).
동일 핀 잔여물: 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, 다른 싱크: MoveDirectory가 아닌 토큰); SYSTEM 주장; 4GiB 언더플로우를 오라클로 배포. 연극. 네이티브 Windows가 없었으므로 랩은 그 함수들의 가젯이다. Unix 소켓이 named pipe를 대신한다.
python3 vfs-hook-impersonate-Abraxas-Labs.py
또는
cd lab
./run.sh
127.0.0.1:19670에서 가젯 HTTP. 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 참조. 루프백 랩 전용. 보증 없음.