
VFS for Git ab95cf51 - उच्च - स्थानीय - विशेषाधिकार अवशेष - उपयोगकर्ता माउंट पाइप डिहाइड्रेट/अनमाउंट
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · vfs-mount-dehydrate
वर्ग: विशेषाधिकार अवशेष पहुँच: स्थानीय
VFS for Git master ab95cf51 (tag v2.0.26259.1) - Microsoft
प्रति-enlistment mount pipe पर CreatePipeByName BUILTIN\Users को ReadWrite | CreateNewInstance प्रदान करता है। कोई owner SID जाँच नहीं है और कोई ImpersonateNamedPipeClient नहीं है। HandleDehydrateFolders हमलावर के folder नामों को Path.Combine करता है और ProcessStartInfo.Arguments के माध्यम से git को feed करता है। CLI dehydrate पथ IsFolderValid चलाता है। mount handler नहीं चलाता।
Users में कोई भी व्यक्ति जो \\.\pipe\GVFS_<ENLISTMENT> का अनुमान लगा सकता है, ProjFS को unmount कर सकता है, mount उपयोगकर्ता के रूप में directories को स्थानांतरित कर सकता है, और git reset HEAD --hard को बाध्य कर सकता है।
| ID | अभी तक कोई CVE नहीं |
| वर्ग | विशेषाधिकार अवशेष (named-pipe ACL) / path traversal / argument injection |
| पहुँच | स्थानीय |
| CWE | CWE-284, CWE-22, CWE-88 |
| CVSS | उच्च: 7.8 CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H |
| उत्पाद | VFS for Git |
| प्रभावित | master ab95cf51d6ffd0ee0e2feae7180078fe9ecbbb3a; installer tags v2.0.26229.1 / v2.0.26259.1. केवल Windows. |
| प्रमाणीकरण | स्थानीय। कोई भी BUILTIN\Users principal जब तक पीड़ित का mount मौजूद है |
| लाइसेंस | GNU Affero GPL v3.0 |
| लैब | केवल 127.0.0.1। how=gadget (कोई Windows VM / live ProjFS नहीं)। |
Pipe प्रोटोकॉल: UTF-8 Header या Header|body, byte 0x03 द्वारा समाप्त। Pipe नाम GVFS_ + uppercase किया गया enlistment root है जिसमें : को _ से बदला गया है (उदाहरण C:\Repos\Foo -> \\.\pipe\GVFS_C_\REPOS\FOO)।
पीड़ित का gvfs mount एक ज्ञात root पर है। हमलावर उसी मशीन पर एक अन्य Users principal है। पीड़ित के रूप में integrity और availability। SYSTEM नहीं। अपने आप में shell नहीं।
| विशेषाधिकार | विधि / sink | यह क्या प्रदान करता है | Recon / integrity / availability | लैब-प्रमाणित या अनुमानित |
|---|---|---|---|---|
| पीड़ित mount pipe से कनेक्ट करें | CreatePipeByName ACL BuiltinUsers ReadWrite | CreateNewInstance; कोई owner जाँच नहीं | mount IPC से बात करें | pipe की Recon | लैब-प्रमाणित (gadget ACL)। हमलावर SID स्वीकृत; owner-only मोड connect-denied लौटाता है |
| enlistment path, cache path, RepoUrl पढ़ें | GetStatus | leftover #1 / #4 के लिए उपयोग किया गया root लीक करें | Recon | लैब-प्रमाणित। Status JSON में RepoUrl और GVFS_C_\REPOS\FOO शामिल था |
ProjFS को unmount करें और gvfs.mount से बाहर निकलें | संदेश Unmount | enlistment को नीचे गिराएँ | Availability | लैब-प्रमाणित। Ack फिर Complete का उत्तर देता है; mount स्थिति Unmounted |
| parse विफलता पर unmount | खाली body के साथ ReleaseLock -> RequestData == null -> UnmountAndStopWorkingDirectoryCallbacks + Environment.Exit | वही unmount प्लस process exit | Availability | लैब-प्रमाणित। खाली ReleaseLock| ने unmount कर दिया |
| पीड़ित working tree को त्यागें | Dehydrate|{"Folders":"--hard",...}। movedFolders.Add भले ही source dir अनुपस्थित हो। Reset("HEAD", "\"--hard\" ") quote strip के बाद git reset HEAD --hard बन जाता है | dirty tracked files को नष्ट करें | Integrity / availability | लैब-प्रमाणित। dirty tracked file ने witness string खो दिया |
| पीड़ित के रूप में worktree से folder को बाहर ले जाएँ | Path.Combine(WorkingDirectoryBackingRoot, folder) + MoveDirectory से BackupFolderPath | worktree folder को चुराएँ / स्थानांतरित करें | Integrity | लैब-प्रमाणित। keepme ने src छोड़ा और हमलावर backup path के अंतर्गत प्रकट हुआ |
.. को traverse करें (CLI IsFolderValid का उपयोग नहीं होता) | वही Combine; ..\secret | mount उपयोगकर्ता जिसे लिख सकता है उसे sibling स्थानांतरित करें | Integrity | लैब-प्रमाणित। sibling secret हमलावर backup path के अंतर्गत पहुँचा। IsFolderValid लागू करने से यह अवरुद्ध हो गया |
| अन्य पीड़ित-लेखन-योग्य directories को चुराएँ या नष्ट करें | ..\ श्रृंखला के साथ वही move जो enlistment के बाहर resolve होती है | mount उपयोगकर्ता के रूप में व्यापक move | Integrity | Combine से अनुमानित। यह लैब केवल throwaway tree का उपयोग करती है |
| पीड़ित के रूप में code exec | यह pipe | हमलावर image का process create | Integrity | बंद। इस leftover पर हमलावर image का कोई process create नहीं (देखें vfs-service-sid और vfs-hook-impersonate) |
| SYSTEM | mount IPC | LocalSystem | Integrity | बंद। Mount enlistment उपयोगकर्ता के रूप में चलता है |
--hard एक .. path नहीं है। CLI IsFolderValid अभी भी इसे अनुमति देता है। एक fix को option-जैसे folder नामों को भी अस्वीकार करना चाहिए।
समान pin leftovers: vfs-quote-breakout, vfs-clone-acl, vfs-service-sid, vfs-hook-impersonate, vfs-install-cwd.
मैंने 2026-09-28 merge के बाद VFSForGit master ab95cf51 को pin किया। service pipe और per-enlistment mount pipe CreatePipeByName साझा करते हैं। CLI पर Dehydrate folders को validate करता है। mount handler नहीं करता।
पहले से दर्ज गलत मोड़: --hard को path traversal मानना (यह quote strip के बाद argument injection है); SYSTEM का दावा करना; एक reverse shell। नाटक। Native Windows अनुपस्थित था, इसलिए लैब उन functions का gadget प्लस एक throwaway git tree है।
python3 vfs-mount-dehydrate-Abraxas-Labs.py
या
cd lab
./run.sh
127.0.0.1:19640 पर Gadget HTTP जो pipe message आकार बोलता है। container के अंदर throwaway git tree। कोई reverse shell नहीं। कोई वास्तविक profile path नहीं। अंतिम पंक्ति how=gadget का उपयोग करती है।
SUCCESS vfs-mount-dehydrate how=gadget unmount=yes reset-hard=yes dirty-gone=yes move-inside=yes move-dotdot=yes pipe-acl=users-no-owner is-folder-valid-not-on-pipe=yes VFS-MOUNT-DEHYDRATE-WITNESS
CreatePipeByName को enlistment owner SID प्लस LocalSystem तक सीमित करें। Users के लिए CreateNewInstance हटाएँ। client का impersonate करें और owner की आवश्यकता रखें। HandleDehydrateFolders में IsFolderValid को दोहराएँ और git options जैसे दिखने वाले नामों को अस्वीकार करें। ReleaseLock parse विफलता को process exit न मानें।