Fork me on GitHub

反虚拟机技术


知识点

恶意代码编写者经常使用反虚拟机技术逃避分析,恶意代码可以使用这种技术探测自己是否运行在虚拟机中。

VMware痕迹:VM虚拟环境在系统中遗留了很对痕迹,特别是在安装Vmtools之后,恶意代码可以通过存在于操作系统文件系统、注册表和进程列表中标记痕迹,探测VM虚拟环境的存在。

安装VMtools的主机上通常会运行三个相关进程:VMwareService.exeVMwareTray.exeVmwareUser.exe。恶意代码在进程列表中中搜索带有VMware字符串的进程,就能找到这些进程。

绕过痕迹检测:

  • 在调试过程中修补二进制代码,使某些位置的跳转永远不会执行
  • 在十六进制编辑器中修改对比的字符串
  • 卸载VMwareTools

探测内存痕迹:搜索整个物理内存中存在的VMware字符串可能会搜索出上百个相关字符串。

查找漏洞指令:虚拟机监视器VMM监视虚拟机的运行,它运行在宿主操作系统并未客户机操作系统提供一个完整的虚拟平台,但是与此同时,VMM也有一些可以被恶意代码探测到的虚拟化安全缺陷。

在内核模式下,VMware使用二进制翻译技术进行指令的模拟。运行在内核态的某些特权指令被解释和模拟,所以他们不在物理处理器上运行,相反,在用户模式下,代码直接在处理器运行,几乎所有与硬件交互的指令,要么使特权指令,要么使会产生内核态陷阱指令或中断指令。VMware解惑所有中断并处理他们,以便虚拟机认为这是一个正常的机器。

然而在x86体系结构中,一些指令在获取硬件相关的信息使并不产生异常,如sidtsgdtsldtcpuid等,为了正确虚拟这些指令,VMware需要在所有指令上进行二进制翻译,因此造成巨大的性能损失,为了避免执行全指令模拟造成的巨大性能损失,VMware会允许一些特定的指令在没有正确虚拟化的前提下运行,这意味着某些指令序列在VMware而不是在物理机运行时返回不同的结果。处理器使用某些关键的结构与表,他们会被加载与真实系统不同的偏移量,而这正式未进行全虚拟化的副作用,中断描述表是CPU内部的一个数据结构,操作系统使用它来确保正确响应和中断、异常。所有内存的获取是通过全局描述表GDT获得,或是通过本地描述表LDT获得,这些表中包含段描述符,他们提供每一个段的详细存取信息,其中包含段基址的类型长度以及存取权限等。

有三条敏感指令可以读取这些表的位置:sigtsgdtsldt,并将相应的寄存器存入内存地址。虽然这些指令通常情况下由操作系统使用,但是在x86体系下可以在用户空间中执行,x86处理器中只有三个寄存器来存储这三个表的位置,因此这些寄存器的值必须对底层宿主操作系统有效,同时,他们派哪里了虚拟操作系统的与气质,因为这三个指令可以随时被用户态的代码调用,并且不会产生陷阱,也未被VMware正确虚拟化,因此这些异常都可以用来检测VMware的存在。

使用Red Pill反虚拟机技术:通过运行sidt指令获取IDTR的值,虚拟机监视器必须重定位Guest系统的IDTR,来避免与HOST系统的IDTR冲突,因为在虚拟机中运行sidt指令时,虚拟机监视器不会被通知,所以返回虚拟机的IDTRRed Pill技术通过检测这种差异性来检测是否处在虚拟环境中。

此方法一般只对单核处理器有效,因为每个处理器都有自己的IDTR。绕过此检测的方法是将sidt指令替换为nop

使用No Pill指令:sgdtsldt指令检测技术称为No Pill,此技术基于LDT结构是由处理器分配而不是由操作系统分配的这个事实,正常情况下Windows不会使用LDT结构,但是VMware为LDT提供了虚拟化支持,在物理集中LDT的值为0而在虚拟环境中为非零值,防止此检测方法的操作是禁用虚拟机加速。

查询I/O通信接口:这是一种时下最流行的虚拟机检测技术,VMware使用虚拟化IO接口来完成宿主主机与虚拟机之间的通信,这个端口可以被查询,然后与一个神秘数进行比较,这个技术成功的关键在与in指令,他从一个源操作数指定的端口复制数据到目的操作数制定的内存地址,VMware会监视in指令的执行,并不会目的通信通道端口为0x5668(VX)的IO数据。VMware会检查第二个操作数是否为VX,如果是则EAX寄存器载入的值是0x564D5868(VMXh),ECX寄存器中必须载入你希望在端口上执行响应操作的值如0xA可以获得VMware的版本。绕过此检测的方法是将in指令替换为nop

使用str指令:str指令用来从任务寄存器中检索段选择子,段选择子之心昂当前运行任务的状态段(TSS),这条指令的返回值在虚拟机系统和物理机上不同(此技术对多处理器的硬件无效)。

在IDA中高亮显示反虚拟机代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
from idautils import *
from idc import *
heads = Heads(SegStart(ScreenEA()),SegEnd(ScreenEA()))
antiVM = []
for i in heads:
if(GetMnem(i) == "sidt" or
GetMnem(i) == "sgdt" or
GetMnem(i) == "sldt" or
GetMnem(i) == "smsw" or
GetMnem(i) == "str" or
GetMnem(i) == "in" or
GetMnem(i) == "cpuid" or):
antiVM.append()
print "Number of potential Anti_VM instructions:%d" % (len(antiVM))
for i in antiVM:
SetColor(i,CIC_ITEM,0x0000ff)
Message("Anti_VM:%08x\n" % i)

使用ScoopyNG:这是一款免费的VMware检测工具,它实现了对虚拟机的其中不同检测。

虚拟机逃逸:VMware中存在一些安全漏洞,可以利用这些漏洞来世操作系统崩溃活在宿主系统中运行代码,共享文件夹功能或者共享工具中发现了很多公开的漏洞,禁用共享文件夹功能可阻止这类攻击。

课后练习

Lab17-1


本章结束🎊

您的支持是我最大的动力🍉