“勒索病毒”Ransom/Crowti详细分析报告
注:本文为后期搬运。发布日期以最早时间为准。
一、背景
在火绒前一篇《“勒索病毒”深度分析报告》(http://bbs.huorong.cn/forum.php?mod=viewthread&tid=12856)中,我们针对“勒索病毒”背后的黑色“生态链”及其猖獗泛滥的原因进行了分析。本篇,我们将试图通过代码级分析,更深入地揭开“勒索病毒”的神秘面纱。
CryptoWall病毒(火绒安全软件将其命名为:Ransom/Crowti),可以算是“勒索行业”的元老级病毒了。该病毒家族最早可查是在2013年11月,到2015年底,该病毒”推出”了4.0版本,誓要将勒索进行到底。时至今日,我们仍可以在各种关于勒索病毒的报道中看到图1所示的勒索“温馨提示”:
图1、Ransom/Crowti病毒赎金缴纳说明
二、初步分析
1 统计分析
图2展示的是火绒样本平台统计到的部分Ransom/Crowti样本,其中左边展示了部分样本的可见图标。通过对大量Ransom/Crowti样本的统计,我们发现:
1)该家族样本数量庞大,且样本的静态特征并不相同,这点可以从图2左面的样本图标以及样本哈希(SHA1)看出;
2)真正的Ransom/Crowti 病毒主要代码几乎没有改变,这个结论可以从火绒的检出(Ransom/Crowti.b)得出;
图2、火绒内部样本分析平台展示
通过在虚拟机中动态执行样本并通过火绒剑监控其行为,我们发现2016年的样本和早期样本相比,行为模型几乎完全一样,如图3:
图3、Ransom/Crowti病毒行为模型
正如《“勒索病毒”深度分析报告》中所介绍的,同一个病毒样本,通过“病毒混淆器”的加壳变形,可以在短时间内批量生成”不同“(Unique)的病毒样本。
2 病毒混淆器
早期的病毒批量生成是通过加壳实现的,对同一样本的不同拷贝分别加壳可以产生“不同“(Unique)的样本。现如今的反病毒引擎也基本都可以对这类加壳程序进行识别,并通常都有不同程度的脱壳能力。随着反病毒引擎技术的发展,为了对抗反病毒引擎的脱壳技术,病毒作者开始选择一些“地下壳”或者“私有壳”加密自己的病毒,这类壳也通常有着很强的代码变形能力,我们通常称这类病毒专属的壳为“病毒混淆器“。
随着高级语言编写的”病毒混淆器”(一些国外安全厂商会报出HLLP、HLLW等名字,即High-Level Language Packer/Wrapper)的出现,病毒和反病毒引擎之前的博弈又被推上了一个新的高度。传统扫描引擎对壳的”识别“被颠覆,基于“通用脱壳”(Generic Unpacking)的反病毒引擎应运而生。“通用脱壳”,简单来说,就是不识别特定类型的壳代码,对所有待扫描样本均通过”虚拟沙盒“虚拟执行,进而在虚拟执行的过程中还原可能被”加壳“的代码和数据。
最早的“病毒混淆器“可以追溯到2008-2009年之间出现过的Trojan/C2Lop病毒。其外层的”病毒混淆器“通常被成为Swizzor。这个病毒曾经流行一时,之后销声匿迹,但是在国内某安全论坛在病毒爆发期已过的很长一段时间后,还有该家族样本被上传。图4展示了在国内某安全论坛中搜索Swizzor得到的结果:
图4、某安全论坛对Swizzor的搜索结果
我们通过研究发现,早期的版本Ransom/Crowti是没有被“病毒混淆器“伪装过的,再被安全软件检测后,病毒作者开始使用”病毒混淆器“来对抗安全软件,且在这几年中,该病毒的核心代码却从来没有改变过。图5以图形的形式展示了不同的混淆器之下包裹了相同的Ransom/Crowti病毒。
图5、不同混淆器掩盖下相同的病毒代码
三、详细分析
下面,本文将对两个Ransom/Crowti样本进行详细分析。这两个样本分别是2014年和2016年收集到的,收集时间与样本编译时间相符。如表1所示:
大小 日期 SHA1
516865Thu Jun 05 17:32:07 2014f642ec7fbc4b0f885df2ac8e58c8478198f3c102
203264 Thu Jan 21 08:26:29 20162a8e29ab5d25b5cf1bddd21496dcab0aa8455b24
表1、两个不同时期的Ransom/Crowti样本
图6、火绒对上述样本的扫描结果
1.行为分析
通过在虚拟机中运行上述样本,并通过”火绒剑”监控其行为,可以看出两样本行为几乎完全相同。如图7、图8所示:
图7、f642ec7fbc4b0f885df2ac8e58c8478198f3c102样本行为
图8、2a8e29ab5d25b5cf1bddd21496dcab0aa8455b24样本行为
2.混淆器分析
使用DIE(Detect it Easy)对两个样本进行初步分析,如图9:
图9、 Detect it Easy的检测结果
通过比对DIE的分析结果,可以看出2a8e29ab5d25b5cf1bddd21496dcab0aa8455b24样本第三个节的熵值(Entropy)曲线明显更高,所以DIE提示我们程序可能是被packed过的,虽然未必准确,但是可以帮助我们发现问题。
通过OD调试两个样本就会发现确实如此。该样本在数据段压缩了两段数据 。数据1就是Ransom/Crowti病毒本身(图10中Malware PE部分),数据2是用来加载解密后的病毒代码的Stub Code。该样本使用的“病毒混淆器”逻辑非常简单,整个流程如图10所示:
图10、混淆器还原病毒本体过程
图10中带有混淆器的样本运行后,会调用相同的代码解出两组数据,分别是:Stub Code和Malware PE。其中 Stub Code长度为0x47f,这段代码接收两个参数,第一个参数是Malware PE的内存地址,第二个参数0x2e400是Malware PE的大小。Stub Code动态获得API后(图11),会使用UnmapViewOfFile 卸载原始映像, 使用VirtualAlloc 在原始映像基址上重新分配内存,把解压出来的Malware PE覆盖回去。再根据需要,修重定位、导入表、入口点,映像基址和大小,处理SXS和TLS,最后返回到子PE入口,完成勒索病毒主体的加载。
图11、Stub Code构造的IAT
在解码过程中,混淆器使用了一个超大的循环,用于对付扫描引擎的模拟器(如图10、图12)。代码片段可见到一个5,000,000(0x004c4b40)次的循环,循环内分别调用HeapAlloc和HeapFree两个系统API,没有任何实际功能,虽然这段代码对真实系统不会造成影响,但是会拖慢仿真系统效率,触发仿真超时或者API上限。
图12、通过超大循环对抗反病毒虚拟机
3 病毒主体分析
在步过混淆代码之后,将内存镜像转储为2a8e29ab5d25b5cf1bddd21496dcab0aa8455b24_dump,这个就是勒索病毒Ransom/Crowti的主体。通过对比之前没有使用混淆器的样本,可以看到Ransom/Crowti病毒主要代码几乎没有改变:
1)使用动态API加载技术构造自己的IAT,使用时根据索引获得需要的系统调用(图13);
2)都使用了类似的字符串混淆方式(图14);
3)系统调用的加载顺序,加密算法均使用Windows原生加密API实现;
图13、根据索引调用系统API
图14、相同的字符串构造方式
除了上述细节,后续的流程也是一样:
1)注入到explorer.exe进程里的代码通过APC调用执行;
2)之后将自身文件复制病毒到%APPDATA%目录,并在注册表中创建启动项,实现开机自启动;
3)删除原始病毒文件;
4)通过宿主explorer.exe进程启动svchost.exe进程再次注入;
5)注入explorer.exe的病毒代码会将注册表HKLMSoftwareMicrosoftWindows NtSystemRestore路径下的“DisableSR”键值设置为1,禁止系统还原;
6)执行vssadmin.exe Delete Shadows /All /Quiet删除系统还原备份;
7)勒索代码逻辑在被注入恶意代码的svchost.exe中执行;
对比最早的版本,作者在原有的代码基础之上对加密的细节做出了改进,之后的分析细节只是针对最新版本的Ransom/Crowti(样本2a8e29ab5d25b5cf1bddd21496dcab0aa8455b24)。
通过OD调试,可以在样本2a8e29ab5d25b5cf1bddd21496dcab0aa8455b24注入svchost.exe的代码中解密出以下C&C服务器地址,如图15:
图15、解密出来的服务器地址
病毒向服务器发送编码过的病毒版本信息、本地计算机信息(形如:{1|crypt11001|8616673C99383500088EE2B3C4B27DF7|2|1|2|})等,并请求下载RSA公钥文件。这段数会通过一段自定义加密算法加密,并通过POST方法发送到C&C服务器。图16是截取到的该病毒发送的请求数据:
图16、加密数据
图17、请求RSA公钥和加密流程
如图17所示,请求RSA公钥文件是整个病毒流程的第一步。因为每个文件在加密之前都会调用Windows API CryptGentKey生成一个全新的AES256密钥(图18),AES256密钥用于加密用户数据文件,下载下来的RSA公钥用来加密AES256密钥,公钥只会请求一次,从始至终不会改变,但每个被加密文件所使用的AES256密钥均不相同。这两组密钥最终都会保存到被加密的文件中,只是RSA公钥以MD5的形式保存于文件头(图19),而AES256密钥被RSA加密存放在后面。
恢复用户文件时,可以通过被加密文件头得到RSA公钥MD5,通过查询匹配得到对应解密私钥,根据RSA私钥解密AES256密钥,再根据AES256密钥还原用户数据文件。但由于RSA私钥保存在服务上,受害者的机器上得不到RSA私钥,没有RSA私钥就无法完成AES256密钥的解密,进而无法得到AES256密钥来还原文件。所以,除非保存RSA公钥、私钥的服务器被攻破,否则被加密的文件只能由攻击者解密。
图18、密钥生成及加密流程
图19、不同的被加密文件具有相同RSA公钥文件头
虽然Ransom/Crowti在加密用户文件上考虑的非常缜密,但是如果公钥服务器挂掉,或者我们因为某些特殊原因不能连接到国外网站,Ransom/Crowti就下载不到RSA公钥,只会不断尝试联网下载,从而使受害者免于被勒索。
成功加密后的文件扩展名是随机的(如图20所示),加密完成后会弹出提示(如图1),指导用户如何付费解锁被加密的文件。
图20、加密后文件名随机
四、安全建议
由于“勒索病毒”均采用高强度非对称加密算法对文件进行加密,且在被加密的文件中并不存储解密密钥,所以如果文件被“勒索病毒”加密,还原的可能性非常低。所以,对于“勒索病毒”应采取预防的策略,我们建议:
1)安装合格的安全软件,开启自动更新,保证防护处于打开状态;
2)及时给操作系统和流行软件打补丁;
3)不要点开来源不明的邮件附件,条件允许的话可以交给安全厂商分析附件内容;