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

目录

笔记

实验

Lab17-1

Lab17-2

Lab17-3


笔记

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

                       识别进程:VMwareService.exe  VMwareTray.exe VMwareUser.exe Service.exe等都是关于虚拟机的进程

                       识别MAC地址:00:0C:29

                       识别内存痕迹:搜索整个物理内存中VMware的字符串

查找漏洞指令:反虚拟机的X86指令:sidt,sgdt,sldt,smsw,str,in。cupid

    使用Red Pill反虚拟机技术:通过sidt指令获取IDTR寄存器的值。调用sidt指令,将IDTR寄存器的值存储,IDTR由6个字节组成,其中第五个字节的偏移量包含IDT的内存地址,将这个值与0xff比较去判断VMware存在。

    使用NO Pill技术:sgdt与sldt指令探测VMware是否存在。NO Pill依赖于LDT结构,正常情况下Windows不会使用LDT结构,而在虚拟机中是非0值。解决方法:防止sldt探测方法-->VM  Setting  Processors  勾选Disable Acceleration

    查询I/O通信端口:经常在Storm worm和Phatdot蠕虫和僵尸程序中,in指令把源操作数指定的端口复制到目的操作数的内存地址。解决方法:NOP指令替换in指令

var_1C是一个内存地址,用来存放从VMware返回的所有响应。inc指令使用参数EAX(magic参数),ECX操作数,返回值在EBX中。如果magic和VMXh匹配,代码运行在虚拟机中,将值放到EBX中。

       使用str指令:用来从寄存器中检索段选择子,段选择子指向当前运行的任务状态段(TSS)。str指令大返回值在虚拟机和宿主机中是不同的。

        解决:1.IDApython,通过IDApython将这些指令找出来

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) == "cupid"):
        antiVM.append(i)
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)

                    2.ScoopyNG:探测VMware探测工具

调整设置:

directexec指定用户模式下的代码模拟执行,而不是在硬件上运行。

前四条设置被VMware后门命令使用,不能获取宿主系统的信息

总结:一个代码在一个条件跳转处过早终止

实验

Lab17-1

运行给定的python脚本,查找漏洞指令。对应结果可以看出有三处

No Pill,开始eax被初始化成一个向量DDCCBBAA,sldt指令的值放到了var_8的位置,然后又给到了eax位置。然后看一下哪了调用了这里的代码

查看初始向量的低序列位是否被设置为了0(在虚拟机中是非0值)。如果不是就执行退出

Red Pill,调用sidt指令,将IDTR寄存器的值存储,IDTR由6个字节组成,其中第五个字节的偏移量包含IDT的内存地址,将这个值与0xff比较去判断VMware存在。

str,将任务状态段(TSS)载入到一个4字节的本地变量var_418中。检测是不是FF。如果是VMware的话,第一个判断处edx是0,第二个判断处eax是40

Lab17-2

dll的导出函数,进入第一个安装函数

在调用完sub_10006196函数后,有两个分支,一个是检测到虚拟机。所以sub_10006196函数是一个检测虚拟机的函数

sub_10006196

in指令来查询I/O通信端口,因为VMware在虚拟机与宿主操作系统之间会使用虚拟的I/O端口进行通信。而在0x100061D6处,这个虚拟端口被保存到了edx中,而前一条指令中,则是将执行的动作,也就是0x0A(获取VMware的版本类型)保存到了ecx里面。在0x100061C7处,magic数0x564d5868(VMXh)被载入到了eax中。

在in指令后,恶意程序使用cmp指令来检查magic数的回应。比较的结果会保存在var_1C里面,最后在0x100061FA的位置,作为函数的返回值,送入al里面。 这个恶意程序似乎并不关心VMware的版本,它仅仅想用一个magic值来查看I/O通信端口的回应

上面代码中的jz指令用于决定是否执行虚拟机的检测。还使用了atoi函数将字符转化为数字。转化的内容是off_10019034,也就是“[This is DVM]5”。这个字符串会保存在eax里面,之后再与0x0D相加,意味着将字符串指针移动了13个字节,指向了字符“5”。之后利用atoi将字符“5”转化为数字的5。下面的test指令用于查看转化后的数字是否为0。那么依据这一点,如果我们将这个字符串修改为“[This is DVM]0”,那么恶意程序就不会执行虚拟机的检查了。

Lab17-3

第一处反虚拟机技术

in指令来查询I/O通信端口,因为VMware在虚拟机与宿主操作系统之间会使用虚拟的I/O端口进行通信。当在虚拟机中时会返回eax=1。

这个函数的返回值将会影响接下来代码的流程,所以可以修改test eax,eax为xor eax,eax

第二处反虚拟机技术 

 sub_4011C0的交叉引用图,指向了多个注册表函数,并且调用了自己本身

检查系统的驻留痕迹。如果说我们进一步检查sub_4011C0函数,可以发现它在循环遍历DeviceClasses下的注册表子键,并且与vmware字符串进行匹配,以检测当前是否运行在虚拟机中。

第三处反虚拟机技术

GetAdaptersInfo函数可以用来获取网络适配器的相关信息,它需要Iphlpapi.dll这个动态链接库的支持。将dword_403114这个函数的起始地址重命名。查看交叉引用,进入函数sub_401670函数

sub_401670

开始的部分展示了一系列mov字节,把这里设置成一个27字节的数组,并命名为Byte_Array数组,便于以后分析。

第一次调用GetAdaptersInfo函数,压入的第一个参数为0(null),链表的大小在dwBytes中。调用函数后返回的是数据的大小 

第二次调用GetAdaptersInfo函数,压入的第一个参数为是HeapAlloc的返回值,最后返回的是一个大小为dwBytes的IP_ADAPTER_INFO结构链表的一个指针。手动添加IP_ADAPTER_INFO结构体

Type是标准常量,0x6--->以太网,0x71--->802.11无线适配器。比较网络接口是以太网接口还是无线接口。然后检查适配器长度是否大于2。如果成功往下看

repe是一个串操作前缀,它重复串操作指令,每重复一次ECX的值就减一 一直到CX为0或ZF为0时停止。 

           cmpsb是字符串比较指令,把ESI指向的数据与EDI指向的数一个一个的进行比较。 

repe cmpsb指令含义将IP_ADAPTER_INFO.Address的前三个字节与Byte_Array比较。其中{00,50,56}和{00,0C,29}都是默认VMware MAC地址的默认开始。比较了9个不同的MAC地址。这里是一个循环。

第四处反虚拟机技术

进入sub_401130

sub_401130

这里功能是遍历进程列表,猜测应该是比对虚拟机的字符串,但是这里并没有明显的关于虚拟机字符串。获取进程名后,调用sub_401060函数把字母转化为小写,然后再执行sub_401000函数。结果与arg_0(0xF30D12A5)进行比较。

进入sub_401000

这是一个简单的字符串哈希函数,给定参数vmware,返回0xF30D12A5。避免了明文的vmware字符串

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: java-7-openjdk-amd64虚拟机不存在,可能是由于以下原因所致: 1. 您使用的操作系统不兼容java-7-openjdk-amd64虚拟机,需要使用其他版本的虚拟机; 2. 您的系统中未安装java-7-openjdk-amd64虚拟机,您可以尝试安装该虚拟机或者使用其他可用的虚拟机; 3. 如果您使用的是云服务器,可能需要联系云服务提供商进行设置或安装java-7-openjdk-amd64虚拟机。 建议您可以尝试通过检查操作系统兼容性、安装虚拟机或者联系云服务提供商等方式来解决该问题,以确保您能够正常使用所需的虚拟机。 ### 回答2: Java-7-OpenJDK-AMD64虚拟机不是一种存在的虚拟机。OpenJDK是一个开源的Java开发工具包,它包含了Java虚拟机,Java类库和其他工具。但是,OpenJDK并没有一个特定的版本叫做Java-7-OpenJDK-AMD64虚拟机。也许您在尝试安装某个应用程序或软件时看到了这个错误消息,这意味着该程序需要Java虚拟机来运行,但是您可能尝试安装了错误的Java版本或操作系统。正确安装Java虚拟机后,您应该能够运行需要它的应用程序或软件。建议您检查所需的Java版本和操作系统,以确保您下载了正确的Java虚拟机。 ### 回答3: Java-7-openjdk-amd64虚拟机是指OpenJDK 7版本的Java虚拟机,支持64位的AMD等处理器架构。如果您在使用该虚拟机时发现它不存在,可能是以下原因导致: 1. 您尚未安装该虚拟机。您可以通过sudo apt-get install openjdk-7-jdk命令在Ubuntu上安装该虚拟机。 2. 该虚拟机已被您卸载或删除。您可以通过sudo apt-get remove openjdk-7-jdk命令在Ubuntu上卸载该虚拟机。 3. 您所使用的操作系统版本不支持该虚拟机或者该虚拟机已过时,建议使用更稳定、更新的版本,比如OpenJDK 8、OpenJDK 11等版本。 在进行Java开发时,选择适合自己的Java虚拟机非常重要,建议根据需要选择合适的开发环境和Java版本。需要注意的是,OpenJDK不同版本的Java虚拟机可能存在不同的特性和性能,您可以根据自己的需要进行选择。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值