• 我们在哪一颗星上见过 ,以至如此相互思念 ;我们在哪一颗星上相互思念过,以至如此相互深爱
  • 我们在哪一颗星上分别 ,以至如此相互辉映 ;我们在哪一颗星上入睡 ,以至如此唤醒黎明
  • 认识世界 克服困难 洞悉所有 贴近生活 寻找珍爱 感受彼此

恶意代码分析实战:第十七章 反虚拟机技术

恶意代码分析实战 云涯 3年前 (2021-02-22) 1774次浏览

本章重点介绍反VMware技术

1 VMware痕迹

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

VMware镜像的进程列表,且安装VMware Tools之后会有三个进程:VmwareService.exe(以服务形式启动VMware Tools)、VmwareTray.exe、VMwareUser.exe。

恶意代码在进程列表中搜索VMware字符串进程,就能找到上述三个进程中任意一个。或者还可以搜索注册表安装的服务,或者可以通过下列命令枚举系统中的服务来识别它。


net start | findstr VMware


在VMware安装目录也可以发现痕迹。

在注册表中搜索VMware字符串,可能也会发现下列注册表项。这些注册表项包括虚拟机硬盘驱动器、适配器和虚拟鼠标。

 

虚拟机MAC地址通常以00:0C:29开始的。恶意代码只需检测虚拟机网卡的MAC地址是否在VMware属性值范围内。

也可以通过探测主板来检测虚拟机。

1.1 绕过VMware痕迹探测

① 定位恶意代码查询VMware标记痕迹的代码位置

② 修补它们

1.2 探测内存痕迹

作为虚拟化过程的结果,VMware在内存中留下了很多痕迹。

有一种被用来探测内存痕迹的技术,搜索整个物理内存中含有VMware字符串,发现这种技术可以检测出上百个字符串实例。

 

2 查找漏洞指令

虚拟机监视器VMM监视虚拟机的运行,它运行在宿主操作系统,并为客户机操作系统提供一个完整的虚拟平台。同时,VMM也存在一些可以被恶意代码探测到虚拟化的安全缺陷。在内核模式下,VMware使用二进制翻译技术进行指令模拟。运行于内核态的某些特权指令被解释和模拟,所以它们不在物理处理器上运行。相反,在用户模式下,代码直接在处理器运行,几乎所有与硬件交互的指令,要么特权指令,要么会产生内核态陷阱指令或中断指令。VMware截获所有中断并处理它们,以便虚拟机仍然认为这是一个正常机器。

然而,在x86体系中,一些指令在获取硬件相关的信息时并不产生异常,如sidt、sgdt、sldt、cpuid等等。为了正确虚拟这些指令,VMware需要在所有指令上进行二进制翻译,因此造成巨大性能损失。为了避免执行全指令模拟造成的巨大性能损失,VMware允许一些特定指令在没有正确虚拟化的前提下运行。最终,这意味着某些指令序列在VMware和物理机上返回不同结果。

处理器使用某些关键的结构和表,他们会被加载与真实系统不同的偏移量,而这正是未进行全虚拟化的作用。

中断描述表(IDT)是CPU内部的一个数据结构,操作系统使用它来正确响应中断和异常。在x86体系下,所有内存获取,或是通过全局描述表(GDT)获得,或是通过本地描述表(LDT)获得。这些表中包含段描述符,他们提供每一个段的详细存取信息,其中包含段基地址类型,长度,以及存取权限等。

IDT(IDRT)、GDT(GDTR)和LDT(LDTR)是CPU内部的寄存器,他们分别存放着各自表的基地址和大小。

有三条敏感指令,sidt、sgdt和sldt可以读取这些表的位置,并且将相应的寄存器存入内存地址,在x86体系结构下它们并不是特权指令,可以在用户空间执行。

x86处理器只有三个寄存器来存储这三个表位置。因此,这些寄存器的值必须对底层宿主操作系统有效,同时,它们偏离了虚拟操作系统的预期值。因为sidt、sgdt和sldt指令可以随时被用户态代码调用,且不会产生陷阱,也未被VMware正确虚拟化,所以这些异常可以被用来检测VMware的存在。

2.1 使用Red Pill反虚拟机技术

Red Pill是一种反虚拟机技术,通过运行sidt指令获取IDTR寄存器的值。虚拟机监视器必须重新定位Guest系统的IDTR,来避免与Host系统的IDTR冲突。

因为在虚拟机运行sidt指令时,虚拟机监视器不会得到通知,所以会返回虚拟机的IDTR。Red Pill通过这种差异来探测VMware的使用。

在①处使用sidt指令,将IDTR寄存器的内容存储到EAX指向的内存地址。IDTR由6个字节组成,其中第五个字节的偏移量包含IDT的内存基址。将第五个字节与0xFF比较,来判断VMware。

Red Pill仅在单处理器上有效,在多核处理器上可能无效,因为每一个处理器(虚拟机或宿主主机)都有一个分配给它的IDT,所以sidt指令返回的结果各种各样,这种方式也不太可靠。

 

2.3 查询I/O通信端口(特权指令)

VMware使用虚拟化I/O端口完成宿主系统与虚拟机之间的通信,以便支持如复制粘贴功能。这个端口可以被查询,与一个数字进行比较,确定VMware的使用。

这种技术成功关键在于x86体系中的in指令,它从一个源操作数指定的端口复制数据到目的操作数指定内存地址。

VMware会监视in指令的执行,并捕获目的通信端口为0x5668(VX)的IO。VMware会检查第二个操作数是否为VX,在这种情况下,EAX寄存器载入的值是0x564D5868(VMXh),ECX寄存器中必须载入你希望在端口上执行相应操作的值,值0xA表示“get VMware version type”; 0x14代表“get the memory size”。它们都可以被用来探测VMware,但0xA更受欢迎,因为它能确定VMware版本。

在①处,恶意代码首先将一个magic数0x564D5868(VMXh)载入EAX寄存器。

接下来,将局部变量var_1c载入EBX,他是一个内存地址,用来存放VMware返回的所有响应。

ECX被载入值0xA,用来获取VMware版本类型。

在②处,0x5668(VX)被载入到DX,用来为随后的in指令指定VMware I/O端口。

当指令执行时,in指令被虚拟机捕获,然后再模拟执行。in指令使用参数EAX(magic数),ECX(操作数)以及EBX(返回信息)。如果magic与VMXh匹配,表示代码运行在虚拟机中,虚拟机监视器会将值存入有EBX指令的内存位置。

由于IN指令属于特权指令,在处于保护模式下的真机上执行此指令时,除非权限允许,否则将会触发类型为“EXCEPTION_PRIV_INSTRUCTION”的异常,而在虚拟机中并不会发生异常。

③处指令用来确定代码是否运行在虚拟机中。由于选择了获取版本选项,ECX寄存器会包含VMware类型(1=Express 2=ESX 3=GSX 4=Workstation)

修复:NOP掉in或者修补跳转。

实例:

EBX返回564D5868,被用来判断是否在虚拟机。

 

 

 

 

 

 

 

 


云涯历险记 , 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:恶意代码分析实战:第十七章 反虚拟机技术
喜欢 (0)