对GOOTKIT木马有效载荷的分析

xiaohui 恶意软件 2019年9月14日发布
Favorite收藏

导语:在这篇文章中,我们将逆向Gootkit执行的例程以下载和执行Node.js最终有效载荷。我们还将看到如何从可执行文件中提取JS脚本,并简要介绍一些有趣的脚本。

本文是对GOOTKIT木马研究的第3部分——检索最终的有效载荷,前两部分,我们分别介绍了《深入分析Gootkit木马的反分析能力》《对GOOTKIT木马的持久性攻击和其他恶意功能的探索》

在这篇文章中,我们将逆向Gootkit执行的例程以下载和执行Node.js最终有效载荷。我们还将看到如何从可执行文件中提取JS脚本,并简要介绍一些有趣的脚本。

本文使用的样本的MD5:0b50ae28e1c6945d23f59dd2e17b5632

-vwxyz参数

如前所述,Gootkit包含几个参数,这些参数可能影响流程的执行,也可能不影响流程的执行。这个示例中最有趣的参数是——vwxyz,在执行时,Gootkit将重新执行,并将-vwxyz作为参数传递。这将启动负责从C2服务器检索最终Node.js有效载荷,解密并解压缩它,最后执行它。

1.jpg

有效载荷检索函数不是很有规则,实际上,它使用了我在上一篇文章中介绍的相同连接函数。有趣的是,它对C2服务器执行了两个请求,首先请求/ rbody320,然后请求/ rbody32。虽然我所分析的Gootkit的样本是最新的,但C2服务器很快就关闭了,所以我使用了Felix Weyne开发的工具ImaginaryC2工具,以模拟Gootkit C2服务器并分析网络相关路径。因此,Node.js有效载荷可能与此示例不完全相同,但是,它本身也是相当新的。

注:Imaginary C2是一款python工具,可帮助安全研究人员分析恶意软件(网络)行为。Imaginary C2上托管了一个HTTP服务器,用于捕获选定域/IP的HTTP请求。此外,该工具还可用于重放捕获的C&C响应/payloads,使这个过程变得更加方便快捷。

2.jpg

然而,在访问C2之前,Gootkit将首先检查注册表以检查有效载荷是否已经被下载过。这样做的原因是,一旦Gootkit下载进入最后阶段,它将被写入注册表,特别是Software\AppDataLow\ 注册表项,但是,它不是将整个二进制文件存储在一个值下,而是将有效载荷分成几个部分并将每个部分写入值bthusrde_x,其中x对于文件的每个部分递增1。如果注册表已经填充了加密的有效载荷,Gootkit将解密并解压缩有效载荷,然后执行它。但是,Gootkit不会跳过通信例程,而是会访问服务器以检查它是否运行在最后阶段。

3.jpg

在向C2服务器发出第一个请求时,返回由服务器托管的Node.js有效载荷的CRC-32哈希。在本例中,该值为0xB4DC123B,不过由于有效载荷可能发生变化,它会因不同的活动而有所不同。首先将十六进制值与0xFFFFFFFF进行比较,如果存在Software\AppDataLow\bthusrde_0 注册表项,则该示例将把本地加密的有效载荷读入内存,并对数据调用RtlComputeCrc32。然后将该哈希与从C2发送的哈希进行比较,如果匹配,则该过程将在重复检查之前休眠一次随机生成的时间。

如果注册表项不存在,则证明系统之前未被感染。因此,Gootkit将再次访问C2服务器,将/ rbody32附加到URL。

4.jpg

成功下载最后一个阶段后,它将以块的形式写入Software\AppDataLow\bthusrde_x。在本文的示例中,总共创建了9个注册表值来保存整个二进制文件。一旦将其写入注册表,下载程序将在内存中解密并解压缩。解密函数与用于解密配置的函数相同,为了解压,Gootkit将加载并调用RtlDecompressBuffer。解密和解压缩后,生成的文件非常大,大小约为5兆字节。这是因为它包含了大量嵌入其中的Node.js脚本,以及执行这些脚本所需的解释程序。

5.jpg

现在可执行文件已完全解密和解压缩,之后下载程序将复制本地配置。为此,它在下载的可执行文件中查找占位符DDDD,一旦找到,它将使用lstrcpyA()复制配置内的URL。

6.jpg

在执行准备好的有效载荷时,Gootkit采用了一种特殊的方法。下载程序不是将其注入另一个进程或将其作为自己的进程执行,而是在通过调用eax执行它之前,在其自己的进程内部分配内存并将有效载荷映射到其中。如果Node.js有效载荷一直退出,下载程序将简单地循环,解密存储在注册表中的有效载荷并执行它。

7.jpg

在介绍了下载功能之后,让我们继续分析Gootkit的最后阶段。

Node.js的有效载荷

与可以编译的Python和许多其他脚本语言类似,JavaScript可执行程序包含开发人员创建的JavaScript脚本,以及执行脚本所需的解释程序。因此,完全有可能提取Gootkit用于执行其恶意任务的每个脚本。不过前提是只需找到它们即可。幸运的是,这并不难做到。

8.jpg

由于我们寻找的是相当大的数据块(可能是加密的),而不是程序代码,因此只需在IDA中进行一些快速搜索,就可以定位间谍软件、恶意软件、gootkit_crypt和vmx_detection等字符串。对这些字符串执行交叉引用会导致.data部分中出现大型数组列表。每个数组都包含一个字符串,例如gootkit_crypt,一个指向可执行文件中包含加密数据块的地址的指针,以及加密数据的大小。

进一步的交叉引用将我们引向负责解密脚本的函数:

9.jpg

每个脚本都使用RC4加密,并使用ZLib压缩进行压缩。但是,RC4与正常情况略有不同。在本文示例中,Gootkit使用自定义RC4 keystate打乱包含0到256之间值的生成数组,在正常情况下,将使用一个密钥来加扰数组。因此,此keystate需要合并到所开发的任何脚本解密工具中。

10.jpg

解密数据后,前4个字节将包含要解压缩的数据大小,所以确保在解压之前将其从数据中删除,以避免出现错误标头问题。你可以在这里查看Python解密脚本的完整示例!

11.jpg

因此,现在我们有了每个解密的JavaScript文件,并且由于嵌入了字符串,每个脚本的名称!由于专注于每一个脚本可能会花费很长时间,所以我将在这篇文章中介绍这几个脚本:malware.js,uploader.js,gootkit_crypt.js和vmx_detection.js。

Malware.js

malware.js脚本充当Gootkit的JavaScript部分的入口点。它负责查询注册表中前一阶段添加的值,所以mainprocessoverride和vendor_id,并为g_botId等全局变量赋值,可以设置为8.666.jet,或者自定义值。

12.jpg

这个脚本特别有趣的地方是,它后面的参与者已经注释掉了某些函数,比如调用issuspend process(),它检查pythonw.exe的运行进程以及pos_trigger.exe,将USERDOMAIN与7SILVIA进行比较,并调用一个负责检查虚拟机的函数。这给人的印象是,攻击者正集中精力感染尽可能多的程序,无论这些程序是沙箱还是虚拟机,或者它可能引起许多误报,因此删除它是最好的选择。

13.1.jpg

13.2.jpg

该脚本还将使用C2服务器执行签入,将/200附加到URL。其中还有很多日志记录,特别是对日志函数dlog()甚至console.log()的调用,这主要用于调试目的。dlog()将检查环境变量debug_main是否设置为true,如果设置为true,那么所有内容都将被记录到控制台。

14.jpg

Uploader.js

顾名思义,Uploader.js负责将文件上传到远程C2服务器。第一个函数uploadFile()会将所有文件上传到C2服务器,并附加/上载到URL。标头都是硬编码的,包括值X-Bot-ID,其中包含MachineGUID。

所谓MachineGUID,就是Windows安装时会唯一生成一个GUID,可以在注册表“HKEY_MACHINE\SOFTWARE\Microsoft\Cryptography”中查看其“MachineGuid”字段。这个ID作为Windows系统设备的唯一标识不错,不过值得注意的一点是,与硬件ID不一样,这个ID在重装Windows系统后应该不一样了。这样授权软件在重装系统后,可能就需要用户重新购买授权。

15.jpg

下一个函数uploadLogFile()会将日志文件上传到服务器,并将/ logfile附加到URL。除此之外还有另一个日志文件上传函数uploadLogFile2,它将文件上传到附加了/ logfile2的C2服务器。虽然标头信息再次硬编码,但是,还有一个附加价值:X-File-Prefix。

16.jpg

最后,脚本中有一个标记为dope()的函数,该函数完全为空,从未提及过。也许,这是未来更新用的占位符?

17.jpg

Gootkit_crypt.js

Gootkit_crypt.js包含Gootkit用于加密和解密数据的大多数加密和编码算法。打开脚本,你将首先注意到我们之前在Node.js编译的可执行文件中实现的RC4自定义keystate。 Gootkit在其他脚本中使用的三种主要算法是:RC4,TEA和Base64。幸运的是,RC4 keystate和TEA加密密钥都硬编码到脚本中,因此解密网络通信或加密文件应该相当简单。

18.jpg

这个脚本中非常有趣的地方在于,在每个算法之前都会留下一条注释,指出函数是一个原型,这非常奇怪。难道在将它们变成木马之前,攻击人员还要应该对原型进行测试吗?

19.jpg

继续分析后,它们在脚本中也有一个UTF-8函数,尽管这只在TEA和Base64函数内部使用。

20.jpg

了解了这些之后,我们就可以进入最终的、未使用的脚本vmx_detection.js。

Vmx_detection.js

vmx_detection.js脚本会执行上一阶段中存在的所有虚拟机检查;但是,它还有一些额外的检查。

21.jpg

第一个添加的检查是对IDE或SCSI设备的检查,这些设备会经常出现在虚拟机中,通常包含供应商名称,如VBox和VMWare。比如在以下示例中,将查询下面显示的注册表值,并将这些值传递到函数VmCheckVitrualDisks(),该函数会检查字符串VMware,vbox和SONI是否存在。

SYSTEM\\CurrentControlSet\\Enum\\IDE
SYSTEM\\CurrentControlSet\\Enum\\SCSI

如果这些检查成功通过,将执行对CPU的最后一次检查。 CPU值与三个“goodIds”进行比较,分别是GenuineIntel,AuthenticAMD和AMDisbetter!。如果值不匹配,则脚本确定系统是虚拟机并且自动退出。否则,它将返回False,表示系统不是虚拟机。

22.jpg

通过这三篇文章我们希望,你可以对Gootkit的分析有一个明确的思路。将来再遇到新的变体时,可以自行分析!

本文翻译自:https://www.sentinelone.com/blog/gootkit-banking-trojan-retrieving-final-payload/如若转载,请注明原文地址: https://www.4hou.com/malware/20278.html
点赞 4
  • 分享至
取消

感谢您的支持,我会继续努力的!

扫码支持

打开微信扫一扫后点击右上角即可分享哟

发表评论