病毒名称:
GandCrab2.0(甘地蟹)
MD5值:F42774332FB637650FF0E524CE1B1685
SHA1值:0012363A8A6EFDD93FBD4624EE5E8DDF1F7BE8D5
CRC32:9732F21C
壳信息:
无壳
编写语言:Microsoft Visual C++ v6.0
1.2
测试环境及工具
Win7 x86虚拟机
IDA v6.8
OllyDbg
Dependency Walker
PC Hunter
Procexp
010 Editor
1.3
分析目标
病毒的主要行为
病毒的加密过程
病毒的通信原理
2.具体行为分析
2.1
主要行为
此勒索软件主要是加密用户电脑文件然后要求用户支付虚拟货币来解锁文件,的不是比特币,而是Dash(达世币),还有中文显示外加二维码支付可谓是很贴心。下图为勒索提示信息,你可以按照他们的教程来搭建环境购买虚拟货币来进行文件。
用户支付页面图:
病毒行为预览图:
火绒剑行为分析结果:
1.
病毒的文件操作:
病毒访问还了一个能获取本机外网IP的网站。
2.
病毒的注册表操作
3.
病毒的进程操作:
病毒不断的使用nslookup.exe程序(
是用于诊断工具显示来自
域名系统(DNS)
名称服务器信息的工具
)。
4.
病毒的网络操作
病毒对网络的主要操作就是伪装成火狐浏览器对“66[.]171.248.178”进行访问,这个
IP地址对应的域名其实就是“http[:]//ipv4bot.whatismyipaddress.com”
。
2.1.1
恶意程序对用户造成的危害
对用户指定后缀的文件进行加密,并在每个被感染的文件的文件夹下面产生提示勒索信息的txt文档来引导用户支付虚拟货币来解锁文件。这个样本运行的时候会发现文件并没有加密,程序会打开nslookup.exe无限循环扫描,具体原因会在下面分析中讲解。
2.2
恶意代码分析
2.
2.
1恶意程序的代码分析片段
我们先通过Dependency Walker和Strings工具来看一看样本里有没有可疑的API和字符串。
既然病毒会遍历文件进行加密那么我们用Dependency Walker看到并没有遍历文件的API而且也没有加密相关的函数和注册表相关的可疑函数,但是有枚举资源名称的API(EnumResourceNamesA)如下图所指,那么我们怀疑病毒可能会对资源段进行操作来释放然后执行真正的恶意代码。
Strings字符串工具也没有发现什么有价值的字符串。
使用ResHacker查看资源信息如下图所示,怀疑这就是病毒需要释放的文件,需要重点关注。
将样本拖入IDA,然后OD转到 WinMain函数0x4010B4,然后程序跳转到0x401D40处,IDA转到此处按F5分析。
然后我们OD开始从0x401D40处开始调试。
根据IDA中F5分析的内容往下分析程序,期间会有大量的无用循环和无用的函数来混淆你的分析,例如下图所示部分。这种无意义的循环毫无作用并且浪费时间,我们选择nop掉或者在循环的下面语句F4,或者在指定地方F2下个断点然后F9。同时无意义的函数我们也可以选择F8步过。
往下分析的时候会看到这么一个循环,结合IDA分析可知,有GetMoudleHandleA函数,参数是Kernel32.dll,下面又出现了GetProcAddress函数,参数是GlobalAlloc,所以我们要选择绕过无意义的循环,来得到我们真正的目的—-获得kernel32.dll的地址。然后我们通过kernel32.dll里面的GetProcAddress函数得到GlobalAlloc函数的地址,然后调用GlobalAlloc得到一个新分配的内存句柄如下图所示。
我们接着往下分析会看到调用了EnumResourceNamesA函数枚举资源,然后将资源数据循环复制到新分配的内存中。
下面我们根据IDA 中的分析结果发现病毒调用了VirtualProtect函数更改新分配的内存保护属性为可读可写可执行,然后对这块内存数据进行了解密,然后调用执行内存中的代码。
代码解密函数。
OD中的流程。
然后我们F7进入执行shellcode的那个函数(0x4020BA处那个函数)来到shellcode执行流程处。
下面我们来分析解密出的ShellCode:我们可以通过资源段里面的size计算大小然后从内存中DUMP出来这段shellcode(也就是选中内存中的解密出的shellcode右键二进制复制,然后在010Editor中新建New Hex File 然后选择十六进制方式粘贴保存shellcode.txt即可拖入IDA分析)。
因为由于shellcode是一小段代码,不依赖于系统环境,所以IDA难以F5帮助我们进行静态分析,我们只能通过常见的shellcode编写思路进行分析,首先我们先进入sub_83A函数。
在这个函数中我们发现了常见的定位kernel32.dll基址的操作。
然后循环查找kernel32.dll查到了以后eax==0。
接着往下分析发现了遍历kernel32.dll的导出表来获得GetProcAddress函数的地址。
往下分析会看到通过GetProcAddress得到LoadLibraryA函数地址。
接着往下分析函数返回,进入到sub_3C函数,看到先通过首先通过LoadLibraryA加载kernel32.dll获得kernel32.dll的句柄,然后调用GetProcAddress函数获取VirtualAlloc,VirtualProtect,VirtualFree,GetVersionExA,TerminateProcess的函数地址,方便后续调用。
接下来往下分析,会看到程序申请了大小为0×23400的一块内存空间,我们怀疑他可能要往内存里面再写入东西,所以我们要重点关注这块内存中的数据。
往下运行的时候我们执行完下图函数的时候内存中变成了一个PE文件,根据PE结构可以判断是一个exe文件,所以我们DUMP出来命名为PE1.exe,方便我们用IDA来分析。
解密完PE文件之后他们调用VirtualProtect函数改变这块内存的保护属性
然后调用函数循环复制PE头的内容。
往下分析会看到循环复制区段数据,调用的函数和复制PE头的是一样的。
之后就是PE1数据的执行了,此时不需像之前一样获取kernel32.dll基址再获取API地址了,因为我们解析的是完整的PE文件,文件里有导入表,修复IAT即可
,
下面为修复
IAT过程。
这样整个过程PE数据没有在磁盘落地,可以躲避杀软的文件检测。本来以为这样就可以了,但是病毒又做了一层封装,使用反射式DLL注入。我们来分析我们DUMP出来的PE1.exe(我们不需要修复导入表以后再DUMP,因为我们DUMP出来的exe运行的话系统会自动帮我们修复导入表)
接下来在我们分析PE1.exe的时候会有很多的花指令,我们接下来可以慢慢单步分析可以看到有个地方调用了VirtualProtcet然后我们根据参数address数据窗口中跟随可以看到如下图所示的PE文件(我们查看PE1.exe的导入表发现有VirtualProtect函数所以我们也可以直接在OD下断,bp VirtualProtect,然后运行程序,成功断下,发现地址来自004120C0,查看004120C0处的内存数据发现是个PE文件),然后我们DUMP下来命名为PE2.dll。
因为病毒如果想要运行此DLL的话必须得注入运行,我们查看PE1.exe的导入表发现并没有关于DLL注入的一些API,我们查看一下DLL的导出导入函数发现了这样一条函数,上网搜索发现可能使用了反射式注入DLL的方法
现在我们分析一下PE2.dll的由来,我们在0x4120C0创建硬件写入断点,重新运行程序,发现程序先在0x4120C0处写入一堆数据,然后进行异或操作,最终解密出了核心PE2.Dll
之后程序进入00401113函数,然后在00401069函数中发现了程序寻找导出函数ReflectiveLoader的文件偏移位置的函数,如下图所示。
接着修改内存保护属性,调用ReflectiveLoader。
这时候我们OD和IDA同时跟进ReflectiveLoader函数,看看病毒是如何实现反射注入的,我们打开IDA,把刚刚DUMP下来的PE2.Dll载入,查看导入表,点击进ReflectiveLoader函数结合OD进行分析
往下分析会看到程序通过PEB结构,找到ntdll.dll和kernel32.dll的基址,然后遍历导出函数,找到ntdll.dll中的NtFlushInstructionCache()函数,kernel32.dll中的LoadLibraryA函数,GetProcAddress函数以及VirtualAlloc函数。
然后调用了VirtualAlloc分配了一块新的内存空间。
下面程序将0x4120C0处的PE2.dll文件头和各个节数据复制到新分配的内存空间。接下来程序循环修复PE2.dll的IAT表。和前面修复IAT一样这里就不再赘述。
因为是DLL所以我们在下面还发现了修复PE2.dll的重定位的操作。
下面程序会找到OEP(RVA)。然后加上模块基地址,找到OEP在内存中的地址,接着调用ZwFlushInstructionCache函数,刷新指定进程的指令高速缓存,最后进入OEP.开始最终的病毒 程序的运行。
PE2.dll分析:
拨开云雾见青天,我们终于见到了日思夜想的程序最终的病毒本体,也就是我们DUMP出来的PE2.dll。为了更能清晰的让大家理解这个病毒,我们将这个病毒的核心功能划分成了三个部分来分析:1.初始化部分2.网络部分3.加密文件部分
我们将PE2.dll加载拖入IDA和OD进行动静结合分析,首先我们分析初始化部分。
初始化部分:
首先病毒会创建一个新的线程,我们在线程回调函数处(0x10004B20)下断然后运行至断点处。
接下来程序储存了一些字符串,方便后续获取信息后拼接。接下来通过相关API函数和查询注册表键值得到系统信息,包括用户名,主机名,处理器类型,操作系统版本,IP地址,磁盘空间,系统语言等,之后会对得到的信息拼接,通过调用RtlComputerCrc32函数得到一个加密值。
之后计算一下获取到的信息的长度然后分配一块内存空间,其中重要的ransomid值是利用之前获得的CRC32加密值和其它内存数据拼接成十六进制整数得到的,随后根据拼接成的字符串信息创建唯一互斥体,防止程序多开,否则结束程序,最后清理内存空间
之后病毒程序会创建一个线程来查找卡巴斯基的klif.sys、kl1.sys,F-secure的Fsdfw.sys,赛门铁克的Srtsp.sys、strsp64.sys,诺顿的Navex15.sys、naveng.sys的驱动程序,如果上面的驱动程序存在则退出,否则将自身写入到缓存目录下,通过注册表实现自启动,详细分析如下
因为我们是用的OD的loaddll.exe调试的病毒的DLL而不是用的病毒的宿主exe,所以病毒会将LOADDLL.EXE当成病毒宿主来写入系统临时文件
获取字符串后,创建CSP并通过调用CryptGenRandom获取随机值,然后使用自己的加密方式获取随机字字符串。
最终获取到的随机字符串如下图eax所示,然后下面程序会得到系统环境变量,然后利用上面获取到的随机字符串当作文件名称,和路径拼接在一起,然后将当前模块所在程序(这里为调试病毒DLL的LOADDLL.EXE)的数据按照上面拼接路径写入到新创建的文件。
写入文件的函数。
病毒写入的文件。
接下来病毒生成一个随机字符串作为键,然后设置注册表键值来实现自启动。
接下来退出当前进程后,来到这三个函数
第一个函数病毒可能怕再加密文件的时候文件被一些进程所占用,所以下面病毒开始结束指定进程
下个函数是完善勒索文本信息,首先和之前一样获取系统信息,然后将random_id后的值写入到勒索文本信息{USERID}处。
下面开始密钥导出,程序先申请两块内存空间用于存放公钥和私钥
Microsoft Enhanced Cryptographic Provider v1.0:密钥长度1024位(此次病毒程序使用。
导出的公钥的信息。
导出的私钥信息。
接下来到了病毒核心功能的第二部分:网络部分
网络部分分析:
接下来病毒和前面一样获取主机信息,这次还对获取的输入法主键信息进行了检查,如果是俄罗斯的程序就退出不发动攻击(怀疑此病毒是俄罗斯黑客制作的),同时他们还会对杀毒软件进行检查。
底下还对杀毒软件进行了检查。
下面就是病毒程序伪装火狐浏览器向“ipv4bot[.]whatismyipaddress.com”发送数据并接收,从而得到我的外网IP地址。
将公钥数据和私钥数据进行Base64位编码,并且与获取到的其他系统信息进行整合,最终得到要发送的未加密的信息。
未加密的信息。
随后病毒结合CRC32和自己写的加密算法加密前面的这段未加密信息。
之后病毒会对加密后的数据进行Base64编码,方便发送。
之后病毒会
通过创建的管道打开nslookup.exe子
进程,使用nslookup来对服务器地址进行解析,并且利用管道通信技术读取创建的子进程信息,解析成功则会得到病毒的服务器地址
。
简单介绍一下管道通信,管道是一种用于在进程间共享数据的机制,其实质是一段共享内存,病毒利用了管道进行父子进程的通信,这样子进程就可以直接影响父进程内存。
为实现父子进程间通信,需要对子进程的管道进行重定向:
创建子进程函数 CreateProcess中有一个参数STARUIINFO,默认情况下子进程的输入输出管道是标准输入输出流,可以通过下面的方法实现管道重定向:
STARTUPINFO si;
si.hStdInput = hPipeInputRead; //输入由标准输入 -> 从管道中读取
si.hStdOutput = hPipeOutputWrite; //输出由标准输出 -> 输出到管
由于病毒的服务器已经挂掉了,所以没有解析出地址
没有解析出来地址,程序会进入循环,不断解析malwarehunterteam[.]bit,politiaromana[.]bit,gdcb[.]bit地址,这就是一开始程序不断打开nslookup程序,进入死循环的原因。
因为服务器已经挂掉无法解析服务器地址,所以只能强制跳转,让程序继续运行下去,我们可以修改ZF位或者直接设置新EIP。
加密部分分析:
下面是指定不加密的文件后缀
之后病毒初始化临界区对象,终于来到了病毒的核心,文件加密。
进入加密函数之后,病毒首先会对磁盘类型进行判断,磁盘类型有以下几种
[0]DRIVE_UNKNOWN 无法识别的设备
[1]DRIVE_NO_ROOT_DIR 给出的名字不存在
[2]DRIVE_REMOVABLE 可移动磁盘
[3]DRIVE_FIXED 固定磁盘
[4]DRIVE_REMOTE 网络磁盘
[5]DRIVE_CDROM CD光驱
[6]DRIVE_RAMDISK RAM(内存虚拟盘)
循环获取磁盘类型,然后当磁盘类型符合加密条件的时候,进入加密线程函数,首先指定不加密文件目录,防止因关键目录被加密后系统无法运行。
被过滤的文件目录如下:
·
ProgramData
·
IETldCache
·
Boot
·
Program Files
·
Tor Browser
·
Ransomware
·
All Users
·
Local Settings
Windows
比较后缀名是否是”.sql”
然后病毒创建勒索信息。性感老哥,在线勒索,连支付教程都这么详细,看来走心啦。
接下来会遍历文件,判断是否是目录,是的话递归,不是的话就准备加密。
我在c:python27下面建立了一个test.txt文档,将内容写为aaaaaaa方便我们后续观察病毒首先利用获取到的文件路径得到后缀,然后与前面储存的不加密文件后缀做对。
然后判断文件名是否是以下特殊文件
desktop.ini、autorun.inf、ntuser.dat、iconcache.db、bootsect.bak、boot.ini、ntuser.dat.log、thumbs.db、CRAB-DECRYPT.txt
当文件既不是要过滤的后缀,也不是特殊文件之后,程序来到文件加密函数。先对文件系统属性进行设置,然后拼接成新的文件名。
通过调用CryptGenRandom函数对字符串GandCrabGandCrab随机。
随后得到长度为0×10随机值,命名为R1
同样的,下面对字符串GandCrabGandCrabGandCrabGandCrab随机,得到长 度0×20随机值,命名为R2
之后对随机后的GandCrabGandCrabGandCrabGandCrab值利用之前导出的公钥进行加密
得到加密后的数据,命名为G1
同样,之后对随机后的GandCrabGandCrab值利用之前导出的公钥进行加密,得到加密后的数据,命名为G2。
之后程序通过ReadFile将待加密文件读入到内存空间
这时候前期准备工作完成,病毒开始加。
进入最终加密文件函数后,将源文件数据与R1异或
对文件字节数进行判断,以大小0×10为判断标准,执行不同的加密流程,但最核心的加密函数是一样的
这个函数前期是将原文件与R1异或之后的数据存入4个寄存器,然后4个寄存器再分别于R2分段数据进行异或
之后程序会运行作者自己写的加密算法,很长很长……
获取到最终加密数据之后,设置文件指针,程序开始写入文件,一共写入4段数。
打开010Editer查看加密后的文件,区分四段数据
到此病毒的加密部分分析完毕,下面病毒会进行一些收尾工作。
检查程序运行权限:
检查系统版。
接下来程序会删除磁盘卷影,达到无法还原备份的作用
然后进行自删除。
至此此病毒分析完成,剩下的结尾部分也就不赘述了,此刻电脑上的文件也已经被加密了,大家如果不幸中招想要解密的话可以搜索比特梵德,使用他们的免费解密工具即可。病毒样本我放入了百度网盘中。
(链接:https://pan.baidu.com/s/1EMB0WPVxlQWs8_vTP6eNMg 提取码:fu3o)
3.
防护建议
1、个人电脑、服务器应及时打补丁,修复漏洞
2、对重要的数据文件定期进行非本地备份
3、不要点击来源不明的邮件附件,不从不明网站下载软件
4、尽量关闭不必要的文件共享权限
5、更改账户密码,设置强密码,避免使用统一的密码
6、GandCrab勒索软件会利用RDP(远程桌面协议),如果业务上无需使用RDP的,建议关闭