Windows Defender 应用程序控制 (WDAC) 和 .NET

(用高级语言(如 C#) )编写的 .NET 应用编译为中间语言 (IL) 。 IL 是一种可在任何操作系统或体系结构上支持的紧凑代码格式。 大多数 .NET 应用使用在多个环境中支持的 API,只需运行 .NET 运行时。 IL 需要编译为本机代码才能在 CPU 上执行,例如 Arm64 或 x64。 在具有 WDAC 用户模式策略的设备上将 IL 编译为本机映像 (NI) 时,它会首先检查原始 IL 文件是否通过当前 WDAC 策略。 如果是这样,.NET 会在生成的 NI 文件上设置一个 NTFS 扩展属性 (EA) ,以便 WDAC 也知道信任它。 运行 .NET 应用时,WDAC 会在 NI 文件上看到 EA 并允许它。

NI 文件上设置的 EA 仅适用于当前处于活动状态的 WDAC 策略。 如果更新了其中一个活动 WDAC 策略或应用了新策略,则 NI 上的 EA 文件将失效。 下次运行应用时,WDAC 将阻止 NI 文件。 .NET 正常处理块并回退到原始 IL 代码。 如果 IL 仍通过最新的 WDAC 策略,则应用将运行,而不会影响任何功能。 由于 IL 现在正在运行时编译,因此你可能会注意到对应用性能的轻微影响。 当 .NET 必须回退到 IL 时,.NET 还会安排一个进程,在下一个维护时段运行以重新生成所有 NI 文件,从而为通过最新 WDAC 策略的所有代码重新建立 WDAC EA。

在某些情况下,如果 NI 文件被阻止,你可能会在 CodeIntegrity - 操作 事件日志中看到“误报”阻止事件,如 WDAC 管理员提示 & 已知问题中所述。

若要缓解 WDAC EA 无效或缺失时导致的任何性能影响::

  • 避免经常更新 WDAC 策略。
  • ngen update 在) 的所有计算机体系结构上运行 (,以强制 .NET 在对 WDAC 策略应用更改后立即重新生成所有 NI 文件。
  • 将应用程序迁移到 .NET Core (.NET 6 或更高版本) 。

WDAC 和 .NET 强化

安全研究人员发现,允许应用从外部源加载库或在运行时生成新代码的一些 .NET 功能可用于规避 WDAC 控制。 为了解决此潜在漏洞,WDAC 包括一个名为 “动态代码安全性 ”的选项,该选项与 .NET 配合使用,以验证在运行时加载的代码。

启用“动态代码安全性”选项后,应用程序控制策略将应用于 .NET 从外部源加载的库。 例如,任何远程源,例如 Internet 或网络共享。

重要提示

如果启用了 UMCI 的任何 WDAC 策略已设置选项 19 Enabled:Dynamic Code Security,则会打开并强制实施 .Net 动态代码安全强化。 此功能没有审核模式。 在跨大量设备打开之前,应使用设置此选项测试应用。

此外,它还检测 .NET 生成的到磁盘的代码的篡改,并阻止加载被篡改的代码。

默认情况下未启用动态代码安全性,因为现有策略可能未考虑外部加载的库。 此外,启用了动态代码安全性时,目前不支持一些 .NET 加载功能,包括加载使用 System.Reflection.Emit 生成的未签名程序集。 Microsoft 建议先在审核模式下测试动态代码安全性,然后再强制执行动态代码安全性,以发现策略中是否应包含任何新库。

此外,客户可以预编译进行部署,以防止允许的可执行文件被终止,因为它尝试加载未签名的动态生成代码。 有关如何解决此问题,请参阅 ASP.NET 预编译概述文档中的“仅限部署的预编译 ”部分。

若要启用动态代码安全性,请将以下选项添加到 <Rules> WDAC 策略的 部分:

<Rule>
    <Option>Enabled:Dynamic Code Security</Option>
</Rule>