做网站一定要效果图吗,中企动力地址,本地网站怎么做,网站后台做的超链接打不开介绍
两年前#xff0c;微软作为Insiders build 18305的一部分发布了一项新功能- Windows Sandbox。
该沙箱具有一些有用的规格#xff1a;
Windows 10#xff08;Pro/Enterprise#xff09;的集成部分。在 Hyper-V 虚拟化上运行。原始且可抛弃 – 每次运行时都干净地开…
介绍
两年前微软作为Insiders build 18305的一部分发布了一项新功能- Windows Sandbox。
该沙箱具有一些有用的规格
Windows 10Pro/Enterprise的集成部分。在 Hyper-V 虚拟化上运行。原始且可抛弃 – 每次运行时都干净地开始并且没有持久状态。可通过具有专用格式WSB 格式的配置文件进行配置。您可以配置网络、vGPU、映射文件夹、用户登录时运行的自动脚本以及许多其他选项。该部署基于 Windows Containers 技术。
微软实现了一个重大的技术里程碑。由此产生的沙盒兼具了两方面的优点一方面沙盒基于 Hyper-V 技术这意味着它继承了 Hyper-V 严格的虚拟化安全性。另一方面沙盒包含多项功能允许与主机共享资源以减少 CPU 和内存消耗。
其中一个有趣的特征特别重要我们将在这里详细说明。
动态生成的图像
客户磁盘和文件系统是动态创建的并使用主机文件系统中的文件实现。 图 1 – 动态生成的图像来自 Microsoft 官方文档。 出于多种原因我们决定深入研究这项技术。
缺乏关于其内部技术细节的文档无论是官方文档还是社区文档。虽然它结合了两种广泛记录的技术Windows 容器和 Hyper-V但我们仍然不知道它们是如何协同工作的。例如技术博客提到了Windows 容器技术但在官方文档中Windows 容器的创建和管理是使用 Windows 的Docker实用程序完成的而 Windows Sandbox 中并未使用该实用程序。不幸的是除了调整 WSB 文件之外微软不允许对沙盒进行任何自定义。这意味着我们无法安装任何需要重新启动的程序也无法为沙盒创建自己的基础映像。
在本文中我们将分解动态图像功能的多个组件、执行流程、驱动程序支持和实现设计。我们展示了其中涉及的几种内部技术例如 NTFS 自定义重新解析标记、VHDx 分层、用于正确隔离的容器配置、虚拟存储驱动程序、VMBus 上的 vSMB 等。我们还创建了一个自定义FLARE VM沙盒用于恶意软件分析其启动时间仅为 10 秒。
通用组件
Hyper-V 及其模块的复杂生态系统已经得到了广泛的研究。发现了几个漏洞例如下一个 VmSwitch RCE它可能导致完全的客户机到主机逃逸。几年前微软推出了 Windows 容器主要用于服务器该功能允许在 Windows 上本地运行 Docker以简化软件部署。
这两项技术也以两个组件的形式引入了 Windows 10 端点平台WDAGWindows Defender 应用程序防护以及最近的Windows Sandbox。最近WDAG 和另一项令人兴奋的 Office 隔离功能合并为MDAG – Microsoft Defender 应用程序防护。
在POC2018大会上张云海做了一个演讲深入介绍了 WDAG 的架构和内部原理。正如我们所展示的Windows Sandbox 的底层实现采用了相同的技术。
沙箱可以分为三个组件两个服务——CmService.dll和vmcompute.exe——以及创建的工作进程vmwp.exe。 图 2 – Windows Sandbox 通用组件 准备沙箱
每个基于 Hyper-V 的虚拟机背后都有一个VHDx文件即机器使用的虚拟磁盘。为了了解磁盘是如何创建的我们查看了一个正在运行的沙箱的工作文件夹%PROGRAMDATA%\Microsoft\Windows\Containers。令人惊讶的是我们发现了 8 个以上的 VHDx 文件。 图 3 – 工作文件夹结构。 我们可以通过下一个路径中的动态大小来跟踪主 VHDx 文件 –Sandboxes\29af2772-55f9-4540-970f-9a7a9a6387e4\sandbox.vhdx其中 GUID 是在每次沙盒运行时随机生成的。
当我们手动挂载 VHDx 文件时我们发现它的大部分文件系统都丢失了这种现象在前面提到的张的 WDAG 研究中也能看到。 图 4 – 安装的沙盒 VHDx。 我们可以立即看到文件夹图标上的“ X ”符号。如果我们打开文件资源管理器中的“属性”列我们可以看到两个不寻常的 NTFS 属性。这些解释如下
O——离线
L——重新解析点
重新解析点是 NTFS 的一个扩展允许它创建指向另一条路径的“链接”。它还在其他功能中发挥作用例如卷安装。在我们的例子中使用此功能是有意义的因为大多数文件并非“物理”存在于 VHDx 文件中。
为了了解重新解析指向的位置以及其中的内容我们深入研究了 NTFS 结构。
解析MFT记录
主文件表( MFT) 存储从 NTFS 分区检索文件所需的信息。一个文件可能有一个或多个 MFT 记录并且可以包含一个或多个属性。我们可以运行流行的取证工具Volatility并可以mftparser选择解析底层文件系统中的所有 MFT 记录。这可以使用以下命令行完成
volatility.exe -f sandbox.vhdx mftparser --outputbody -D output --output-filesandbox.body
当我们kernel32.dll在输出中搜索示例系统文件记录时我们遇到以下文本 0| [ MFT FILE_NAME ] Windows\System32\kernel32. dll 偏移量0x3538c00 | 1251 |---a---S--o----| 0 | 0 | 764456 | 1604310972 | 1596874670 | 1603021550 | 1596874670 0 | [ MFT STD_INFO ] Windows\System32\kernel32. dll 偏移量0x3538c00 | 1251 |---a---Sr-o----| 0 | 0 | 764456 | 1606900209 | 1596874670 | 1603021550 | 1596874670
我们可以看到与之前类似的重新解析“ S ”和离线“ o0x3538c00 ”属性但 Volatility 没有提供任何其他信息。我们可以使用 MFT 记录的偏移量来启动我们自己的手动解析。
我们使用下一个 NTFS 文档来执行解析过程。我们没有提供 MFT 格式的完整规范但简单地说MFT 记录包含可变数量的属性每个属性都有自己的标头和有效负载。我们正在寻找$REPARSE_POINT由序数 标识的属性0xC0。 图 5 – MFT 属性头结构。 图 6 –$REPARSE_POINT属性有效载荷结构。 我们对上面列出的结构进行解析得到以下数据 $REPARSE_POINT 属性 --------------- 属性标题 --------------- C0 00 00 00 -类型$REPARSE_POINT 78 00 00 00 - 长度 00—— 非居民旗帜 00—— 名称长度 00 00 - 名称偏移量 00 00—— 旗帜 03 00 - 属性ID a 5C 00 00 00 -属性的长度 18 00 - 属性偏移量 00—— 索引标志 00—— 填充 ---------------- 属性数据 ---------------- 18 10 00 90 - 重新解析标签 54 00 - 重新解析数据长度 00 00—— 填充 ----------------- 重新解析数据 ----------------- 01 00 00 00-版本 00 00 00 00——保留 77 F6 64 82 B0 40 A5 4C BF 9A 94 4A C2 DA 80 87 - 参考 GUID 3A 00 - 路径字符串大小 57 00 69 00 6E 00 64 00 6F 00 77 00 73 00 5C 00 53 00 79 00 73 00 74 00 65 00 6D 00 33 00 32 00 5C 00 6B 00 65 00 72 00 6E 00 65 00 6C 00 33 00 32 00 2E 00 64 00 6C 00 6C 00 - 路径字符串
一些重要说明
我们没有找到有关微软重新解析数据结构的任何公开文档但进行逆向工程并不太难。重新解析标签在此处0x90001018定义如下IO_REPARSE_TAG_WCI_1
“由 Windows 容器隔离过滤器使用。仅供服务器端解释无意义。”
在这项研究中对 Windows 模块进行逆向工程时我们多次发现引用的 GUID77 F6 64 82 B0 40 A5 4C BF 9A 94 4A C2 DA 80 87是硬编码值。此值表示对主机基础层的引用我们稍后会讨论它。重新解析数据中的路径显示了我们的示例文件的相对路径Windows\System32\kernel32.dll
根据以上信息我们可以得出结论文件是由底层文件系统“链接”的可能是链接到指定的 FS 过滤器但许多问题仍然没有答案VHDx 是如何构建的其他 VHDx 的用途是什么以及哪个组件负责链接到主机文件。
VHDx 分层
如果我们在沙箱创建期间跟踪Procmon日志我们会注意到一系列 VHDx 访问尝试 图 7 – VHDx 分层引线。 虽然第一个是我们之前解析过的“真实” VHDx但后面还有 3 个其他 VHDx 访问。我们怀疑 Microsoft 对虚拟磁盘模板使用了某种分层。
通过使用二进制编辑器检查 VHDx 文件可以轻松验证我们的理论 图 8 – parent_linkage010 编辑器中的标签。 VHDx 格式的父定位器可以使用多种方法给出绝对路径、相对路径和卷路径。文档可在此处找到。
有了这些知识我们可以构建下一层
Sandboxes\new_sandbox_guid\sandbox.vhdx– “真正的” VHDx。Sandboxes\constant_guid_per_installation\sandbox.vhdx– 每个沙箱安装创建一次。BaseImages\0949cec7-8165-4167-8c7d-67cf14eeede0\Snapshot\SnapshotSandbox.vhdx– 可能与基础层快照相关。PortableBaseLayer\SystemTemplateBase.vhdx– 基础模板。
当我们浏览这些虚拟磁盘时我们注意到文件仍然丢失一些系统文件夹是空的以及用户/程序文件和其他各种文件的文件夹。
使用 Procmon 让我们了解到缺少另一个重要层操作系统基础层。
操作系统基础层
操作系统基础层主文件位于下一个路径的沙盒工作文件夹中BaseImages\0949cec7-8165-4167-8c7d-67cf14eeede0\BaseLayer.vhdx。通过 Procmon 查看安装过程我们可以看到下一个.wimWindows 映像格式文件C:\Windows\Containers\serviced\WindowsDefenderApplicationGuard.wim被提取到PortableBaseLayer同名文件夹中并被复制并重命名到上面的基础层文件中。这又显示了 WDAG 和 Windows Sandbox 之间的另一个相似之处。
当我们浏览BaseLayer.vhdx磁盘时我们可以看到创建的沙箱的完整结构但系统文件仍然“物理”缺失。像kernel32.dll我们之前所做的那样解析 MFT 记录会产生相同的$REPARSE_POINT属性但标签不同0xA0001027。IO_REPARSE_TAG_WCI_LINK_1记住这个标签以备后用。 图 9 – 基础层用户文件夹。 此外当我们运行mountvol命令时我们会看到基础层 VHDx 被挂载到其所在的同一目录中 图 10 – 已安装的操作系统基础层。 负责安装该卷的服务以及我们到目前为止提到的所有功能都是容器管理服务 CmService.dll。
此服务运行一个名为的可执行文件cmimageworker.exe并使用下一个命令行参数之一expandpbl/deploy/clean来执行这些操作。 图 11 —CmService基础层创建。 computestorage!HcsSetupBaseOSLayer我们可以在 中观察到对 的调用cmimageworker.exe以及在 中基础层的实际创建部分computestorage.dll。 图 12 –cmimageworker!Container::Manager::Hcs::ProcessImage启动基础层创建。 图 13 – 中基础层创建的一部分computestorage!OsImageUtilities::ProcessOsLayer。 微软就沙盒发表了以下声明
Windows 的一部分– 此功能所需的一切都随 Windows 10 Pro 和 Enterprise 一起提供。无需下载 VHD
到目前为止我们了解了有关该功能的关键实现细节。让我们继续看看容器是如何执行的。
运行沙盒
运行 Windows Sandbox 应用程序会触发执行流程我们在此不再赘述。我们只提到该流程通过 RPC 调用导致CmService执行。另一项关键服务运行并协调主机上的所有计算系统容器。vmcompute!HcsRpc_CreateSystemvmcompute.exe
在我们的例子中CreateSystem命令还接收描述所需机器的下一个配置 JSON
注意为了便于阅读JSON 已被截断。您可以在附录 A中查看完整的 JSON 。 { “所有者” “马德里” ... “虚拟机” { ... “设备” { “Scsi” { “基本的” { “附件” { 0 { “类型” “虚拟磁盘” “路径” “C:\\ProgramData\\Microsoft\\Windows\\Containers\\Sandboxes\\025b00c8-849a-4e00-bcb2-c2b8ec698bab\\sandbox.vhdx” ... } } } } ... “虚拟Smb” { “分享” [{ “名称” “os” “路径” “C:\\ProgramData\\Microsoft\\Windows\\Containers\\BaseImages\\0949cec7-8165-4167-8c7d-67cf14eeede0\\BaseLayer\\Files” ... }] } ... } ... “运行在Silo” { “SiloBaseOsPath” “C:\ProgramData\Microsoft\Windows\Containers\BaseImages\0949cec7-8165-4167-8c7d-67cf14eeede0\BaseLayer\Files” “通知SiloJob创建” true 文件系统层 : [{ “ID” “8264f677-40b0-4ca5-bf9a-944ac2da8087” 路径 “C:\\” “路径类型” “绝对路径” }] } ... } ... }
此 JSON 是在 处创建的CmService!Container::Manager::Hcs::Details::GenerateCreateComputeSystemJson。我们未能追踪任何有助于构建该配置的文件。
在开始分析 JSON 中有趣的字段之前我们想提一下 Palo Alto Networks 的这篇文章。该文章解释了容器内部结构以及Job和Silo对象之间的关系。
第一个有趣的配置标签是RunInSilo。此标签触发代码流vmcompute引导我们进入下一个堆栈跟踪 3 kd k # Child-SP ReAddr 调用站点 00 ffff9a008da57648 fffff80685d2b7fb wcifs!WcPortMessage 01 ffff9a008da57650 fffff80685d63499 FLTMGR!FltpFilterMessage 0xdb ... 减少 0b 0000004d4218dbf0 00007ffa08c5363d FLTLIBFilterSendMessage 0x31 0c 0000004d4218dc40 00007ffa08c48686 wc_storage!WciSetupFilter 0x195 0d 0000004d4218dcf0 00007ffa 22e06496 wc_storage!WcAttachFilterEx 0x156 0e 0000004d4218dee0 00007ffa22de5a66 容器容器::FilesystemProvider::Setup 0x15e 0f 0000004d4218dfc0 00007ffa22ded4ad 容器container_runtime::CreateContainerObject 0x106 10 0000004d 4218e010 00007ffa22decf3c 容器容器::CreateContainer 0x10d 11 0000004d 4218e4 a0 00007ff6fcf0bc7f 容器WcCreateContainer 0x1c 12 0000004d 4218e4 d0 00007ff6fcf0c5c4 vmcompute计算服务::JobUtilities::ConvertJobObjectToContainer 0xcb 13 0000004d 4218e590 00007ff6fce8573f vmcomputeComputeService::JobUtilities::CreateSiloForIsolatedWorkerProcess 0x4dc 14 0000004d 4218e8 c0 00007ff6fce875c5 vmcomputeComputeService::Management::Details::PrepareJobForWorkerProcess 0x17b 15 0000004d 4218e9 a0 00007ff6fcee6cbb vmcompute计算服务::管理::详细信息::ConstructVmWorker 0xfd5 ... 减少
从堆栈中我们可以了解到每当计算系统收到 Silo 配置时它都会通过调用创建并配置一个容器container!WcCreateContainer。作为其配置的一部分它还wcifs.sys通过 与驱动程序进行通信FLTLIB!FilterSendMessage。我们简要介绍一下这个驱动程序及其用途。
第二个有趣的特性是VirtualSmb用于为之前提到的已安装基础层路径创建相应共享的标签。我们稍后也会讨论这一点。
容器隔离
从堆栈跟踪中我们可以看到容器创建包括\WcifsPort使用wcifs.sys驱动程序Windows Container Isolation FS Filter Driver打开端口上的过滤器通信通道。这是用户模式代码与过滤器驱动程序通信的 常用方法。
此微过滤驱动程序在容器文件系统虚拟化的实现中起着重要作用。此驱动程序在客户机和主机中都充当此角色。
文件系统过滤驱动程序通常非常复杂这个也不例外。幸运的是 Google Project Zero 的James Forshaw最近写了一篇很棒的文章解释了 Windows FS 过滤驱动程序的低级设计这有助于我们理解我们案例中的逻辑。
我们可以将驱动逻辑分为两部分
驱动程序配置——配置取决于驱动程序是在客户机还是主机系统上运行。处理操作回调例如WcPreCreate、WcPostCreate、WcPreRead和WcPostRead。这些回调包含主要逻辑、数据操作和适当的重定向。
我们将解释该驱动程序用来了解沙盒生态系统的一些方法。
初始配置
来宾配置
正如我们之前所说主机和客户机都使用该驱动程序但方式不同。
客户机通过注册表接收一组参数用于其初始配置。其中一些参数位于HKLM\SYSTEM\CurrentControlSet\Control如下HKLM\SYSTEM\CurrentControlSet\Control\BootContainer所示 图 14 –HKLM\SYSTEM\CurrentControlSet\Control配置值。 图 15 –HKLM\SYSTEM\CurrentControlSet\Control\BootContainer配置值。 您可能会注意到我们之前在“真实” VHDx 文件中看到的IO_REPARSE_TAG_WCI_1代码。此标记与我们在中看到的重新解析标记一起被硬编码到方法中0x90001018IO_REPARSE_TAG_WCI_LINK_1BaseLayer.vhdxwcifs!WcSetBootConfiguration 图 16 – 中的硬编码重新解析标签值WcSetBootConfiguration。 客户机配置的第二个更重要的部分是wcifs!WcSetupVsmbUnionContext它在其中设置了一个称为Union ContextFltGetInstanceContext的虚拟化层。在后台驱动程序将自定义数据存储在多个上下文对象上并使用适当的 NT API 、PsGetSiloContext和 访问它们FltGetFileContext。这些自定义对象包含 AVL 树和哈希表以高效查找虚拟化层。
该WcSetupVsmbUnionContext方法还有两个有趣的工件。一个是属于层的 vSMB 路径另一个是HOST_LAYER_ID我们之前在解析的 MFT 和描述虚拟机的 JSON 中看到的 GUID 图 17 – 中的硬编码 vSMB 路径WcSetupVsmbUnionContext。 图 18 – 的硬编码 GUID HOST_LAYER_ID。 随着我们深入研究我们发现有迹象表明虚拟 SMB方法用于在客户机和主机之间共享文件。很快我们就会发现 vSMB 是基础层实现和映射文件夹共享的主要方法。
主机配置
对于主机系统主要配置发生在父计算进程vmcompute启动容器创建并向发送自定义消息时\WcifsPort。这会触发wcifs!WcPortMessage发送到该特定端口的任何消息的回调例程。
下面是服务向过滤驱动发送的消息的部分重构 WcifsPortMsg结构 { DWORD 消息代码 DWORD 消息大小 WcifsPortMsgSetUnion 消息 }
WcifsPortMsgSetUnion结构 { DWORD 消息版本或代码 DWORD 消息大小 DWORD 数字联合 wchar_t 实例名称[ 50 ] ; DWORD 实例名称长度 DWORD 重新解析标签 DWORD 重新解析标签链接 DWORD 不确定 处理工作 BYTE 上下文数据[ 1 ] }
该ContextData字段还包含联合应映射的设备路径。
操作回调
在注册期间过滤驱动程序会为其想要拦截的每项操作提供一组回调。过滤管理器会在每项文件操作之前/之后调用这些回调如下所示。 图 19 –迷你过滤器架构由James Forshaw提供。 无需过多探讨技术细节驱动程序定义并处理两个自定义重新解析标签
IO_REPARSE_TAG_WCI_1 – 这是指示磁盘上的文件实例是虚拟的真实路径可以在其内部结构中找到的主要标记。此“转换”的示例用法如下 客户机将文件从其本机路径转换C:\Windows\system32\kernel32.dll为 vSMB 路径\Device\vmsmb\VSMB-{dcc079ae-60ba-4d07-847c-3493609c0870}\os\Windows\System32\kernel32.dll。主机将文件从基础层设备路径转换C:\ProgramData\Microsoft\Windows\Containers\BaseImages\0949cec7-8165-4167-8c7d-67cf14eeede0\BaseLayer\Files\Windows\System32\en-US\apphelp.dll.mui为真实路径C:\Windows\System32\en-US\apphelp.dll.mui。 这种转换非常有趣因为它主要发生在基础层中包含此重新解析标记的空系统文件夹中例如文件en-US夹。IO_REPARSE_TAG_WCI_LINK_1 – 据我们所知此标签仅在主机上使用并将系统文件从基础层设备路径链接C:\ProgramData\Microsoft\Windows\Containers\BaseImages\0949cec7-8165-4167-8c7d-67cf14eeede0\BaseLayer\Files\Windows\System32\kernel32.dll到真实路径C:\Windows\System32\kernel32.dll。与上一点相比此示例 DLL 文件条目确实存在于基础层中并且具有此重新解析标签。
发现 vSMB 是操作系统基础层共享的主要方法这令人颇感意外。既然我们知道它是生态系统中一种至关重要的通信方法那么下一步自然就是进一步深入挖掘。
vSMB 文件共享
在沙盒安装过程中我们注意到通过调用存储提供程序设备vmcompute创建了多个虚拟共享并发送了 IOCTL 。此类调用的示例路径可能如下所示。CreateFileW0x240328\??\STORVSP\VSMB\??\C:\ProgramData\Microsoft\Windows\Containers\BaseImages\0949cec7-8165-4167-8c7d-67cf14eeede0\BaseLayer\Files
创建这些共享的方法是vmcompute!ComputeService::Storage::OpenVsmbRootShare。我们可以在下一个堆栈跟踪中看到它的流程 3 kd k # Child-SP ReAddr 调用站点 00 ffff9a008d48a178 fffff80685fd6af8 storvsp!VspFileCreate 01 内联函数---------------- Wdf01000FxFileObjectFileCreate::Invoke 0x29 [ minkernel\wdf\framework\shared\inc\private\common\ FxFileObjectCallbacks.hpp 58 ] ... 减少 11 0000004d4210d690 00007ff6fcf33700 KERNELBASE!CreateFileW 0x66 12 0000004d4210d6f0 00007ff6fceb8180 vmcompute计算服务::存储::OpenVsmbRootShare 0x3ac 13 0000004d4210d850 00007ff6fceba0fc vmcompute计算服务::虚拟机::详细信息::配置VSMB 0x598 14 0000004d4210da30 00007ff6fceba908 vmcompute计算服务::虚拟机::详细信息::初始化设备设置 0x918 15 0000004d4210eb90 00007ff6fce86abd vmcompute计算服务::虚拟机::创建虚拟机配置 0x68 16 0000004d4210ebe0 00007ff6fcee6cbb vmcompute计算服务::管理::详细信息::ConstructVmWorker 0x4cd ... 减少
此外当我们使用 WSB 文件配置将主机文件夹映射到客户机时也会调用相同的方法。例如映射Sysinternals文件夹会导致对驱动程序的下一个调用\??\STORVSP\VSMB\??\C:\Users\hyperv-root\Desktop\SysinternalsSuite。
通过 (v)SMB 访问文件
创建这些共享后我们可以通过创建的别名在客户机中访问它们。我们可以使用该type命令打印kernel32.dll主机的以下路径\\.\vmsmb\VSMB-{dcc079ae-60ba-4d07-847c-3493609c0870}\os\Windows\System32\kernel32.dll 图 20 – 访问 vSMB 共享。 为了提供 vSMB 文件vmusrv作为 VM 工作进程一部分的模块会创建一个工作线程。该模块是一个用户模式 vSMB 服务器它在例程中直接从 VMBus 请求数据包vmusrv!VSmbpWorkerRecvLoop然后继续处理这些数据包。
服务创建文件操作
每当vmusrv收到创建SMB 请求时它都会向存储提供程序驱动程序发起新请求。这样的调用可能如下所示 2kd k # Child-SP ReAddr 调用站点 ... 减少 0c ffff9a008d9522e0 fffff806892c4741 storvsp!VspVsmbCommonRelativeCreate 0x369 0d ffff9a008d952510 fffff806892c3b7e storvsp!VspVsmbHandleRelativeCreateFileRequest 0x321 0e ffff9a008d952790 fffff806892c0f85 storvsp!VspVsmbDispatchIoControlForProcess 0x11e 0f ffff9a008d9527e0 fffff806 8100e522 storvsp!VspFastIoDeviceControl 0x175 ... 减少 13 000000ae9c0ff298 00007ffa110c0c0a ntdll!NtDeviceIoControlFile 0x14 14 000000ae9c0ff2a0 00007ffa110c0456 vmusrv!CShare::OpenFileRelativeToShareRootInternal 0x306 15 000000ae9c0ff3e0 00007ffa110b9381 vmusrv!CShare::OpenFileRelativeToShareRoot 0x356 16 000000ae9c0ff510 00007ffa110b4451 vmusrv!CFSObject::CreateFileW 0x185 17 000000ae9c0ff690 00007ffa1109a568 vmusrv!CShare::创建 0x91 18 000000ae9c0ff740 00007ffa1109d74d vmusrvProviderCallback_Create 0x30 19 000000ae9c0ff780 00007ffa1109c299 vmusrv!SrvCreateFile 0x331 1a 000000ae9c0ff860 00007ffa1109c6f0 vmusrv!Smb2ExecuteCreateReal 0x111 1b 000000ae9c0ff940 00007ffa110a08da vmusrv!Smb2ExecuteCreate 0x30 1c 000000ae9c0ff970 00007ffa 11098907 vmusrv!Smb2ExecuteProviderCallback 0x7e 1d 000000ae9c0ff9d0 00007ffa 11088311 vmusrv!Smb2PacketProcessing 0x97 1e 000000ae9c0ffa40 00007ffa 11087225 vmusrvSmb2PacketProcessingCallback 0x11 ... 减少
与存储提供程序的通信是通过代码中的IOCTL完成的0x240320而引用的句柄是在初始化阶段打开的vSMB路径 图 21 – 引用 IOCTL 的句柄。 如果我们仔细观察storvsp!VspVsmbCommonRelativeCreate就会发现每次执行后都会调用nt!IoCreateFileEx。此调用包含所需文件的相对路径以及一个附加RootDirectory字段该字段表示\Files已安装的基础层 VHDx 中的文件夹 IoCrateFileEx图22 – 执行storvsp.sys。 提供读/写操作
中的工作线程执行读/写操作vmusrv!CFSObject::Read/vmusrv!CFSObject::Write。如果文件足够小线程只需ReadFile/WriteFile在句柄上执行。否则它将文件映射到内存并通过VMBus 上的RDMAvmusrv!SrvConnectionExecuteRdmaTransfer高效传输。此传输在 执行而 RDMA 通信是使用 IOCTL或 与RootVMBus设备主机 VMBus 设备名称进行的。0x3EC0D30x3EC08C 2kd k ... 减少 06 ffffad0e3bee7650 fffff80036225b62 vmbusrRootIoctlRdmaFileIoHandleMappingComplete 0x10f 07 ffffad0e3bee7690 fffff800361fee21 vmbusrRootIoctlRdmaFileIo 0xf2 08 ffffad0e3bee76f0 fffff800339da977 vmbusrRootIoctlDeviceControlPreprocess 0x191 ... 减少 12 00000009 ae27f7e8 00007ffe281ce773 ntdll!NtDeviceIoControlFile 0x14 13 00000009 ae27f7f0 00007ffe281dcbd2 vmusrv!SrvConnectionExecuteRdmaTransfer 0x24f 14 00000009 ae27f940 00007ffe281d4874 vmusrv!CFile::ReadFileRdma 0xc2 15 00000009 ae27f9c0 00007ffe281c218e vmusrv!CFSObject::Read 0x94 16 00000009 ae27fa00 00007ffe281c08da vmusrv!Smb2ExecuteRead 0x1be 17 00000009 ae27fa60 00007ffe281b8907 vmusrv!Smb2ExecuteProviderCallback 0x7e 18 00000009 ae27fac0 00007ffe281a6a4e vmusrv!Smb2PacketProcessing 0x97 19 00000009 ae27fb30 00007ffe3bba6fd4 vmusrv!SmbWorkerThread 0xce ... 减少 图 23\Device\RootVmBus\rdma\494 –读/写操作的通信。 访客到主人的流程
根据本文解释关系的一些见解我们Storvsc.sys/Storvsp.sys可以将所有先前的技术块结合到下一个文件访问流中。 图 24 – 文件访问流程。 我们用命令type打开并打印文件内容kernel32.dll。这是一个系统文件因此沙盒不拥有它的副本而是使用主机的副本。客户机不知道该文件不存在因此它通过文件系统驱动程序堆栈直到存储驱动程序堆栈执行正常的文件访问。Hyper-V 存储消费者Storvsc.sys是一个微型端口驱动程序这意味着它充当来宾的虚拟存储。它通过 VMBus 接收和转发 SCSI 请求。存储提供程序Storvsp.sys有一个工作线程正在通过 VMBus 监听新消息storvsp!VspPvtKmclProcessingComplete。提供程序解析 VMBus 请求并将其传递给vhdparser!NVhdParserExecuteScsiRequestDisk执行vhdmp.sysVHD 解析器驱动程序。最后通过过滤管理器vhdmp.sys访问的物理实例sandbox.vhdx并执行读/写操作。在这种情况下它读取客户文件系统过滤管理器请求的数据。该数据返回给过滤管理器进行进一步分析。如前所述返回的条目带有 WCI 重解析标记和主机层 GUID。在wcifs.sys对文件执行创建后操作时它会查找该设备的联合上下文并用下一个文件对象替换该文件对象\Device\vmsmb\VSMB-{dcc079ae-60ba-4d07-847c-3493609c0870}\os\Windows\System32\kernel32.dll该\Device\vmsmb设备被创建为 SMB 共享因此筛选器管理器可以像访问任何其他普通共享一样访问它。在后台它通过 VMBus 向主机执行 SMB 请求。vSMB 用户模式服务器在其工作线程方法中vmusrv.dll轮询\\.\VMbus\设备以获取新消息vmusrv!SmbWorkerThread。正如我们之前所展示的在创建操作中服务器通过已安装的 OS 基础层的句柄上的 IOCTL 与存储提供程序进行通信\Device\STORVSP\VSMB\??\C:\ProgramData\Microsoft\Windows\Containers\BaseImages\0949cec7-8165-4167-8c7d-67cf14eeede0\BaseLayer\Files存储提供程序通过 执行文件请求IoCreateFileEx。该请求是相对的并且包含RootDirectory已安装操作系统层的 。这会触发筛选器管理器在已安装操作系统层中打开文件。与步骤(7)类似返回的条目包含 WCI 重解析标记这会导致wcifs.sys在 post-create 方法中更改文件对象。它将文件对象更改为其物理路径C:\Windows\System32\kernel32.dll访问主机kernel32.dll文件并返回给客户机。对于ReadFile操作wcifs.sys驱动程序会在文件对象顶部保存上下文状态以帮助其执行读/写操作。此外工作线程vmusrv要么直接访问文件要么通过 VMBus 顶部的 RDMA 执行读取请求。
实际过程要复杂得多因此我们试图专注于虚拟化的关键组件。
沙盒还允许通过其配置将文件夹从主机映射到客户机。此类文件夹会收到 vSMB 路径的唯一别名并且访问方式与 OS 层类似。唯一的区别是路径在客户机过滤器管理器中由 更改bindflt.sys。
例如如果我们将SysinternalsSuite文件夹映射到客户机桌面文件夹则路径C:\Users\WDAGUtilityAccount\Desktop\SysinternalsSuite\Procmon.exe将更改为\Device\vmsmb\VSMB-{dcc079ae-60ba-4d07-847c-3493609c0870}\db64085bcd96aab59430e21d1b386e1b37b53a7194240ce5e3c25a7636076b67\Procmon.exe而其余过程保持不变。
玩沙盒
这项研究的目标之一是根据我们的需求修改基础层内容。现在我们了解了生态系统这似乎相当容易。
修改有几个简单的步骤
停止CmService创建并维护基础层的服务。当服务卸载时也会移除基础层的挂载。安装基础层它在C:\ProgramData\Microsoft\Windows\Containers\BaseImages\0949cec7-8165-4167-8c7d-67cf14eeede0\BaseLayer.vhdx文件中。这可以通过双击或使用diskmgmt.msc实用程序来完成。对基础层进行修改。在我们的例子中我们添加了所有 FLARE 安装后文件。卸下基础层。开始CmService。
当我们启动沙箱时我们就有了超棒的 FLARE VM 图 25 – Windows Sandbox 上的 FLARE VM。 概括
当我们开始研究 Windows Sandbox 时我们并不知道这样一个“简单”的操作会归结为一个复杂的流程其中包含多项 Microsoft 内部未记录的技术例如 vSMB 和容器隔离。
链接
Hyper-V VmSwitch RCE 漏洞
https://www.youtube.com/watch?v025r8_TrV8I
Windows 沙盒
Windows Sandbox - Microsoft Community Hub
Windows 沙盒 WSB 配置
Windows Sandbox configuration - Windows Security | Microsoft Learn
Windows 容器
About Windows containers | Microsoft LearnWhat I Learned from Reverse Engineering Windows Containers
NTFS 属性
SOLVED: All NTFS Attributes Defined – Up Running Inc – Tech How Tos
重新解析点
Reparse Points - Win32 apps | Microsoft Learn
NTFS 文档
http://dubeyko.com/development/FileSystems/NTFS/ntfsdoc.pdf
NTFS 重新解析标签
[MS-FSCC]: Reparse Tags | Microsoft Learn
VHDx 父级定位器
[MS-VHDX]: VHDX Parent Locator | Microsoft Learn
FS 过滤驱动 – 用户态与内核态之间的通信
https://docs.microsoft.com/en-us/windows-hardware/drivers/ifs/communication- Between-user-mode-and-kernel-mode
寻找 Windows Mini-Filter 驱动程序中的错误
https://googleprojectzero.blogspot.com/2021/01/hunting-for-bugs-in-windows-mini-filter.html
Hyper-V Storvsp.sys-Strovsc.sys 流程
https://www.linkedin.com/pulse/hyper-v-architecture-internals-pravin-gatale/
微软对 RDMA 的解释
Host network requirements for Azure Stack HCI - Azure Stack HCI | Microsoft Learn