这是一个Gamarue(又叫Andromeda僵尸网络或仙女座)样本,通过可移动存储介质传播,这个样本的运行过程比较复杂,分为多个阶段,几乎所有的重要操作都是在内存中通过shellcode来完成的,分析起来比较麻烦,现将分析过程记录如下。
病毒的整个执行流量大体如下。
第1阶段 病毒母体 TrustedInstaller.exe
样本的基本信息如下 。
MD5: e14b086a6d42c5e25bc60ff1d112c654
SHA1: 6ce503d230391c27262a36b2f13985fcb8218d0f
SHA256: 4fa723dd51ef2f5eb2db796217c8c86d421a1826af68e8c9513e742de47fea70
Link date: 18:01 2007/3/3
Publisher: n/a
Company: House
Description: Marko
Product: Sunce
Prod version: 3, 0, 0, 0
File version: 1, 3, 4, 7
MachineType: 32-bit
这个样本的主要功能是从资源节中解密出来一个PE,然后创建一个同名的傀儡进程,将解密出来的PE注入到傀儡进程中。
这个样本中有许多无用的花指令,用于对抗分析 。
1.从资源节读取一段二进制数据(资源类型为29,资源名为60),解密出一段字段符,其中包含一系列dll名和api名称,用|分隔,如下图所示。
2.通过LoadLibrary和GetProcAddress获取这些API地址。
3.从资源名63处读取一个字符串,作为解密的key,从资源节中读取了100个分片,将内容拼接在一起,如下图所示(花指令太多)。
4.使用key (FZnZuXhcQc) 解密出来一个完整的PE文件,隐藏病毒母体。
5.创建一个同名的进程(作为傀儡进程),将解密出来的PE注入到傀儡进程的内存空间,然后运行。
6.最后一部分条件由于不满足,不会执行。这部分代码的功能是在系统开始目录下,创建一下快捷方式,用于开机自启动。
傀儡进程技术(又称Process Hollowing技术)可参考傀儡进程技术实现 。
使用OD在4022E0处设置断点,将解密后的PE dump出来。dump出来的样本暂且命名为01E70020_000E87EC.bin。
第2阶段 01E70020_000E87EC.bin(ADropper.exe)内存执行不落地
样本的基本信息如下,根据其pdb路径,可以将命名为ADropper。
文件大小: 929 KB (952,300 字节)
Link date: 23:38 2013/4/9
MD5: B03A1494BDFF7C51B6BC3693D0F3B0DC
SHA1: 2B8A4235F5EB5094D5331D22DC4E061EBAA90F6
SHA256: aac85c2ad3f4354ace6bafa891ac8534300570571d13d7e05c308a69276fe159
pdb path,T:\ldr\CUSTOM\local\local\Release\ADropper.pdb
1.打开互斥量TLS,防双开。
2.遍历系统所有进程,查找名为avp.exe的进程(卡巴斯基杀毒软件的相关程序)。
若系统中没有进程avp.exe,会在临时目录下释放一个PE,保存为%temp%\_install_\msiexec.exe
。
若存在avp进程,根据当前用户是否为管理员,选择不同的路径释放载荷。
-
是管理员的话,保存为
%ALLUSERSPROFILE%\Local Settings\Temp\[8个随机字符].exe
-
不是管理员的话,保存为
%temp%\[8个随机字符].exe
。
在startups
目录创建一个快捷方式文件:%USERPROFILE\StArT meNu\PROGraMs\StaRtup\(empty).lnk
,指向释放的PE。
3.在注册表表中写入两段二进制数据。
第一段二进制数据的va为446F10,大小为719F(这是一个加密的dll,这是病毒的传播模块,后面会用到)。
-
对于管理员用户,写入
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\00E35EEE
。 -
对于非管理员,定稿
HKEY_CURRENT_USER\SOFTWARE\Microsoft\00E35EEE
。
第二段二进制数据是加密后的病毒母体。从0-255中取一个随机数对病毒母体TrustedInstaller.exe进行异或加密,之后存储在注册表HKEY_CURRENT_USER\SOFTWARE\ImageBase
中。(当病毒感染U盘时会用到)
4.最后使用ShellExecute来启动释放的exe。
将释放的样本暂且命名为msiexec.exe。
第3阶段 msiexec.exe
样本的基本信息如下。
Verified: Unsigned
Link date: 9:34 2013/4/8
Publisher: n/a
Company: House
Description: Marko
Product: Sunce
Prod version: 3, 0, 0, 0
File version: 1, 3, 4, 7
MachineType: 32-bit
MD5: 88D67DCABE60BDCF5E225765CEADBD09
SHA1: 5AC7641EDC14DEE9E28F783DA5CEF53F4C1CB18A
SHA256: 092d2e51eeb2aa092dbf35571dd4218877c2b25677299a6c71b60ef2bf5a7ca5
文件大小: 245 KB (250,880 字节)
这个样本与第一阶段的代码基本一致,就是资源节不一样。
1.首先从资源节中解密出一个字符串列表,以|分隔。
2.通过LoadLibrary和GetProcAddress获取一系列要使用的API地址。
3.解密出一个PE文件,解密使用的key为kifheHJSbU
。
4.创建一个同名的傀儡进程,将上面解密出的PE注入傀儡进程。
5.同阶段1一样,创建开机启动项的代码不会执行。
将解密的PEdump出来分析。
第4阶段 00562F08_0001AE56.bin 内存执行不落地
样本的基本信息如下。
文件大小: 107 KB (110,166 字节)
Verified: Unsigned
Link date: 18:46 2013/2/6
MachineType: 32-bit
MD5: E925FDECEC02C92E60032BD5C71BD587
SHA1: dcd8621d3b70ef6cbdf7b478516f0ec66e676bce
SHA256: 7ecdf427b7cde6adc3e6bab7de9c53362c7492d9f3e04b69f47fd419140655c9
1.首先通过PEB的方式,通过比对hash的方式获取了10个api的地址。
通过函数名计算hash的方式如下所示。
#define ROTL32(value, shift) (((DWORD) value << (BYTE) shift) | ((DWORD) value >> (32 - (BYTE) shift)))
int __stdcall GetHash_4010C6(char *a1)
{
int i; // edx
char v3; // al
for ( i = 0; ; i = ROTL32(i, 11) )
{
v3 = *a1++;
if ( !v3 )
break;
*((BYTE*)(&i)) = (v3 | 0x21) ^ i;
}
return i;
}
2.创建命名为lol的互斥量,若存在同名的互斥量,执行va为401778处的shellcode。
3.检测沙箱环境。
首先遍历系统进程,寻找特定的进程,进程名使用hash值匹配,所以无法得出其原始名称,推测应该沙箱或虚拟机相关进程。
检测是否存在sbiedll.dll模块。
查看硬盘的序列号中是否含有wmwa
,vbox
,qemu
关键字。
通过计算两个时钟差来检测是否在调试状态。
4.若第3步中检测不是虚拟机环境,则执行401778处的shellcode,并将sub_4013B9作为shellcode的参数传入。
若当前环境为虚拟机环境中的话,执行403F95处的shellcode。
5.执行shellcode的过程如下图所示,会经过两次解密,地址重定位,建立IAT表,最后跳转到shellcode的入口处执行。
通过OD动态调试,在401153处设置断点。将解密后的将2段shellcode都dump出来,大小和入口点如下 。
第一块shellcode
0x401778
内存地址 0x20000 大小0x490
入口点 0x200c0
第二块shellcode
va 0x403F95
内存地址 0x20000 大小0x4B4
入口点 0x20100
下面重点分析这两段个shellcode。
第5阶段 检测到沙箱 shellcode 0x403F95 内存执行
当检测到沙箱环境时,会运行到这个分支。
通过OD调试,这段shellcode在内存中地址为0x20000(不同的机器不一样),大小为0x4B4,入口点0x20100,将其dump出来,暂且将其命名为20000_4B4_20100.bin。
这段shellcode的功能是将设置开机启动项,设置一个后门。
1.将自身拷贝为%ALLUSERSPROFILE%\svchost.exe
,并隐藏,在注册表中设置开机启动项SunJavaUpdateSched
。
2.监听本地的TCP 8000端口,等待控制端连接,打开一个cmd.exe的shell。
第6阶段 未检测到沙箱 shellcode 0x401778 内存执行
若未检测到沙箱环境,则会运行这个分支。
通过在OD中调试,这段shellcode内存地址 0x20000(不同机器不一致),大小0x490,入口点为0x200c0,将sub_4013B9作为shellcode的第一个参数。将这段shellcode从内存中dump出来,暂且命名为20000_490_200c0.bin。
这段shellcode的功能是将第1个参数进注入到系统进程中,下面详细分析。
1.获取当前程序的路径,存储在环境变量src
中,这是路径是msiexec.exe的路径(这个环境变量在后面会用到)。
2.选择一个系统进程作为傀儡进程,创建并挂起,将本进程的内存注入到这个傀儡进程中(原理同第一阶段)。若是32位信息,选择C:\windows\system32\wuauclt.exe
,若是64位系统,选取C:\windows\\syswow64\svchost.exe
。
3.修改傀儡进程的入口点(如下所示),其中arg0为sub_4013B9,这样傀儡进程启动后就会执行sub_4013B9,最后激活傀儡进程。
使用push + retn来修改函数的返回地址在恶意代码中很常见。
push arg0 ;68 xx xx xx xx
retn ;c3
下面分析回到第4阶段,分析sub_4013B9这个函数。
sub_4013B9
回到第4阶段中,在IDA中定位到sub_4013B9。
这个函数的如下所示,非常简单,就是解密和跳转到0x401BB9代表的shellcode处执行。
下面分析0x401BB9所代表的shellcode。
第7阶段 病毒主体 shellcode 0x401BB9 内存执行不落地
通过OD动态调试,在401153处设置断点,可以将va为0x401BB9所代表的shellcode,解密后的内容提取出来。这段shellcode在内存地址为0x20000(不同机器不一样),大小31A4,入口点0x20BB2。将其dump出来,暂且命名为20000_31A4_20BB2.bin。
这段shellcode执行了病毒的主要功能,下面深入分析一下这段shellcode。
1.获取系统的基本信息。包括C盘的卷序列号(用于唯一标识受害机器,暂且命名为mid)、当前windows的版本、是否在wow64环境,这些信息后面会回传给C2服务器。
2.创建一个与 mid同名的互斥量,防双开。
从环境变量src中取出msiexec.exe的路径(之后清空环境变量src),将其拷贝到临时目录下(区分是管理员和非管理员,保存在不同的路径下),文件名为一段随机字符,后缀名是从exe com scr pif cmd bat com exe
中随机取一个。之后删除msiexec.exe文件。
-
管理员,保存在
%allusersprofile%\Local Settings\Temp
-
非管理员,保存在
%userprofile%\Local Settings\Temp
在注册表中创建开机启动项,指向新创建的文件。
3.创建一个线程, 遍历HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\
下面的键值,若是一段二进制数据,且以0x4034b50开头,对其进行解密,在内存中加载执行。
第二阶段写入的HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\00E35EEE
,此时会被加载执行,解密后是一个dll,其主要功能是用来感染U盘,后面会详细分析。
4.创建一个线程,遍历HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft
的ValueName和ValueData,若ValueData为字符串,切换到%allusersprofile%
目录下,加载以ValueName命名的dll文件,执行其名为以ValueData命名的函数。
5.通过连接www.update.microsoft.com:80
端口或8.8.4.4:53来的测试网络的连通性;
6.创建一个线程,与C2通信,接收并执行C2的指令。
这部分比较复杂。
使用POST方法向C2发送从终端上采集的信息,如下格式,这段信息采用异或和Base64两层加密。
如 id:1147521097|bid:2730|bv:518|sv:1281|pa:0|la:0|ar:1
id 为主机的标识mid
bid 不知道
bv 不知道
sv 表示windows操作系统的版本
pa 表示是否在wow64环境
la 表示是否能连接互联网
ar 表示当前用户是否有管理员权限
C2地址如下图,会依次请求下列域名,直到找到一个可用的,用HTTP协议发送用户信息,请求成功后,会得到C2的响应,经过两次解密,得到明文的响应。
http://xdqzpbcgrvkj.ru/in.php
http://anam0rph.su/in.php
http://orzdwjtvmein.in/in.php
http://ygiudewsqhct.in/in.php
http://bdcrqgonzmwuehky.nl/in.php
http://somicrososoft.ru/in.php
每次的响应中包含多个指令,每个指令包含三部分:任务id,命令的id和参数。
不同的命令id对应不同的操作,下面详细介绍。
命令1
下载一个exe,保存在临时目录下,命名为%temp%\[xxxxxxxx].exe
([xxxxxxxx]为GetTickCount函数的返回值16进制表示),并执行这个exe。
命令2
下载一个dll,在内存中解密并加载。
然后将这段payload写入注册表HKEY_LOCAL_MACHINE\software\\microsoft
,ValueName为8位十六进制字符串。
命令3
响应为一个PE,打开注册表 HKLM\software\microsoft\windows\currentversion\Policies\Explorer\Run
,
-
若存在与g_mid同名(十六进制字符串)开机启动项,替换对应的PE,并运行程序。
-
若不存在与g_mid同名的开机启动项,根据当前时间生成一个随机的文件名
%tmp%\[xxxxxxxx].exe
,释放这个PE,并运行它。
命令4,
这个命令的是参数格式为 url,funcname,url为dll的下载地址,funcname为dll的导出函数。从url下载payload保存为%allusersprofile%\ms[xxxxxxxx].dat
,加载这个dll,执行funcname对应的函数,将这个dll的文件名和导出函数名写入注册表。如HKLM\software\microsoft\ms[xxxxxxxx].dat=funcname
。
命令5
删除上面在HKLM\software\microsoft中存储的注册表项和对应的dll文件,其实是命令4的反操作。
命令6
删除HKLM\software\\microsoft
下,ValueData为二进制的项。找到HKLM\software\microsoft\windows\currentversion\Policies\Explorer\Run\[mid]
对应的exe,使用CreateProcess运行它。
命令9
自毁操作,清理注册表HKLM\software\microsoft
下的所有项,删除HKLM\software\microsoft\windows\currentversion\Policies\Explorer\Run
下病毒的开机启动项和对应的病毒文件。
命令执行完后,以下面的格式返回命令执行的结果,其中id为主机id,tid为任务id(C2返回的),result为命令执行的结果 ,将这段字符串通过两层加密后回传。
j_wsprintfA_20120(a4, "id:%lu|tid:%lu|result:%lu", g_mid, taskid_a1, result_v10)
第8阶段 注册表中00E35EEE部分 Worm65.DLL
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\00E35EEE
这部分存储了一个dll,解密在内存中加载这个dll,将其从内存中dump出来。
根据其pdb路径,将这个样本暂且命名为Worm65.DLL。
样本的基本信息如下。
文件大小: 58.5 KB (59,904 字节)
MD5: acec8a24bd1d8c705f3b466838586881
SHA1: 725483e909fdf41ac0c18e8e8bbe71bc4ca57240
SHA256: 634cbc61965fefc758240acde714e49ccbf25442e4cfa1ef5c0694a7dee0ca16
pdb path,T:\ldr\CUSTOM\local\Worm65.DLL.PnP\Release\Worm65.DLL.pdb
Verified: Unsigned
Link date: 22:59 2013/4/9
这一部分主要执行U盘的感染操作,原理比较简单。
1.创建一个互斥量TLS,防双开,然后创建一个线程来执行感染操作。
2.在注册表HKEY_CURRENT_USER\Software下写入3段二进制内容,若能连网,会向C2请求更新这三段内容(这三段内容后续会写入U盘)。
HKEY_CURRENT_USER\Software\IMAGE_FILE_HEADER va 1000D9C0 大小为0xE00u
对应的URL为http://pe.suckmycocklameavindustry.in/+一个随机字符串
HKEY_CURRENT_USER\Software\DOS_STUB va 1000CE50 大小为 0xB70u
对应的URL为http://sc.suckmycocklameavindustry.in/+一个随机字符串
HKEY_CURRENT_USER\Software\ImageBase va为1000CDC0 0xBu
对应的URL为http://img.suckmycocklameavindustry.in/+一个随机字符串
3.通过设置注册表,来隐藏文件后缀名。
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced\ShowSuperHidden = 0
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced\Hidden = 2
4.遍历系统中所有的驱动器盘符,找到可移动存储介质进行感染。
5.感染的原理也很简单,创建一个隐藏的文件夹,名为X:\<A0>\
,将U盘中其它的文件移动到这个目录下,在U盘的根目录下创建4个文件,如下所示,除了Lnk文件其它都是隐藏文件。lnk文件的图标为系统驱动器图标,诱导用户点击。
X:\_W[小于10个随机字符串].init 这是一个dll 来自注册表IMAGE_FILE_HEADER部分解密
X:\desktop.ini 这是一段加密的shellcode 来自注册表DOS_STUB部分解密后
X:\Thumbs.db ImageBase部分
Removable Disk ([U盘的剩余空间]GB).lnk 一个快捷方式 target指向 X:\_W[小于10个随机字符串].init crys
6.创建一个隐藏的窗口,窗口名为#usb#
,通过处理WM_DEVICECHANGE消息,监控可移动存储介质的插入和拔出操作,当有U盘插入时,对其进行感染。
U盘感染后的迹象
还有几个隐藏的文件用户看不到,如下图所示。
快捷方式的target为C:\WINDOWS\system32\rundll32.exe _WUPXUDEBNZ.init,crys ukapf aukukapfukapfukapfpfukaf
,说明_WUPXUDEBNZ.init是一个dll。
去掉desktop.ini Thumbs.db _WUPXUDEBNZ.init
这三个文件的系统和隐藏属性,下面重点分析一下U盘上这三个文件。
第9阶段 加载器 dll _WXXXXXX.init
样本的基本信息
文件大小: 5.00 KB (5,128 字节)
修改时间: 2024年01月16日,16:54:20
MD5: bcc4c0f581b3d2f699666da0ad5d4a86
SHA1: 590e46d3fd91c3babdc545cd15cd6467cda77655
SHA256: 47113606cba9e677cb26a3d0d6385418884ef8aaaddab176e0aa6e645741beee
Link date: 21:59 2013/4/9
这是一个dll,主要功能是crys导出函数中,功能很简单,
1.首先打开同目录的名为<A0>
的文件夹
2.读取同目录下的desktop.ini文件,作为shellcode执行。
第10阶段 desktop.ini shellcode
样本的基本信息
文件大小: 2.86 KB (2,937 字节)
修改时间: 2024年01月16日,16:54:20
MD5: f49289ae45d0e46f44bfd3a6f5d60fa3
SHA1: 6b45dc8ac445013b0a391c4b1382879b267a00b4
SHA256: 702aca804b4f1a7a6dff1192cd295d23ced8a492fe8a66af1d66d23154f063d2
这是一段shellcode。这段shellcode的功能也很简单。
1.首先通过PEB和hash的方式获取了LoadLibraryA和GetProcAddress两个API的地址。
2.通过LoadLibraryA和GetProcAddress获取一系列需要用的API的地址。
3.创建了名为TLS的互斥量,防双开,调用URLDownloadToFileA从http://suckmycocklameavindustry.in/
下载文件更新本地的Thumbs.db文件。
4.从Thumbs.db
文件读取内容,解密后保存为heap.exe
(创建C:\TEMP
目录失败的情况下)或C:\\TEMP\\TrustedInstaller.exe
;执行C:\\TEMP\\TrustedInstaller.exe
,或者执行heap.exe
后将其删除(创建C:\TEMP
目录失败的情况下)。
这样就回到了第1阶段了,完成感染过程。
IOC
U盘:
X:\_W[小于10个随机字符串].init 这是一个dll
X:\desktop.ini 这是一段加密的shellcode
X:\Thumbs.db 加密的病毒母体
Removable Disk ([U盘的剩余空间]GB).lnk 一个快捷方式 target指向 X:\_W[小于10个随机字符串].init crys
X:\<A0>\ 一个隐藏目录,用于存储U盘中原来的所有文件
系统中
C:\TEMP\TrustedInstaller.exe 病毒母体 运行后会自毁
%temp%\_install_\msiexec.exe 释放的文件
%ALLUSERSPROFILE%\Local Settings\Temp\[8个随机字符].exe msiexec.exe的副本
%temp%\[8个随机字符].exe msiexec.exe的副本
%USERPROFILE\StArT meNu\PROGraMs\StaRtup\(empty).lnk 指向 msiexec.exe的副本
%ALLUSERSPROFILE%\svchost.exe msiexec的副本
%allusersprofile%\Local Settings\Temp\xxxxx.[exe|com|scr|pif|cmd|bat] msiexec.exe的副本或从后台下载的exe
%userprofile%\Local Settings\Temp\xxxxx.[exe|com|scr|pif|cmd|bat] msiexec.exe的副本或从后台下载的exe
%temp%\[xxxxxxxx].exe 从C2下载的exe
%tmp%\[xxxxxxxx].exe 从C2下载的exe
%allusersprofile%\ms[xxxxxxxx].dat 从C2下载的dll
hash:
e14b086a6d42c5e25bc60ff1d112c654 TrustedInstaller.exe
88D67DCABE60BDCF5E225765CEADBD09 msiexec.exe
bcc4c0f581b3d2f699666da0ad5d4a86 X:\_W[小于10个随机字符串].init
f49289ae45d0e46f44bfd3a6f5d60fa3 X:\Desktop.ini
B03A1494BDFF7C51B6BC3693D0F3B0DC ADropper.exe 在内存中不落地
E925FDECEC02C92E60032BD5C71BD587 PE 在内存中不落地
url
http://suckmycocklameavindustry.in/ 用于更新病毒母体
这几个是C2
http://xdqzpbcgrvkj.ru/in.php
http://anam0rph.su/in.php
http://orzdwjtvmein.in/in.php
http://ygiudewsqhct.in/in.php
http://bdcrqgonzmwuehky.nl/in.php
http://somicrososoft.ru/in.php
用于更新U盘传播模块
http://pe.suckmycocklameavindustry.in/+一个随机字符串
http://sc.suckmycocklameavindustry.in/+一个随机字符串
http://img.suckmycocklameavindustry.in/+一个随机字符串
这三个来测试网络连通性
www.update.microsoft.com
8.8.8.8
8.8.4.4.
User-Agent
Mozilla/4.0
注册表
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\xxxxxxxx REG_BINARY 这是一个加密的dll
HKEY_CURRENT_USER\SOFTWARE\Microsoft\xxxxxxxx
HKLM\software\microsoft\[dllname]=[funcname] 记录恶意dll的文件名和导入函数
HKLM\software\microsoft\windows\currentversion\Policies\Explorer\Run\SunJavaUpdateSched
HKCU\software\microsoft\windows\currentversion\Policies\Explorer\Run\SunJavaUpdateSched
HKLM\software\microsoft\windows\currentversion\Policies\Explorer\Run\51273
HKCU\software\microsoft\windows\currentversion\Policies\Explorer\Run\51273
HKEY_CURRENT_USER\Software\IMAGE_FILE_HEADER U中的加载器
HKEY_CURRENT_USER\Software\DOS_STUB U盘中shellcode
HKEY_CURRENT_USER\Software\ImageBase 加密的病毒母体
隐藏文件后缀名
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced\ShowSuperHidden = 0
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced\Hidden = 2
互斥量 防双开
TLS
LOL
窗口 用于监控U盘的插入
#usb#
总结
Gamarue原来是全球最大的僵尸网络,变种很多,本文中的样本使用了多种规避检测的技术,包括傀儡进程、检测沙箱和分离免杀等技术,虽然这是10年前的样本,现在依然具有学习的价值。