硬件虚拟化系统中的非特权进程能否在没有内核合作的情况下导致“VMExit”?

信息安全 虚拟化 沙盒
2021-08-14 18:17:36

对于 SVM 或 VT-x,触发vmexit虚拟机监视器的一组条件非常复杂。如果没有内核的帮助,非特权进程可以触发其中任何一个吗?VMMCALL的文档VMCALL都说它们只在环 0 中工作,所以我认为它们没问题。

这是Ninefinger前几天出色回应的后续问题。那里的细节太多了,我花了一段时间才吸收。:)

2个回答

您需要了解说明的是英特尔软件开发人员手册对于它的价值,我有时会发现它们有点不透明——所以我对比了我在谷歌和 AMD 手册中读到的内容,因为它们都实现了 x86/x64 架构。

具体来说,为此您需要第 3C 卷:虚拟化从当前手册开始,您需要第 293 页(“VMCALL — 调用 VM 监视器”)。在那里,你有这个有用的表达:

IF not in VMX operation
    THEN #UD;
ELSIF in VMX non-root operation
    THEN VM exit;
ELSIF (RFLAGS.VM = 1) or (IA32_EFER.LMA = 1 and CS.L = 0)
    THEN #UD;
ELSIF CPL > 0
    THEN #GP(0);
...

翻译成英文:#GP是一般保护异常,CPL是当前的特权级别。VMX 非 root 操作是:

VMX 操作有两种:VMX 根操作和 VMX 非根操作。通常,VMM 将以 VMX 根操作运行,来宾软件将以 VMX 非根操作运行。

因此,这意味着VMCall可以从guest 的任何特权级别发出指令。环 0 要求仅适用于主机系统。但是,我用免责声明警告这一点 - 请稍后查看我的含义要点。

疯狂的疯狂我知道。然而,显然,这是真的。阅读这个线程,KVM 内核开发人员正在讨论这个问题。有问题的 KVM 补丁是这样做的:

kvm_get_segment(vcpu,&cs, VCPU_SREG_CS);
if (cs.dpl != 0) {
    ret = -KVM_EPERM;
    goto out;
}

如果不是从访客环 0 发出的,它认为“超级呼叫”无效。

影响:

  1. 任何客人级别的代码都可以发出VMCall. 但是,从我所做的非常初步的阅读来看,它似乎(可能)不可能以任何方式有用 - 因为环 3 地址可能是虚拟的客户操作系统(因此没有任何意义主人)。我强烈怀疑是这种情况,但我(还)不能确认。
  2. 如果您考虑一下,这是有道理的——如果客人级别的代码触发了其他类型的 VM 退出,您希望 VMM 接管。
  3. 但是,我怀疑许多虚拟机管理程序实现了上述限制 - 仅环 0 来宾,或者它们应用的超级调用 API 上的一些其他条件。
  4. 但是,他们可能不会。

因此,如果您真的想深入研究它,您需要做的是验证:

  • 您的 VMM 支持哪些超级调用(如果有)。
  • 他们认为超级调用有效的条件。正如我所说,我预计VMCall将仅限于访客环 0。

如果VMCallet al 只能从 ring 0 有意义地执行,那么您的客户端客户代码也必须能够在 ring 0 中执行,或者说服您现有的一些代码做一些不应该做的事情。例如:

  1. 你可以说服内核执行任意一段包含 的代码VMCall来做你想做的任何事情。
  2. 您说服现有驱动程序使用 aVMCall以您的方式进行调用,即使用您的参数,而不是通常使用的参数。

漏洞利用的成功完全取决于管理程序以及这些 VMCall 是否易受攻击。如果它们不是,那么您是否设法调用它们并不重要 - 管理程序可以酌情拒绝它们。在这一点上,老实说,我认为这种利用路线(通过 a VMCall)不太可能(尽管如果有的话,后果当然会非常严重)。

我在这里错过了两件事:

  • VM 退出还有许多其他触发器。来宾进程会导致它们吗?不是以编程方式我不认为 - 它们发生是因为客人正在做的事情(VMM 提供的退出条件),而不是直接响应操作码。
  • 同样,VM 的“爆发”是一个松散的术语。虚拟机的用户还应该警惕网络仿真之类的事情——如果你的客户和主机可以通过 TCP/IP 相互通信,并且你的主机 IP 堆栈中存在漏洞并且客户上的代码可以利用它——你仍然可以被妥协。同样,将文件从客户机传输到主机也存在固有风险。

是的,非特权访客代码可以触发 VM 退出。

然而,这并不意味着非特权的来宾代码可以突破虚拟机。当触发 VM 退出时,控制权转移到虚拟机监视器的代码。如果 VMM 代码编写正确,它负责安全地处理 VM 退出:特别是,以不允许恶意来宾代码从 VM 中突围的方式。

请注意,“VM 退出”是一个技术术语,是指将控制权转移到 VMM。尽管使用了“退出”这个词,但这并不意味着来宾代码可以突破虚拟机。它指的是一种调用 VMM 的方式,而不是某种安全漏洞。如果 VMM 没有安全漏洞,那么来宾代码就无法脱离 VM,无论它是在环 0(在来宾中)还是在非特权模式下执行。

因此,虽然您的问题的答案是肯定的,但它的危险性远不如最初看起来的那么危险。