前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Windows 10 S 上的 DG:滥用 InstallUtil

Windows 10 S 上的 DG:滥用 InstallUtil

作者头像
Khan安全团队
发布2022-01-18 09:56:51
6200
发布2022-01-18 09:56:51
举报
文章被收录于专栏:Khan安全团队

将详细介绍另一个 DG 绕过,而不是禁用整个策略。在这种情况下,它利用的根本原因与我之前披露的相同,.NET 通过序列化从字节数组加载不受信任的代码,但有一个有趣的转折(*spoiler*它没有使用BinaryFormatter ,主要是)。因此,我认为披露信息并没有太大的不同。MS,或者至少是 .NET 团队(嗨,Barry),不太可能很快解决 DG 和 .NET 之间的根本不兼容问题。

是你吗,NetDataContractSerializer?

事实证明,BinaryFormatter和 .NET 远程处理太危险而无法生存,MS 最终将其从 .NET 中删除。开个玩笑,MS没有这样做。当您尝试搜索有关.NET 远程处理BinaryFormatter的文档时,MS 可能会尝试发出可怕的警告(如果有点小的话) ,但这两种技术仍然存在于 .NET 框架中,并且在使用它们时不会产生警告。事实上BinaryFormatter太棒了,它在 .NET Core 2.0 中又回来了,恕我直言,这有点可惜。

.NET Framework 3.0 版中发生的事情是引入了 Windows Communication Foundation (WCF),这是一个用于访问远程服务的新对象通信堆栈。从过去学到了很多东西,MS 选择使用 XML Web Services(很可能从过去没有学到那么好),而不是BinaryFormatter ,他们实现了一种新的序列化机制Data Contracts。WCF 数据协定的规范实现是DataContractSerializer (DCS) 类。为了使用 DCS 类进行序列化,您应该使用DataContractAttribute和DataMemberAttribute注释您的类和属性. 明确注释,数据契约并不是那么有趣,但是,显然有人认为如果有一种方法可以序列化现有的可序列化类,那就太好了。因此,DCS 还支持序列化任意类,只要它们具有SerializableAttribute注释,例如,如果您有以下 C# 类:

代码语言:javascript
复制
namespace DCSerializer {
  [Serializable]
  public class Contract {
      public int Value;
  }
}

并通过 DCS WriteObject方法运行它,您将获得以下 XML 内容:

代码语言:javascript
复制
<Contract 
    xmlns="http://schemas.datacontract.org/2004/07/DCSerializer" 
    xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
  <Value>1234</Value>
</Contract>

理论上,在没有任何特殊知识的情况下,有足够的信息来反序列化这个 XML 文件,命名空间 ( DCSerializer ) 和类名 ( Contract ) 并分别反映在默认的 XML 命名空间和根元素名称中。但是,这里缺少的是对Contract类型存在于哪个程序集中的引用。这种歧义通过要求必须在构造期间或通过解析器指定所有已知类型(某些特定系统类型之外)来解决。在一个简单的、定义良好的 Web 服务中,这不是问题。但它确实使 DCS 作为通用的、可利用的序列化程序变得不那么有用。

虽然 DCS 以自己的方式很棒,但从懒惰的开发人员的角度来看,指定所有类型的要求是一个弱点。如果您可以获得更通用的序列化程序(例如BinaryFormatter)的一些灵活性,那就太好了。这就是相似但不同的NetDataContractSerializer (NDCS) 类出现的地方。 DCS 和 NDCS(以及相关的DataContractJsonSerializer)都派生自XmlObjectSerializer类。如果您愿意,这允许 NDCS 用于 WCF 服务而不是 DCS。通过 NDCS 序列化上一个类会生成以下内容:

代码语言:javascript
复制
<Contract 
  z:Id="1" 
  z:Type="DCSerializer.Contract" 
  z:Assembly="DCSerializer, Version=1.0.0.0" 
  xmlns="http://schemas.datacontract.org/2004/07/DCSerializer" 
  xmlns:i="http://www.w3.org/2001/XMLSchema-instance" 
  xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/">
  <Value>1234</Value>
</Contract>

NDCS 的输出包括程序集信息。因此,NDCS 的工作方式与BinaryFormatter类似,因为它不需要任何关于被反序列化的类型的先验知识。这使得 NDCS 等同于BinaryFormatter但采用 XML 格式,但公平地说,.NET 已经与SoapFormatter有类似的东西。这是一种冗长的说法,如果您能找到一个将加载不受信任的 NDCS XML 文件的应用程序,那么您可以使用BinaryFormatter完全相同的序列化小工具集来利用它。因此,问题是,这样的应用程序存在吗?我们只看一个例子。

InstallUtil的方式

InstallUtil是一个预安装在 .NET Framework 中的 .NET 实用程序。该实用程序至少从 v1.1 开始可用(我没有 v1.0 的任何内容要检查)。其目的是允许您从程序集中运行安装代码,以便您可以配置系统状态并安装代码。要正常使用它,您首先定义一个派生自 Installer 类的类,使用RunInstallerAttribute注释您的类,然后实现主要的回调方法之一,例如Install。例如,以下类足以由InstallUtil执行:

代码语言:javascript
复制
[RunInstaller(true)]
public class TestInstaller : Installer {
    public override void Install(IDictionary stateSaver) {
        Console.WriteLine("Hello from the Installer");
        base.Install(stateSaver);
    }
}

如果将类编译成程序集,则可以使用以下命令行运行安装程序,它将在程序集中执行Install方法:

代码语言:javascript
复制
InstallUtil path\to\installer.dll

InstallUtil的有趣之处在于它是一个已知的应用程序白名单绕过(特别是针对 AppLocker 之类的东西)。可执行文件是 Microsoft 签名的,位于系统目录中,将执行命令行上传递的任意汇编文件中的代码。但是,它不是 DG 旁路。InstallUtil从文件加载程序集,需要在 SI 策略中允许加载该文件,这意味着对于 Win10S,我们只能加载由 Microsoft 签名的现有程序集。我们也许可以找到一个带有我们可以滥用的安装程序的程序集,但我看起来并不是很努力。不过,这并不意味着我们不能以其他方式滥用InstallUtil

如果您通过InstallUtil运行更简单的安装程序,您可能会注意到在安装程序程序集文件旁边创建了一个文件,该文件具有InstallState扩展名。该文件要求仔细检查。在文本编辑器中打开它,您会遇到看起来非常熟悉的内容:

代码语言:javascript
复制
<ArrayOfKeyValueOfanyTypeanyType 
  xmlns:i="http://www.w3.org/2001/XMLSchema-instance" 
  xmlns:x="http://www.w3.org/2001/XMLSchema" 
  z:Id="1" 
  z:Type="System.Collections.Hashtable" 
  z:Assembly="0" 
  xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/" 
  xmlns="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
...

这看起来很像 NDCS 序列化的输出。为了确认我们可以在反编译器中查看代码,参考源中似乎没有该程序集。InstallUtil实际上只是在System.Configuration.Installer程序集中实现的ManagedInstallerClass类的一个薄包装器。仔细研究了一下,我们发现AssemblyInstaller在很多地方都在使用 NDCS。我们对 NDCS 用于写出对象的地方不太感兴趣,相反,我们对它正在读取的地方更感兴趣。例如在Uninstall方法中,有以下代码

代码语言:javascript
复制
public override void Uninstall(IDictionary savedState) {
  string installStatePath = GetInstallStatePath(Path);
  if (File.Exists(installStatePath)) {
    FileStream fileStream = new FileStream(installStatePath);
    XmlReader xmlReader = XmlReader.Create(fileStream);
    var ser = new NetDataContractSerializer();
    IDictionary savedState = ser.ReadObject(xmlReader);
    
    // Run uninstaller...
    base.Uninstall(savedState);
  }  
}

从这段代码中,我们可以看到它使用不安全的 NDCS 类实例逐字加载不受信任的安装状态文件。如果我们可以说服InstallUtil加载精心设计的安装状态文件,其中包含反序列化链以从字节数组加载程序集,我们可以绕过 DG。虽然我们无法加载不受信任的程序集,但该实用程序不需要特定的程序集,因此我们可以指示它卸载诸如mscorlib之类的系统程序集。不用担心,它实际上不会做任何事情,因为mscorlib不包含任何安装程序。另外,查看文档有一个InstallStateDir我们可以传递参数来指定实用程序将在何处查找我们的安装状态。如果我们将序列化文件复制到c:\dummy\mscorlib.InstallState那么我们可以通过运行以下命令来绕过 DG:

代码语言:javascript
复制
InstallUtil /u /InstallStateDir=c:\dummy /AssemblyName mscorlib

我已经更新了我的 DG 绕过 Github存储库以包含此绕过。运行CreateInstallState实用程序,传递要加载的程序集的路径(再次实例化它找到的第一个公共类型)和输出文件名,例如mscorlib.InstallState 。执行前面的InstallUtil命令,您应该执行您的程序集。请注意,InstallUtil将在使用后尝试删除InstallState文件,如果您不希望发生这种情况,您可以在文件上设置只读标志,删除将失败。

与我在AddInProcess中披露的前一个相比,这种 DG 绕过的主要优点是它易于用于持久性。只需使用适当的命令行在启动文件夹中添加运行InstallUtil或 LNK 文件的计划任务,登录时将运行代码 DG 绕过。

最后一点,您可能想知道InstallUtil如何在框架 v4 之前序列化安装状态,特别是在 NDCS 仅在 v3.0 中引入的情况下?将 v2 System.Configuration.Installer程序集放入我们发现它使用的反编译器*drum roll* SoapFormatter中。所以它在 v2 中同样容易受到这种攻击,假设你有 v2 兼容的小工具(大多数 v2 安装确实是 v3.5,所以这通常是肯定的,因为我在上一篇文章中介绍的小工具是在 v3.0 中引入的)。

虽然这种绕过目前存在于 Win10S 中,并且可能存在于许多自定义 DG 策略中,但很容易像使用AddInProcess一样禁止InstallUtil ,这将消除绕过。我将再次为您提供一个指向 Matt Graeber 的博客文章的链接,该文章介绍了将新的可执行文件添加到您的 DG 策略中。

最后总结

我计划的Win10S系列到此结束。希望我已经证明,无论来自 Microsoft 的 PR 都不是 100% 安全的,至少对于任何知道您运行 Win10S 并愿意为您或您的组织定制攻击的人来说。DG 总会有绕过的,而 Windows 的工作方式,几乎不可能完全锁定它。如果它不是 .NET,那将是来自过长命令行参数或同样愚蠢的东西的内存损坏漏洞。

Win10S有什么价值吗?当然不是,即使不是完美的,DG 也是一种很好的方式,可以将系统限制为一组非常特定的签名可执行文件。如果 Win10S 没有成为如此透明的营销策略,而不是真正推动 Windows 平台向前发展的目标,我就不会那么怀疑了。不幸的是,如果不完全抛弃 Windows 目前为人们工作的所有原因,我就无法实现安全 Windows 平台的目标。

本文系外文翻译,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文系外文翻译前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 是你吗,NetDataContractSerializer?
  • InstallUtil的方式
  • 最后总结
相关产品与服务
文件存储
文件存储(Cloud File Storage,CFS)为您提供安全可靠、可扩展的共享文件存储服务。文件存储可与腾讯云服务器、容器服务、批量计算等服务搭配使用,为多个计算节点提供容量和性能可弹性扩展的高性能共享存储。腾讯云文件存储的管理界面简单、易使用,可实现对现有应用的无缝集成;按实际用量付费,为您节约成本,简化 IT 运维工作。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档