恶意代码分析实战 14 反虚拟机技术

14.1 Lab17-01

题目

  1. 这个恶意代码使用了什么反虚拟机技术?

恶意代码用存在漏洞的x86指令来确定自己是否运行在虚拟机中。

  1. 如果你有一个商业版本IDAPro,运行第17章中代码清单17-4所示的IDAPython脚本(提供如jindAniM.py),看它发现了什么?

使用IDA载入脚本文件。
vmware_eEk2wxYTjH.png
给出了地址。
vmware_vly6wWcQod.png
vmware_caaTNmf4BZ.png
vmware_xcMxKVCHxf.png

  1. 每种反虚拟机技术成功执行后会发生什么?

第一处:
vmware_e6v2LyfLoH.png
vmware_9VVxyiq7BC.png
vmware_VxsrDBHiMx.png
这串字符串进行了修改。
查看调用函数的位置。
vmware_YNB4o8KVe9.png
使用OD查看,EAX被赋值为了00DDCC000h,将会跳转,而不会创建线程。
第二处:
vmware_nqyGofHoU6.png
检测虚拟机特征。
检测到之后,删除自身。
vmware_SNclTLcPY0.png
第三处:
vmware_ePP5QwmysK.png
检测到之后不会执行创建服务的操作。

  1. 针对你的虚拟机,这些反虚拟机技术中哪些技术会生效

使用OD检查可知,所有的操作都会失效。可能与虚拟机的内核数量有关。

  1. 为什么每个反虚拟机的技术,会生效或失败?

sidt指令:多核机器上进行实验,ECX寄存器的值不是0xFF,所以失效。
str指令:本机上的特征码0x28.
sldt指令:在0x4012D6处设置断点,发现EAX等于0xDDCC000h.

  1. 怎么便这些反虚拟机技术无效,从而让恶意代码运行

你可以用NOP替换sidt和str指令,或者在调试恶意代码时,实时改变跳转标志。

14.2 Lab17-02

题目

  1. 这个DLL导出了什么?

查看导入函数。
vmware_28mYlkOV5I.png
存在对注册表的操作。
查看导出。
vmware_4Vg7jNghtA.png
导出函数是InstallRT、 InstallSA、 InstallSB、 PSLIST、ServiceMain、StartEXS、UninstallRT、UninstallSA, 以及UninstallSB。

  1. 尝试使用rundll.32.exe安装后,都发生了什么?

vmware_e6VLZuYY7d.png
使用ProMon查看。
vmware_x6n3qeRkEH.png
新建了xinstall.log文件和vmselfdel.exe文件。
但他又将vmselfdel.exe文件删除了。

  1. 它创建了哪些文件,这些文件都包含什么内容?

vmware_TTHBcoxQgD.png
创建一个包含自我删除代码的.bat文件,同时还创建一个包含字符串FoundVirtualMachine,InstallCancel的xinstall.log文件。

  1. 它使用何种反虚拟机方法?

使用IDA查看该文件。通过交叉引用查询到文件创建的位置。
vmware_oDjneHqnfP.png
反虚拟机技术实现的函数。
vmware_YZXBrWc26a.png
恶意代码正在使用in指令查询IO通信端口(0x5668)(VMware在虚拟机与宿主操作系统之间使用虚拟IO端口通信)。这个虚拟端口被载入到EDX,在前一条指令中,执行的动作被载入ECX。本例中,动作是xA,它表示“获取VMware的版本类型”。magic数0x564d5868(VMXh)被载入到EAX,在in指令后,恶意代码使用cmp指令,检查magic数的回应(如所示)。比较结果被送入变量var1c,最后作为函数sub10906196的返回值送入AL。

  1. 在恶意代码运行时,怎么强制安装它。

这个恶意代码似乎并不关心VMware的版本。它仅仅想用一个magic值来查看IO通信端口的回应。在运行时,我们可以用NOP替换in指令,绕过后门IO通信端口技术。插入NOP可以使程序完成安装。

  1. 怎样可以永久禁用这些反虚拟机技术?

为了永久性禁用VM检查,用十六进制编辑器将二进制文件中的静态字符串从[This is DVM15修改为[This is DVM]。另外,使用OllyDbg用NOP替换检查指令,并且将修改写入硬盘。

  1. 每个安装的导出函数是如何工作的?

InstallRT:通过带有被注入进程可选参数的DLL注入来执行安装
InstallSA:通过服务安装来执行安装
InstallSB:通过服务安装来执行安装,如果覆盖的服务正在运行,那么使用DLL注入来安装。

14.3 Lab17-03

题目

  1. 当你在虚拟机中运行这个恶意代码时会发生什么?

使用ProMon进行监控。
vmware_aFJphqvxJ6.png
与Lab12-2不同的是,当这个恶意代码在虚拟机中运行时,它会立即终止。另外这个恶意代码在svchost.exe上执行了进程替换。

  1. 怎么让这个恶意代码运行,并且关闭它的键盘记录呢?

使用插件,查找x86漏洞。
vmware_kreA3EyYS4.png
这个脚本在0x401ac8处识别了一个反虚拟机指令,以红色高亮显示。我们注意到这是一个通过in指令查询的后门I/O通信端口。这个反虚拟机技术包含在被IDA Pro标注为sub_401A80的函数中。如果他运行在虚拟机中,这个函数返回1,否则返回0.这是main函数开始处唯一的一个交叉引用。
vmware_0fi5D4ApxM.pngvmware_KhTndNVbyb.png
jz指令必须被移除,否则会跳转到0x401a71处,让main方法立即终止。当运行到jz指令时,我们置位零标志位来禁用这种反虚拟机技术。要永久禁用这种反虚拟机技术,将test指令按如下步骤改为xor eax,eax。

  1. 启动OD,将光标放在行0X40199F上。
  2. 按空格键,在文本框中输入xor eax, eax。
  3. 单击Assemble。

查看该函数的交叉引用。
image.png
来到main函数。
chrome_Qi5AdYE8Fb.png
可以看到该函数的返回值会通过test,jz指令影响程序的执行如果是往左边走。
chrome_3o8wgyfuim.png
是直接就结束了,很明显,我们是希望往右边走,那么我们就要保证eax为0,为了实现给eax赋0,我们可以将test修改为xor。
查看string窗口。
chrome_njEdcN9o1k.png
上图显示为阴影的字符串似乎是一个注册表的路径,上面的GetAdapterInfo是用于获取网络适配器相关信息的函数,这类注意到vmware,我们分析一下,双击后查看交叉引用。
chrome_67a4OgmMUj.png
跟入sub_4011c0,看看它交叉引用图。
chrome_sYuhOeMY8W.png
可以看到调用了多个注册表相关函数,最重要的是上图圈起来的,有一个循环的箭头,表示它还会调用自身。我们可以推测这是在注册表中递归检查字符串vmware,分析sub_4011c0。
chrome_VOXz5UsC04.png
这里有个循环结构,这是在循环遍历DeviceClasses下的注册表子键
调用sub_401060。
chrome_FvVGmy0jCs.png
跟入可知其作用是将字母转为小写。
chrome_wlx8JbVfkg.png
在将每个子键名的前6个字节转为小写后,与字符串vmware进行比较,查看sub_4011c0交叉引用。
chrome_mAk0rrrfVw.png
跟入在main函数中调用的地方。
chrome_2uLYyffk4N.png
在其调用之前,有三个push,说明有三个参数,其中之一就是之前看到的注册表的路径,所以猜测函数就是从这个路径开始递归检查注册表的,这就是对系统驻留痕迹的检查,我们希望能够实现004019c0的跳转,所以我们将test改为xor即可确保零标志位置位,接着我们看看GetAdapterInfo字符串,双击后查看交叉引用。
chrome_IBeADS4tb6.png
来到main。
chrome_1SEhcNEJto.png
通过LoadLibraryA和GetProcAddress动态解析GetAdapterInfo,并将地址保存在dword_403114,这里可以将其重命名为GetAdapterInfo_Address,查看其交叉引用。
chrome_rdBsFsKBJ7.png
跟入第一处。
chrome_N6LDpAh6vC.png
其上是一系列字节mov,一共有27条,双击Var_38,将其设置为一个大小为27字节的数组来将这些mov字节初始化Wie一个字节数组,如下操作,右键。
chrome_Nta1bMabJQ.png
Array Size设为27。
chrome_KwnkTzker6.png
修改完成后如图所示。
chrome_ef8fEPEMAm.png
可以将var_38重命名为Byte_Array。
chrome_6F5FocFw0S.png
在调用GetAdapterInfo时可以看到,其有两个参数,查阅MSDN文档可知。
chrome_Ds6I36IQuC.png
两个参数分别为IP_ADAPTER_INFO结构的链表和链表的长度而对应着IDA可知,传入的链表为NULL,传入的链表大小来自dwBytes一般来说,在调用GetAdapterInfo_Address时,设置它的第一个参数为NULL是找出函数返回数据大小的简单方法,从而为第二个GetAdapterInfo_Address调用使用的链接结构分配内存。所以我们可以在之后简单GetProcessHeap,HeapAlloc使用dwBytes。
chrome_LXV91XSMyJ.png
调用HeapAlloc为再次调用GetAdapterInfo_Address分配内存,其返回值在lpMem。
chrome_5pqA27JnVB.png
在第二次调用GetAdapterInfo_Address时可以看到传入的第一个参数不是NULL,而是IpMem,随后,lpMem成了大小为dwBytes的IP_ADAPTER_INFO结构链表的一个指针,我们需要在IDA中添加IP_ADAPTER_INFO结构,来到structure窗口,按insert键。
chrome_QKwsM42p1y.png
恢复后:
chrome_PYkbtBGQ4x.png
004017d0:给ecx赋3
004017e2:var_3c赋给eax
004017e5:使用eax索引Byte_Array
将Byte_Array中的一个索引与当前的IP_ADAPTER_INFO.Address比较
由于ecx被赋3,所以004017f4处的repe cmpsb指令会将IP_ADAPTER_INFO.Address的前三个字节与Byte_Array比较
Byte_Array内容:
光标定位到Byte_Array,按x键。
chrome_3wZLwgyeNY.png
也就是说此处是在查看MAC地址的前三个字节是否为{00h,50h,56h}或者{00h,0ch,29h}等
我们查到,00,0c,29是VMware MAC地址的默认开始。由于数组长度为27,所以可知此处比较了9个不同的MAC地址为了避免这种技术的检测,我们可以将40169f的jnz指令改为jmp 0x40184a。
chrome_W7gxxXWmdI.png
这样就可以跳过MAC地址的检查,直接到资源节操纵代码,恶意代码最后一处针对虚拟机的检查在sub_401400。
chrome_s9p5LxDq44.png
跟入该函数。
chrome_CMLdiOyIpG.png
调用了sub_401130,可以看到传入的两个参数分别为6和0f30d125ah,该函数返回值将决定jz指令时候会跳转,跟入这个函数。
chrome_eWTeYF0wPD.png
通过上图看到的几个关键函数和循环结构可知,这是在遍历进程列表。
之后调用了sub_401060,其参数之一是进程名称,这函数用于将字母转成小写,之后调用sub_401000,其参数为arg_4,以及sub_401060的返回值,也就是其返回的小写字符串,而sub_401000的返回值会在00401195处的cmp与arg_0比较。
回溯可知。
chrome_8chQmuFE4X.png
arg_0就是F30D125A,如果00401195处比较结果相等,则走右边。
chrome_u4lsNo1YgQ.png
eax被赋1,恶意代码终止,sub_401000将进程名称转换为一个数字,然后将数字与预设值比较。Sub_401000是一个简单的字符串hash函数,如果给定的参数是vmware,则返回0xF30D12A5.从而终止恶意代码,为了禁用这个检查反虚拟机检查的部分,可以用nop替换到40145d处的sub_401130调用。
我们可以使用nop指令将位于0x0040145D的指令填充掉即可。

  1. 这个恶意代码使用了何种反虚拟机技术?

这个恶意代码使用了如下4种不同的反虚拟机技术:使用后门I/O通信端口。搜索在注册表键SYSTEM\CurrentControlSet \Control \DeviceClasses下的vmware字符串。检查MAC地址,查看它是否是VMware默认使用的MAC地址。用字符串哈希函数来搜索进程列表中以字符串vmware开头的进程。

  1. 你可以对系统做什么样的变化,从而使你能够永久避免恶意代码所使用的反虚拟机技术?

为了逃避这个恶意代码使用的反虚拟机技术,你可以卸载VMware工具并修改MAC地址。

  1. 为了让反虚拟机技术永久失效,你该如何用OllyDbg对二进制文件进行修补?

在OllyDbg中,你可以采用下面的补丁:
用NOP替换0x40145D处的指令。
修改0x40199F 和0x4019BE处的指令为xor eax,eax。
修改0x40169F 处的指令为jmp θx40184A。

猜你喜欢

转载自blog.csdn.net/weixin_61823031/article/details/128758320
今日推荐