对于 SVM 或 VT-x,触发vmexit虚拟机监视器的一组条件非常复杂。如果没有内核的帮助,非特权进程可以触发其中任何一个吗?VMMCALL和的文档VMCALL都说它们只在环 0 中工作,所以我认为它们没问题。
这是Ninefinger前几天出色回应的后续问题。那里的细节太多了,我花了一段时间才吸收。:)
对于 SVM 或 VT-x,触发vmexit虚拟机监视器的一组条件非常复杂。如果没有内核的帮助,非特权进程可以触发其中任何一个吗?VMMCALL和的文档VMCALL都说它们只在环 0 中工作,所以我认为它们没问题。
这是Ninefinger前几天出色回应的后续问题。那里的细节太多了,我花了一段时间才吸收。:)
您需要了解说明的是英特尔软件开发人员手册。对于它的价值,我有时会发现它们有点不透明——所以我对比了我在谷歌和 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 发出的,它认为“超级呼叫”无效。
影响:
VMCall. 但是,从我所做的非常初步的阅读来看,它似乎(可能)不可能以任何方式有用 - 因为环 3 地址可能是虚拟的客户操作系统(因此没有任何意义主人)。我强烈怀疑是这种情况,但我(还)不能确认。因此,如果您真的想深入研究它,您需要做的是验证:
VMCall将仅限于访客环 0。如果VMCallet al 只能从 ring 0 有意义地执行,那么您的客户端客户代码也必须能够在 ring 0 中执行,或者说服您现有的一些代码做一些不应该做的事情。例如:
VMCall来做你想做的任何事情。VMCall以您的方式进行调用,即使用您的参数,而不是通常使用的参数。漏洞利用的成功完全取决于管理程序以及这些 VMCall 是否易受攻击。如果它们不是,那么您是否设法调用它们并不重要 - 管理程序可以酌情拒绝它们。在这一点上,老实说,我认为这种利用路线(通过 a VMCall)不太可能(尽管如果有的话,后果当然会非常严重)。
我在这里错过了两件事:
是的,非特权访客代码可以触发 VM 退出。
然而,这并不意味着非特权的来宾代码可以突破虚拟机。当触发 VM 退出时,控制权转移到虚拟机监视器的代码。如果 VMM 代码编写正确,它负责安全地处理 VM 退出:特别是,以不允许恶意来宾代码从 VM 中突围的方式。
请注意,“VM 退出”是一个技术术语,是指将控制权转移到 VMM。尽管使用了“退出”这个词,但这并不意味着来宾代码可以突破虚拟机。它指的是一种调用 VMM 的方式,而不是某种安全漏洞。如果 VMM 没有安全漏洞,那么来宾代码就无法脱离 VM,无论它是在环 0(在来宾中)还是在非特权模式下执行。
因此,虽然您的问题的答案是肯定的,但它的危险性远不如最初看起来的那么危险。