日前实验室捕获一个样本。远远望去,像是搜狗输入法,在测试机中点开一看,弹出一款游戏的物价表,再看PE文件属性,还带正常着数字签名,一副人畜无害的样子。经过一番认真分析后。发现远没有这么简单,这里就分析过程记录一下,希望其他安全工作者有些许帮助。
先介绍一下所谓白名单免杀。随着病毒与杀软之间的斗争,杀软的手段不断地增多、增强,由早期传统的特征码匹配算法发展到目前虚拟机技术、实时监控技术等流行的查杀算法。但始终存在一种最直接也最根本的免杀方式——白名单免杀。病毒就安安静静地躺在杀软的白名单中,谁闲的没事会去查水表呢?
当了解了白名单免杀的基本含义之后,就可以针对样本进行深入的研究,本文以下内容就是笔者拿到样本之后,逐步分析样本主要功能的完整过程,其分析环境如下:
样本包含5个文件:
File name | size | MD5 | attribute |
---|---|---|---|
nvvsvc1.exe.exe | 451.50 KB (462336 bytes) | 4D9B3A508BC2402A86E10F7907022263 | hidden |
HWSignature.dll | 48.50 KB (49664 bytes) | 85F50E1D2DE076079D98F09416E4C710 | hidden |
HanziSort.dat | 158.75 KB (162557 bytes) | 4FB42CBC7ADD3CF2AB3F0A99B9E7CE25 | hidden |
图1 | Shortcut linked to cmd | cmd /c nvvsvc1.exe & exit | Shortcut |
01.jpg.jpg | 99.07 KB (101446 bytes) | 78501660AD39494A7248BA0C96989494 | hidden |
cmd.exe /c nvvsvc1.exe & exit
其中,nvvsvc1.exe为主程序,其目的是加载HWSignature.dll,而HWSignature.dll会加载并解码HanziSort.dat, 进一步的,HanziSort.dat会再次解码自身并在内存中释放svchost2.dll,此后手动加载svchost2.dll,该DLL为包含恶意程序的主要功能。
传播方式:以《怪物猎人官方最新物价表》为鱼饵进行钓鱼,下载解压后,其他文件隐藏,只能看到名称为“图1”的文件,点开后确实会展示图片,但木马也会加载。 笔者建议广大游戏玩家,下载的攻略要先看清是什么东西,再点开查看内容。
拿到样本之后,首先放到virusbook查了查,主程序想必没问题,而除此之外的一个DLL就被查出有问题了。很明显,这是一个通过DLL劫持加载自己的木马样本,这种通过DLL劫持的木马,可以算是白名单免杀吗?这个问题先放一放,后文(0x8 结语)会给出笔者的看法。
IDA分析主程序,绝大部分都是输入法相关的操作,中规中矩。值得注意的是,此处创建了8个线程。
这其中第4个线程,即执行sub_427C80的线程会进一步调用sub_42F090函数,在该函数的子函数中,会加载HWSignature.dll,但此处被样本劫持,用来执行其恶意功能。
跟进这个DLL,进一步分析该DLL的行为。无关行为不说,该DLL会打开HanziSort.dat文件:
读取其内容,并解码:
其解码方式很简单,只是把读取到的文件内容逐字节的与0x56做异或运算。解码之后,成为包含可执行指令的程序段:
此后,程序会通过retn的方式跳到解码的代码段执行。
在DAT解码的代码中,首先会寻找解码内容为0xDDCCBBAA的位置:
通过该地址,可以辅助完成一些列的定位操作,具体内容不做介绍。进而会调用VirtualAlloc函数分配内存空间,然后通过memcpy函数将指定数据拷贝到申请的内存中:
而拷贝过去的内存段,会再一次进行解码:
其解码方式同样比较简单,是逐字节与0xCC进行异或运算。当完整所有解码工作之后,可以发现解码之后的内存为一个完整的PE文件:
将该PE文件dump出来,用查看CFF看下,可以确认是个完整的DLL:
(忽略一些细节吧。笔者懒得打码了。)
这个DLL叫做svchost2.dll,后面的代码可想而知,新申请一块内存
然后手动完成PE的加载流程:
以及根据导入表和重定位表做一些修复工作,并加载所需的各种DLL,最后调用VirtualProtect更改页保护。
完成以上操作之后,调用DLL main函数:
DLL的主函数并没有什么需要深入分析的地方,这里略过。DLL main返回后,会查找DLL导出的mystart函数:
最后调用mystart:
在该函数中,首先会获得当前仅进程的名字,并判断名字中是否包含”1.exe”字符串。
获得的样本中,当然是包含该字符串的。接下来,会进行一些有意思的事。首先会调用WinExec执行” taskkill /f /im cmd.exe
”命令,然后创建一个互斥体。
进一步的,该样本会在C:/Users/zzz/AppData/Roaming创建一个文件夹,其名字随机:
在本次分析中为:C:/Users/zzz/AppData/Roaming/dptpbzwoztxwrh,并将样本所在的文件夹中所有文件都复制到该目录下,包括ida生成的几个文件,但排除01.jpg.jpg。对于这幅图片,该样本会调用cmd执行rundll32.exe shimgvw.dll imageview_fullscreen 01.jpg.jpg,其作用就是把样本中的01.jpg.jpg展示出来:
(01.jpg.jpg :什么仇什么怨?)
如此一来,受害者看到了想了解的《价格表》,也不会怀疑该文件是木马了。此外,复制到Roaming的主程序会重命名为MSUpdateXXXXXXXX.exe,XXXXXXXX表示8位随机字母。注意,IDA生成的几个文件也会被复制过去并重命名。
拷贝完成之后,释放互斥体,并Sleep(0x2EE0)的时间。
并注册表增加一些键值:
最后,通过shellexecute执行刚刚复制到Roaming的样本文件。
当第二次执行时,之前的行为都是类似的,只有在mystart函数中,出现了变化。由于当前进程是复制到Roaming下的镜像文件,重命名之后不包含”1.exe”字符串(参考上文)。所以会执行到另一个分支,调用Fi函数。
该函数为svchost2.dll的另外一个导出函数。该函数会隐藏自己的进程名以及其他的信息:
隐藏结果使自己的进程名变为csrss.exe的,如图:
但这种隐藏手段并不高级,随便一个工具就能识别出来。
进而,会调用Fa函数,该DLL的另一个导出函数。在该函数中出现了一些网络行为。首先,会连接139.196.184.116:34176
并发送数据:
该数据是怎么来的,暂时没有必要追究。有需要时,可以进一步分析,不过,可以肯定的是,对于同一台机器,每次发送的数据是一样的,应该是作为机器的ID标识。发送之后,会接收到如下内容:
针对返回的内容,会判断是否含有”Set-Cookie:”字符串,如果有,则取出:
接下来,会用该Cookie作为机器的标识。
进而,会连接139.196.184.116:35131地址:
但是该端口已经挂掉了,无法连接上。所以,笔者只好重新定向到自己的IP,并模拟其通信。 连接上IP之后,会发送一些随机生成的数据:
本机的监听结果如下:
发送3次随机生成的数据之后,会创建新线程用于接收返回数据:
该线程会接收来自139.196.184.116:35131回复的数据,但是由于该端口已经挂掉了,笔者只能随意的回复点什么东西,[email protected]
接收到回复之后,会在sub_12A50F0中做解码工作。其解码工作首先会将受到的数据逐比特与0xE9异或。
进而会对长度进行判断,然后对几个关键位置的内容进行判断,如果出现不符合的情况就会结束该线程;如果全部满足条件,则调用zlib 1.2.8版的库函数解压接收到的数据。
最后根据解压缩出来的内容选择初始化某个对象,并调用该对象的成员函数,实现恶意功能。
执行完毕后,该线程会进入循环接收新的数据,并执行相应功能。此外,主线程创建了上述之后,会统计当前系统的各种信息:
其中sub_100010F0实现捕获摄像头信息的相关操作。当获取了所有的信息之后,发送给目标地址,目标地址同样挂掉了。最后同样进入发送和接收的循环中。
该样本的恶意功能比较多,现随机展示一个通过匿名双管道实现远程CMD的功能。该功能由编号0x31的分支实现。
详情参考sub_10007DC0函数,该函数首先会调用sub_10004C00 初始化socket,进而调用sub_1000F060创建管道并启动CMD进程:
这个样本并不复杂,但是能够实现较为全面的木马功能,另外通过游戏攻略进行传播,利用白+黑的方式过杀软。哪怕现在HWSignature.dll会被查杀。但有白名单宿主进程的话,绕过杀软并不困难(基本瞬间就能想到好几种绕过检测的方式)。因此这种模式是值得我们警惕的。