使用卷序列号作为加密密钥:APT恶意软件LOWKEY分析

41yf1sh 恶意软件 2019年11月13日发布
Favorite收藏

导语:本文主要分析了我们发现的一个复杂、被动型后门,在关于APT41的报告中曾经提到,并且在最近的FireEye Cyber Defense Summit会议上与大家进行了分享。

概述

在2019年8月,FireEye发布了有关最新发现的威胁组织——APT41的“Double Dragon”报告。APT41是一个与亚洲某国家联系紧密的双重间谍组织,聚焦于财务领域,该恶意组织主要针对游戏、医疗保健、高科技、高等教育、电信和旅游服务等行业。

本文主要分析了我们发现的一个复杂、被动型后门,在关于APT41的报告中曾经提到,并且在最近的FireEye Cyber Defense Summit会议上与大家进行了分享。我们观察到,LOWKEY被用于一些针对性非常强的实际攻击之中,并利用仅能在特定系统上运行的Payload。文章中还使用了其他恶意软件家族名称,并进行了简要描述。有关APT41使用的恶意软件的完整概述,请参阅APT41报告中的技术附录部分。

本文主要分为三个部分:第一部分描述了我们如何分析加密的Payload;第二部分主要描述了我们在多个样本的不同位置中发现的加载器,该加载器经过一层混淆;最后一部分分析LOWKEY后门,该后门有两个变种,分别是针对IIS的被动TCP监听器和被动HTTP监听器。

1.png

DEADEYE – RC5

我们持续跟踪过去几个月中的APT41恶意活动,观察到有多个样本都具有两个独特之处:(1)使用不常见的RC5加密算法;(2)包含唯一的字符串“[email protected]!rCto R$.”。基于此,我们将这些样本命名为DEADEYE。

DEADEYE有多个变种:

(1)DEADEYE.DOWN可以下载其他Payload;
(2)DEADEYE.APPEND附加了其他Payload;

(3)DEADEYE.EXT可以加载系统上已经存在的Payload。

接下来,我们分别对这些变种进行详细分析。

(1)DEADEYE.DOWN

通过对一个DEADEYE.DOWN样本(MD5:5322816c2567198ad3dfc53d99567d6e)进行分析,我们发现它在首次执行恶意软件时,会下载两个文件。

第一个文件是从hxxp://checkin.travelsanignacio[.]com/static/20170730.jpg下载的。首先恶意软件会使用密钥“wsprintfA”对RC5的命令和控制(C2)服务器进行解密,随后使用其他密钥对RC5进行加密,并将其以<MODULE_NAME>.mui的形式写入磁盘中。

RC5密钥是基于C盘驱动器的卷序列号构造的。卷序列号是一个长度为4字节的值,通常基于系统安装时间生成。卷序列号与硬编码后的常量“[email protected]!rCto R$.”进行异或,然后转换为十六进制,生成最长为28个字节的密钥。如果异或后的值包含嵌入式的零字节,则秘钥长度可能会有所不同,因为lstrlenA API调用会确定密钥的长度。请注意,在将结果转换为十六进制之前,就会先进行lstrlenA API调用。如果字节模4的索引为0,则十六进制转换为大写表示。下面展示了密钥派生的过程。

卷C驱动器的序列号,我们以0xAABBCCDD为例。

F ^ 0xAA = 0xCC 大写
@ ^ 0xBB = 0xFB 小写
U ^ 0xCC = 0x99 小写
k ^ 0xDD = 0xB6 小写
d ^ 0xAA = 0xCE 大写
! ^ 0xBB = 0x9A 小写
r ^ 0xCC = 0xBE 小写
C ^ 0xDD = 0x9E 小写
t ^ 0xAA = 0xDE 大写
o ^ 0xBB = 0xD4 小写
(0x20) ^ 0xCC = 0xEC 小写
R ^ 0xDD = 0x8F 小写
$ ^ 0xAA = 0x8E 大写
. ^ 0xBB = 0x95 小写

最终得到密钥:CCfb99b6CE9abe9eDEd4ec8f8E95。

第二个文件是从hxxp://checkin.travelsanignacio[.]com/static/20160204.jpg下载的。在将C2的响应保存到C:\Windows\System32\wcnapi.mui之前,首先使用密钥“wsprintfA”进行RC5解密,然后将其与0x74进行异或。

2.png

随后,该样本确定其自己的模块名称,将扩展名mui附加到其后面,并尝试使用RC5算法对改文件解密。这样一来,此前下载并存储在系统上的恶意软件文件就已经被有效解密。由于已经使用基于卷序列号的密钥对文件进行了加密,因此只能在下载了该文件的系统上,或者是具有相同卷序列号的系统上执行该文件,后者的可能性非常小。

我们的样本mui文件,MD5值为e58d4072c56a5dd3cc5cf768b8f37e5e。在十六进制编辑器中查看加密的文件,我们发现显示的熵(Entropy)非常高(7.999779/8)。RC5在默认情况下会使用电子密码本(ECB)模式,也就意味着相同的明文块始终会产生相同的密文,而与其在二进制文件中的位置无关。该文件总计792933字节,但几乎没有重复的密码块,这意味着数据可能有额外的加密层。

如果没有正确的卷序列号,或者如果没有任何关于明文的线索,那么我们无法仅凭借样本来解密Payload(e58d4072c56a5dd3cc5cf768b8f37e5e)。

(2)DEADEYE.APPEND

幸运的是,结合RC5中的组件,通过搜索唯一的字符串“[email protected]!rCto R$.”我们可以发现更多样本。其中的一个样本是DEADEYE.APPEND(MD5:37e100dd8b2ad8b301b130c2bca3f1ea),此前已经由Kaspersky进行过分析。该样本与其他样本有所不同,因为它受到了VMProtect的保护,并附加了混淆的二进制文件。嵌入式二进制文件从偏移量3287552开始,如下图所示,其中文件大小与PE大小不同。

3.png

加密后Payload的熵稍低,为7.990713。在十六进制编辑器中,我们查看嵌入式二进制文件,会发现多次出现连续字节“51 36 94 A4 26 5B 0F 19”(如下图所示)。如果在加密数据中间连续使用两次,并且使用的是ECB模式,那么我们猜测明文应该是00 00 00 00 00 00 00 00。

37e100dd8b2ad8b301b130c2bca3f1ea样本中重复出现的连续字节:

4.png

RC5暴力破解

有了这些知识后,我们决定采用RC5的参考实现,并添加一个主要函数,该函数说明了恶意软件样本所使用的密钥派生算法(如下图所示)。因为密钥是从单个DWORD派生的,因此就存在暴力破解的可能性。即使最终密钥长度是28个字节,那么也只有4294967296个可能的密钥。下图展示的代码会生成所有可能的卷序列号,并从中导出密钥,然后尝试解密从51 36 94 A4 26 5B 0F 19到00 00 00 00 00 00 00 00。在运行RC5暴力破解程序几分钟后,我们就得到了恶意样本中正确的卷序列号,也就是0xc25cff4c。

请自行选择是否要使用暴力破解的方式。

我们在参考实现中使用的密钥的DWORD由全局c表示,我们必须将其更改为7,以匹配恶意软件28字节的密钥长度。转换过程中出现了一些问题,因为在恶意软件中,生成密钥内的零字节最终会导致密钥长度变短。我们的实现使用硬编码的密钥长度(c),因此这里生成了c = 6,c = 5,c = 4…这样的多个可执行文件,因为这些可执行文件通常只运行了几分钟才能覆盖整个密钥空间。附录1中涉及的所有样本,都可以使用c = 7或c = 6计算出来。

RC5暴力破解工具的主要函数:

5.png

解密后的Payload属于恶意软件家族POISONPLUG(MD5:84b69b5d14ba5c5c9258370c9505438f)。POISONPLUG是具有插件功能、经过高度混淆的模块化后门。该恶意软件具有注册表/服务持久性、自我删除、执行插件和转发网络连接的功能。我们已经观察到POISONPLUG开始使用社交平台上托管的编码后命令和控制命令。

我们确认了Kaspersky此前的发现,并且发现了第二个命令和控制URL,是hxxps://steamcommunity[.]com/id/oswal053,我们在APT41的报告中也说明了这一点。

综合考虑我们研究DEADEYE.APPEND(MD5:37e100dd8b2ad8b301b130c2bca3f1ea)所获得的成果,我们决定再次查看加密的mui文件(e58d4072c56a5dd3cc5cf768b8f37e5e)。我们尝试强行将第一个字节与解密后POISONPLUG Payload的字节匹配,没有产生任何结果。

幸运的是,我们发现了使用相同加密方案的其他样本。在其中一个样本中,恶意软件作者进行了两次检查,以验证解密后的Payload。下面是DEADEYE.APPEND(MD5:7f05d410dc0d1b0e7a3fcc6cdda7a2ff)在指定偏移量处的预期纯文本。

偏移量及解密后的预期字节:

0     0x48
1     0x8B
0x3C0     0x48
0x3C1     0x83

将上述约束应用到我们的暴力破解工具中,然后再尝试对mui文件(e58d4072c56a5dd3cc5cf768b8f37e5e)进行解密,这将再次导致成功命中所需尝试的次数减少,我们可以手动对其进行确认。我们已经知道,加密mui的正确卷序列号是0x243e2562。经过分析,确认解密后的文件是XMRig挖矿工具。这也解释了为什么投放工具会下载两个文件。第一个<MODULE_NAME>.mui是加密货币挖矿工具,第二个C:\Windows\System32\wcnapi.mui是配置。解密的mui包含另一层混淆,并最终使用命令x -c wcnapi.mui执行。在本文的下一章,我们将解释如何获取命令以及附加的混淆层。

有关带有相应卷序列号的恶意样本列表,请参考附录1。

附加的RC4层

在APT41使用的投放工具中,我们还发现了额外的RC4层,我们在内部将其命名为DEADEYE。ESET此前已经在文章中详细介绍了该层,由于我们成功对一些样本进行了暴力破解,因此我们希望分享关于附加层的一些额外信息。

附加层是包含反射型DLL加载工具的Shellcode,这段Shellcode独立运行,与出现位置无关。加载程序解密RC4加密的Payload,并将其加载到内存中。这段代码本身是一个简单的加载工具,但我们在分析过程中发现了其中包含一些值得关注的组件。

正如ESET在文章中提到的那样,加密的Payload前面带有标头。其中包含RC4加密密钥和两个长度可变的字段,这些字段此前已经被标识为文件名。这两个字段使用相同的RC4加密密钥进行加密,该密钥也被用于解密Payload。下面列举了这些标头,并说明其具体含义:

0 - 15:以0x37编码后使用RC4密钥进行异或
16 - 19:标头之前的加载工具的存根(Stub)大小
20 - 23:RC4密钥大小
24 - 27:命令ASCII大小(CAS)
28 - 31:命令UNICODE大小(CUS)
32 - 35:加密Payload的大小
36 - 39:执行类型
40 - (40+CAS):命令ASCII
(40+CAS) – (40+CAS+CUS):命令UNICODE
(40+CAS+CUS) – (40+CAS+CUS+加密Payload的大小):加密的Payload

通过查看隐藏在RC5层后面的Payload,我们观察到这些字段不仅限于文件名,还可以包含反射型加载程序使用的命令。如果未指定命令,则默认参数是已加载的Payload的文件名。在某些情况下,这里体现了开发环境下的完整文件路径和文件名。下面列举了一些路径和文件名,这也是我们从文章第一部分中找到的用于启动解密后mui文件的命令(x -c wcnapi.mui)。

解密后的路径和文件名:

7f05d410dc0d1b0e7a3fcc6cdda7a2ff - E:\code\PortReuse\3389-share\DeviceIOContrl-Hook\v1.3-53\Inner-Loader\x64\Release\Inner-Loader.dll
7f05d410dc0d1b0e7a3fcc6cdda7a2ff - E:\code\PortReuse\3389-share\DeviceIOContrl-Hook\v1.3-53\SK3.x\x64\Release\SK3.x.exe
7f05d410dc0d1b0e7a3fcc6cdda7a2ff - UserFunction.dll
7f05d410dc0d1b0e7a3fcc6cdda7a2ff - ProcTran.dll
c11dd805de683822bf4922aecb9bfef5 - E:\code\PortReuse\iis-share\2.5\IIS_Share\x64\Release\IIS_Share.dll
c11dd805de683822bf4922aecb9bfef5 - UserFunction.dll
c11dd805de683822bf4922aecb9bfef5 - ProcTran.dll

LOWKEY分析

最后,我们对DEADEYE.APPEND(MD5:7f05d410dc0d1b0e7a3fcc6cdda7a2ff)解密后的被动后门LOWKEY(MD5:8aab5e2834feb68bb645e0bad4fa10bd)进行分析。LOWKEY是一个被动型的后门,它支持反向Shell、上传和下载文件、列出并终止进程以及文件管理等命令。目前,我们已经确定LOWKEY后门的两个变种。

第一个是侦听53端口的TCP变种,第二个是侦听TCP/80端口的HTTP变种。HTTP变种拦截与URL后缀http://+:80/requested.html相匹配的URL请求。该URL中的“+”表示它可以与任何主机名相匹配。Kaspersky此前将其简称为“未知后门”。

这两个变种都是由前文所述的反射型加载工具加载。这也就意味着,我们能够提取原始文件名。在原始文件名中包含着有意义的名称,可以给我们有关后门操作方式的第一条提示。

HTTP变种(MD5:c11dd805de683822bf4922aecb9bfef5) – E:\code\PortReuse\iis-share\2.5\IIS_Share\x64\Release\IIS_Share.dll

TCP变种(MD5:7f05d410dc0d1b0e7a3fcc6cdda7a2ff) – E:\code\PortReuse\3389-share\DeviceIOContrl-Hook\v1.3-53\SK3.x\x64\Release\SK3.x.exe

值得关注的部分如下图所示,PortReuse描述了后门的通用思路,在常用的端口上进行操作。在其路径中,还包含版本号2.5和v1.3-53。IIS_Share用于HTTP变种,并且描述了目标应用程序,DeviceIOContrl-Hook被用于TCP变种上。

概述可执行路径的重要部分:

6.png

两个LOWKEY变种在功能上均相同,但有一个地方例外。TCP变种依赖于第二个组件,也就是能够拦截传入TCP连接的用户模式Rootkit。开发人员在开发过程中为该组件制定的内部名称是:

E:\code\PortReuse\3389-share\DeviceIOContrl-Hook\v1.3-53\NetAgent\x64\Release\NetAgent.exe。

LOWKEY组件:

7.png

关于Inner-Loader.dll

Inner-Loader.dll是LOWKEY后门的守护程序。它利用GetExtendedTcpTable API检索存在打开的TCP连接的所有进程。如果某个进程正在侦听TCP/53端口,就会将NetAgent.exe注入到该进程中。这是在10秒的延迟时间内完成的。在成功注入NetAgent.exe之后,加载程序退出循环。在注入之后,它将为LOWKEY后门(SK3.x.exe)创建一个新的线程。

守护程序陷入了一个死循环之中,会每隔20分钟执行一次,并确保NetAgent.exe和LOWKEY后门仍然处于活动状态。如果任何一个程序未处于活动状态,那么它会重新启动后门,或重新注入NetAgent.exe。

关于NetAgent.exe

NetAgent.exe是一个用户模式的Rootkit,提供与LOWKEY后门组件的秘密通信。在收到字节序列FF FF 01 00 00 01 00 00 00 00 00 00后,它将传入的数据包转发到命名管道\\.\pipe\Microsoft Ole Object {30000-7100-12985-00001-00001}。

这个组件通过挂钩NtDeviceIoControlFile来工作。它通过分配一个可疑的大内存区域(用作全局挂钩标)来实现。该表由0x668A0字节组成,并具有读取、写入和执行权限的集合。

每个挂钩的表条目都包含3个指针。其中,第一个指向包含每个已挂钩函数的原始11个字节的内存,第二个指向包含指向其他原始指令的指针,第三个指向存储函数挂钩的指针。恶意软件只会以这种方式对其中的一个函数进行挂钩,因此会分配不必要的大量内存。这种恶意软件旨在通过何种方式,连接过多达10000个功能。

挂钩函数从迭代全局挂钩表开始,然后将指向挂钩函数的指针与其自身相比较。这样一来,就可以找到已安装挂钩的原始说明,在本文示例中为NtDeviceIoControlFile。随后,恶意软件执行已经保存的指令,从而导致常规的NtDeviceIoControlFile API调用。之后,将NtDeviceIoControlFile与0x12017(AFD_RECV)进行比较。

如果IoControlCode不匹配,那么就返回原始API调用结果。

如果匹配,恶意软件将比较传入数据的12个字节。由于它实质上是一个TCP数据包,因此它也正在解析TCP标头来获取该数据包的数据。将数据的前12个字节与硬编码的字节模式进行比较,得到:FF FF 01 00 00 01 00 00 00 00 00 00。

如果它们匹配,则期望接收没有使用的附加数据,然后以十六字节的标头响应00 00 00 00 00 91 03 00 00 00 00 00 80 1F 00 00,表示以下数据包被转发到命名管道\\.\pipe\Microsoft Ole Object {30000-7100-12985-00001-00001}。后门组件(SK3.x.exe)接收数据,并将数据发送到命名管道。挂钩函数会将所有接收到的数据从命名管道转发回套接字,从而有效地允许命名管道与套接字之间进行秘密通信。

关于SK3.x.exe

SK3.x.exe是实际的后门组件,它支持写入和读取文件、修改文件属性、交互式命令Shell、TCP中继功能以及列出正在运行的进程。后门将打开一个命名管道\\.\pipe\Microsoft Ole Object {30000-7100-12985-00001-00001}以进行通信。

后门在收到数据后,使用密钥“CreateThread”通过RC4进行加密,然后与0x77进行异或。后门发送的所有数据都会以相反的顺序(首先使用0x77进行异或,然后使用密钥“CreateThread”对其进行RC4加密)使用相同的加密方式进行处理。加密的数据是一个16字节的标头,该标头未经加密,包含标识符及后续加密后数据包的大小。

标头示例如下所示:

00 00 00 00 00 FD 00 00 10 00 00 00 00 00 00 00

标头的子组件,标头示例及含义:

00 00 00 00 00 – 未知。
FD 00 – 第5-6个字节是命令标识符,有关所有受支持的标识符清单,请参考下一章。
00 – 未知。
10 00 00 00 – 标头后面要发送的加密后数据包的大小。
00 00 00 00 – 未知。

该后门支持全部下表所列出来的命令。其中,大多数命令在开头时都希望有一个字符串,该字符串可能描述了该命令,并且为操作人员提供了便利,但该字符串没有被恶意软件积极使用,可能是任何内容。例如,KILL <PID>也可以表示成A <PID>。其中一些命令依赖于嵌入在后门中的两个Payload(UserFunction.dll和ProcTran.dll),这些Payload最终会被注入到另一个进程,或者直接启动另一个进程。

关于UserFunction.dll

UserFunction.dll会启动一个隐藏的cmd.exe进程,创建命名管道\\.\pipe\Microsoft Ole Object {30000-7100-12985-00000-00000},并将所有接收到的数据都从管道转发到cmd的标准输入.exe进程。进程的所有输出都将重定向回命名管道,这将允许命名管道上与外壳进行交互。

关于ProcTran.dll

该组件打开到指定主机和端口的TCP连接,创建命名管道\\.\pipe\Microsoft Ole Object {30000-7100-12985-00000-00001},并将所有接收到的数据都通过管道转发到打开的TCP连接。并且,将从连接上收到的所有数据包都转发到命名管道。这样一来,将会允许通过命名管道与TCP连接进行交互。

0xC8(<cmd> <arg1> <arg2>):提供一个简单的Shell程序,支持dir、copy、move、del、systeminfo和cd命令。这些与Shell中标准命令的功能相匹配。并且在这里,是唯一一次使用到<cmd>。

0xC9(<cmd><arg1>):该参数被解释为进程ID(PID)。后门将UserFunction.dll注入到进程中,该进程是一个交互式Shell工具,它将所有输入输出数据转发到Microsoft Ole Object({30000-7100-12985-00000-00000})。然后,后门会将传入的数据转发到命名通道,以便于打开的Shell进行通信。如果未提供PID,那么会将cmd.exe作为后门进程的子进程启动,其输入和输出会重定向到命名管道Microsoft Ole Object {30000-7100-12985-00001-00001}。

0xCA(<cmd> <arg1> <arg2>):将数据写入文件。第一个参数是文件名,第二个参数是文件的偏移量。

0xCB(<cmd> <arg1> <arg2> <arg3>):从文件读取数据。第一个参数是文件名,第二个参数是文件的偏移量,第三个参数为可选,我们还暂时不清楚其真正用途。

0xFA:列出正在运行的进程,包括进程名称、PID、进程所有者和可执行文件路径。

0xFB(<cmd> <arg1>):使用提供者的进程ID(PID)终止该进程。

0xFC(<cmd> <arg1> <arg2>):从第二个参数复制文件CreationTime、LastAccessTime和LastWriteTime,并将上述内容更新到第一个采纳数的文件路径中。

0xFD:通过执行WMI查询SELECT Name,ProcessId,SessionId,CommandLine,ExecutablePath FROM Win32_Process,列出正在运行的进程以及其他详细信息,例如SessonId和CommandLine。

0xFE:在ping命令后,恶意软件将使用以下字节序列(00 00 00 00 00 65 00 00 00 00 00 00 06 00 00 00)进行响应。对后门进行的成功实践表明,标识符65似乎表明操作成功,而66测表示操作错误。

接下来列出的命令,都是用来提供TCP通信终端的功能。这样一来,恶意组织就可以利用后门,通过TCP协议与另一台主机进行通信。这一技巧可以用于实际的红蓝对抗之中。例如,后门的一个实例可以作为跳转主机使用,并且可以通过TCP流量中继到达目标网络中的其他主机。请注意,下面列出的命令0xD2、0xD3和0xD6可以直接在后门主线程上运行,而不必使用ProcTran.dlll。

0x105(<cmd> <arg1>):该参数被解释为进程ID(PID)。后门将ProcTran.dll注入到这一进程中,该进程是一个TCP通信中继组件,它将所有输入和输出数据转发到Microsoft Ole Object {30000-7100-12985-00000-00001}。可以将命令0xD2、0xD3、0xD6与该组件共同使用。

0xD2(<arg1> <arg2>):打开到指定主机和端口的连接,第一个参数是主机,第二个参数是端口。成功后,将返回标头被设置为0xD4(00 00 00 00 00 D4 00 00 00 00 00 00 00 00 00 00)的数据包。这样一来,就有效地建立了一个TCP通信中继,使攻击者可以通过后门主机与另一个系统进行通信。

0xD3(<arg1>):通过0xD2命令打开的连接接收和发送数据。首先使用密钥“CreateThread”对接收到的数据进行RC4解密,然后使用0x77对单字节进行异或以解码。传回的数据直接发出,无需进行任何其他加密。

0xD6:关闭由0xD2命令建立的套接字连接。

0xCF:关闭与注入的ProcTran.dll通信的命名管道Microsoft Ole Object {30000-7100-12985-00000-00001},具体是通过0x105命令终止了目标进程中的线程。

总结

TCP LOWKEY变种被动侦听TCP/53端口上是否出现字节组合“FF FF 01 00 00 01 00 00 00 00 00 00”,一旦发现就会激活。经过测试,发现后门最多使用三个命名管道进行通信。其中,一个管道用于后门的主要通信,其他管道则按需用于嵌入式Payload。

\\.\pipe\Microsoft Ole Object {30000-7100-12985-00001-00001} – 主通信管道

\\.\pipe\Microsoft Ole Object {30000-7100-12985-00000-00001} – 命名管道,用于与TCP中继模块ProcTran.dll进行交互

\\.\pipe\Microsoft Ole Object {30000-7100-12985-00000-00000} – 命名管道,用于与交互式Shell模块UserFunction.dll进行交互

下图总结了LOWKEY组件如何相互交互:

8.png

附录

1.png

本文翻译自:https://www.fireeye.com/blog/threat-research/2019/10/lowkey-hunting-for-the-missing-volume-serial-id.html如若转载,请注明原文地址: https://www.4hou.com/technology/21109.html
点赞 0
  • 分享至
取消

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

扫码支持

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

发表评论