这是一例文件夹病毒,手法相对比较高级,通过域名关联到MMCore样本,可能与印度方向APT组织有关联。
这个病毒使用了分离免杀技术,有2个样本,一个加载器,一个payload。
加载器(文件名为dwm22.exe)的主要功能是从C2加载payload在内存执行,若无法连接C2,会解密本地的payload(文件名为tpe64.dll),最终会在内存加载一个反射型dll。
该病毒使用文件夹图标,通过U盘传播,将U盘根目录的目录隐藏,创建同名的副本,诱导用户点击。
这个样本的payload文件(tpe64.dll)使用了多层加密,边解密边执行,并且采用了随机值异或的方式加密,导致每次落地的文件都不一样。
文件大小: 69.5 KB (71,168 字节)
MD5: b36ff48c880c206606a293b6afeb6c20
SHA1: 230a6889fe730d08a3711a9af24ba54e551af15e
SHA256: 169ec38530734ee1f0e8a8c01fa2567feaed2708ba6317cd69ee245021cccd31
CRC32: 657ecd4f
Verified: Unsigned
Link date: 15:48 2013/12/12
MachineType: 32-bit
编译器: EP:Microsoft Visual C/C++(2008-2010)[EXE32]
链接程序: Microsoft Linker(9.0)[GUI32]
这个样本比较简单,主要功能是在内存中加载payload,功能如下图所示
首先解密了两个硬编码的字符串,分别是域名和uri
域名为 adnetwork33.redirectme.net
uri为 /wp-content/themes/booswrap/layers.png
,解密方式如下图所示。
然后将工作目录切换到当前程序目录下。
分配了一个全局数组,主要是存储几个全局变量,这个数组会多次使用,后面会传递给要加载的dll,这时将其命名为 gArgv
,里面的内容如下,前4个参数winmain函数的输入参数,后2个是Payload的信息 。
DWORD gArgv_40BF90[6]
0 hInstance;
1 hPrevInstance;
2 lpCmdLine;
3 nShowCmd;
4 payload文件的内容
5 payload的大小
若当前目录下存在 tpe64.dll
文件,读取其内容存储在 gArgv_40BF90[4]
中,文件大小存储在 gArgv_40BF90[5]
中。
若当前目录下没有tpe64.dll,则从下面链接 下载文件
http://adnetwork33.redirectme.net/wp-content/themes/booswrap/layers.png
保存在 gArgv[4]
中,gArgv[5]
保存其大小,下载失败的话,休眠5s再试
接下来对获取到的tpe64.dll文件内容或下载的payload进行解密,解密首先使用遍历的方式找到异或加密所使用的参数(byte大小),遍历范围为 [0,0x100)
,找到后用这个参数进行解密。(解密后的shellcode开始4字节为 EB 02 CC F1
,后面会看到,这样下面这段代码就比较好理解了)
最后,在内存中加载解密后的payload执行,传递给shellcode有2个参数: 0xDEFACED
和 gArgv
(gArgv是传递给后面的dll用的,0xDEFACED是用于在内存中标记gArgv的位置的,看后面)
为了分析payload的行为,需要动态调试。将dwm22.exe和tpe64.dll放在同一目录下,用OD调试dwm22.exe。
在函数401070处(上一图的函数起始位置)设置断点,单步运行到下面的位置。
可以看到shellcode的位置是0x00230000,gArgv的地址为0x004EB8A0,其中的内容如下。(这两个地址、下面的gArgv[2]和gArgv[4]每次调试会有不同)
00 00 40 00 0 hInstance;
00 00 00 00 1 hPrevInstance;
3C 1D 4D 00 2 lpCmdLine; 内存地址为0X4D1D3C
0A 00 00 00 3 nShowCmd; 0x0000000A = SW_SHOWDEFAULT
00 00 2F 00 4 解密后的payload 内存地址 0x002f0000
95 10 01 00 6 解密后的payload的大小 0x00011095=69781
下面进入shellcode看一下。
这个shellcode比较复杂,总共进行了5次解密。
第一次解密
写成C的伪代码更好理解
char* t = shellcode + 0x4;
short cx = 0x441E;
do
{
*(DWORD*)(t+0x19) ^= 0xBA3B337D;
*(DWORD*)(t+0x19) += 0xBA3B337D;
t+=4;
} while (cx-- > 0);
char* t = shellcode+ 0x26;
short cx = 0x4416;
do
{
*(DWORD*)(t+0x13) ^= 0x687F9462;
*(DWORD*)(t+0x13) += 0x687F9462;
t+=4;
} while (cx-- > 0);
char* t = shellcode+ 0x3E;
short cx = 0x440F;
do
{
*(DWORD*)(t+0x1B) ^= 0x705C17CC;
t +=4;
*(DWORD*)(t+0x17) += 0x705C17CC;
} while (cx-- > 0);
char* t = shellcode+ 0x60;
short cx = 0x4408;
do
{
t +=4;
*(DWORD*)(t+0x11) ^= 0x0CA13F46F;
*(DWORD*)(t+0x11) += 0x0CA13F46F;
} while (cx-- > 0);
char* t = shellcode+ 0x7D;
short cx = 0x4401;
do
{
*(DWORD*)(t+0x14) ^= 0x0D3363D3D;
t +=4;
*(DWORD*)(t+0x10) += 0x0D3363D3D;
} while (cx-- > 0);
为了方便分析,将解密后的shellcode从内存中dump出来。
shellcode地址为0x230000,大小为0x00011095,这里使用pchunter进行dump。
dump出来的文件的hash为
MD5: 9c51e4ec3c555cb13a77e33fce50d739
SHA1: 0c36009e5823e2291abf6d4f0a010c4cff4ee218
下面分析一个上面这个pe加载函数
使用IDA加载dump出来的文件,定位到0x1a95处,F5看伪代码
该函数首先从shellcode+0x1aa2处向前检索PE文件。
然后找到PEB结构,找到kernel32.dll的基址。(dll和后面API都通过name作hash比对找到的,这是shellcode的常用操作)
进而获取LoadLibaryA、GetProcAddress、VirtualAlloc这三个API的地址。
分配内存,复制pe头部和各节,加载导入表的dll,构造导入地址表。
然后进行地址重定位,最后跳转到dll入口执行。
通过上面的分析说明这个dump文件中应该含有一个dll文件,通过010editor很容易实现将这个dll提取出来 。
这个dll的偏移在0x95,大小为0x11000,暂且命名为 0x95-0x11000.dll
,下面重点分析这个dll。
文件大小: 68.0 KB (69,632 字节)
MD5: 6a789f158162d3aa617aa117ff8add2a
SHA1: ca6276a84c251f2d49c4a315b4dd69409b986994
Link date: 17:57 2013/11/18
MachineType: 32-bit
DIE识别的信息:
编译器: EP:Microsoft Visual C/C++(2008-2010)[DLL32]
链接程序: Microsoft Linker(9.0)[DLL32]
这个dll的导出表有两个函数,其中ReflectiveLoader上面已经分析过了,样本的主要功能在DllEntryPoint中
Name Address Ordinal
ReflectiveLoader(void) 10002600 1
DllEntryPoint 100035D0 [main entry]
进入DllMain函数,发现一段有意思的汇编代码,这段代码的功能是在内存中检索0x0DEFACED(这是前文中dwm22.exe中传入的第1个参数,用来标识 gAarv
的位置),检索的范围是[ebp-1ch,ebp+4000000ch],当找到这个标识后,它的下一个位置就是gArgv,就是dwm22.exe中构造的数组。
将找到的gArgv保存到一个全局变量中,将dwm22.exe的基址传递给DoWork_10001320函数,将dwm22.exe的commandline存储在eax中,这样就完成dwm22.exe向dll的参数传递。然后进入DoWork_10001320开始干坏事。
下面进入DoWork_10001320
首先会处理命令行参数(sub_10001D00函数),再根据不同的返回值来执行不同的逻辑,有4种情况。
若参数是空串,即没有参数的话,返回值为0x70000015,这是从U盘中启动的情况,用户点击了伪装成文件夹的病毒副本,将执行感染系统的操作。
情况1是在U盘上执行的情况,情况2-4都是在主机上运行的场景。
首先调用资源管理器打开与当前文件同名的文件夹,用户以为自己打开了一个普通的目录,其实是点击了一个exe。
创建互斥量 B2B27EA7-6F32-4465-8C7C-D2A6E4BAEFA3
,若存在同名的互斥量,退出本实例(返回0x70000011)。
创建目录 C:\ProgramData\WindowMan
,若创建失败的话,会选择 %appdata%
作为宿主目录,将自身拷贝到其中,命名为 dwm22.exe
创建开机启动项:在系统Startup目录中创建一个名为WindowManager.lnk
的快捷方式文件,这个lnk指向 C:\ProgramData\WindowMan\dwm22.exe -c2
或 %appdata%dwm22.exe -c2
。
C:\Users\\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup\WindowManager.lnk
执行C:\ProgramData\WindowMan\dwm22.exe -c2
或 %appdata%dwm22.exe -c2
,若执行成功,退出本实例(返回0x07000013),否则执行后续代码。
若参数为-c1,执行
,返回值为0x70000013,退出本实例
若参数是-c2,设置工作目录为当前程序目录,返回值为 0x70000014
创建名为 B2B27EA7-6F32-4465-8C7C-D2A6E4BAEFA3
的互斥量
若存在同名互斥量,退出(返回0x70000011)
若参数不是-c1也不是-c2,返回值为0xF0000007,执行后续代码
后续代码如下图
首先创建一个名为 BrowserMgr
的窗口,通过windows消息机制,监听DBT_DEVICEARRIVAL类型的消息,检测U盘的插入操作,当有U盘插入时,执行感染操作。
将U盘根目录下的文件夹隐藏,将 tpe64.dll
加密释放到U盘根目录并隐藏,将 dwm22.exe
拷贝成与文件夹同名的文件,诱导用户单击。
在当前目录下创建一个文本文件 x22.dd
,将运行日期、U盘插入的日期和在U盘中创建的副本数记录下来。如下图所示,其中S表示运行,I表示U盘插入,C表示在U盘中创建的副本数。
然后创建一个线程,负责从后台下载载荷执行。
这个线程是个死while循环,首先创建互斥量 GGM-KRTYUA1-B1NHHTYU
,若存在同名的互斥量,跳出。
进而测试网络的连通性,只要与下列地址之一的80端口建立连接即可,不通的话休眠5分钟再试。
74.125.224.112
74.125.224.113
74.125.224.114
74.125.224.115
74.125.224.116
207.46.197.32
207.46.232.182
129.42.38.1
198.133.219.25
若连通的话,从C2下载payload保存为临时文件,
C2地址为
adnetwork33.redirectme.net/wp-content/themes/booswrap/main.php
临时文件名为 %temp%\setupGZ[uuuu].tmp
若下载的文件头两个字节是MZ,说明是一个PE文件,不用解密。
若不是PE格式的话,对其进行解密,从1到0xff开始遍历,寻找加密的使用XOR参数,找到后使用异或解密。
最后执行下载的程序。
文件路径
C:\ProgramData\WindowMan\dwm22.exe
C:\ProgramData\WindowMan\tpe64.dll
C:\ProgramData\WindowMan\x22.dd
%appdata%\dwm22.exe
%appdata%\tpe64.dll
%appdata%\x22.dd 保存感染和U盘记录
%temp%\setupGZ[uuuu].tmp 从C2下载的文件
可移动存储介质
X:\dwm22.exe
X:\tpe64.dll
快捷方式启动项
C:\Users\\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup\WindowManager.lnk
hash
b36ff48c880c206606a293b6afeb6c20 dwm22.exe
9c51e4ec3c555cb13a77e33fce50d739 tpe64.dll解密后的内存dump文件
6a789f158162d3aa617aa117ff8add2a tpe64.dll解密后提取的dll
域名
http://adnetwork33.redirectme.net/wp-content/themes/booswrap/layers.png
http://adnetwork33.redirectme.net/wp-content/themes/booswrap/main.php
User-Agent:
Mozilla/5.0 (Windows NT 5.1) AppleWebKit/535.1 (KHTML, like Gecko)
IP
74.125.224.112
74.125.224.113
74.125.224.114
74.125.224.115
74.125.224.116
207.46.197.32
207.46.232.182
129.42.38.1
198.133.219.25
互斥量
B2B27EA7-6F32-4465-8C7C-D2A6E4BAEFA3
GGM-KRTYUA1-B1NHHTYU
创建了一个名为BrowserMgr的窗口
内存的使用0x0DEFACED标识参数
rule MMCore
{
meta:
description = ""
strings:
$s1 = { 50 32 57 34 5B 36 52 38 4D 3A 4C 3C 52 3E 4D 40 2A 42 70 44 76 46 69 48 3B 4A 2E 4C 29 4E 26 50 23 52 36 54 36 56 23 58 34 5A 3E 5C 73 5E 31 60} //加密的域名
$s2 = { 1E 32 44 34 45 36 1A 38 5A 3A 54 3C 53 3E 4B 40 24 42 2D 44 31 46 68 48 3D 4A 23 4C 28 4E 22 50 34 52 20 54 7A 56 35 58 36 5A 34 5C 2E 5E 28 60 } //加密的Uri
$s3 = { 8A CB 80 C1 31 30 0E 43 46 } //解密算法
condition:
any of them
}
这样样本与MMCore存在一定的关联性
使用IDA打开从内存dump出来的解密后shellcode,可以比较直观的看清楚5层解密
这种多次解密的方式与参考资料1中的图很相似,可以推断出这个样本与MMCore有一定的联系。
adnetwork33.redirectme.net
在参考资料1和2都有提及
这样的样本的的功能比较简单,但是的还是有很高明的地方
确实非常聪明。