摘要

勒索软件Darkside是在Colonial Pipeline攻击活动中使用的一个恶意软件家族,于2021年5月7日被曝光,详情可参考https://www.zdnet.com/article/darkside-the-ransomware-group-responsible-for-colonial-pipeline-cyberattack-explained/。该二进制文件包含一个经过加密的配置,它需要使用自定义算法进行解密;另外,该配置含有一个22字节的缓冲区,用于描述该恶意软件执行的不同操作。这些操作包括:检查系统语言并避免加密俄语机器,删除卷影副本,清空回收站,忽略特定文件、目录和文件扩展名,杀死特定进程,删除特定服务等。该勒索软件可以使用CMSTPLUA COM接口进行权限升级,并通过将自己安装为服务来实现持久性。另外,被挟持的文件是使用自定义的Salsa20算法实现进行加密的,其中Salsa20矩阵则是由硬编码在二进制代码中的RSA公钥进行加密的。Darkside使用带有I/O完成端口的多线程技术,在主线程和负责文件加密的工作线程之间进行通信。值得一提的是,该进程使用RDRAND和RDSEED指令生成随机的Salsa20矩阵,而早期版本则使用RtlRandomEx函数完成该任务。

技术分析

SHA256: 0A0C225F0E5EE941A79F2B7701F1285E4975A2859EB4D025D96D9E366E81ABB9

该恶意软件带有一个加密的配置,并且它必须通过自定义算法进行解密。

其中,自定义解密算法由4次减去0x10101010的减法运算和一些加法运算组成,具体如下图所示:

对于要加载的每个DLL,都用一个哈希函数计算DLL名称的哈希值,并将长度为4字节的计算结果与硬编码的值进行比较:

例如,下列值对应于kernel32.dll:

预计将加载以下DLL:ntdll、kernel32、Advapi32、user32、gdi32、ole32、oleaut32、shell32、shlwapi、WinInet、netapi32、wtsapi32、activeds、userenv、mpr、rstrtmgr。该进程根据使用相同算法计算得到的相近哈希值检索多个导出函数的地址。

解密后的配置如下图所示,它由RSA-1024指数(0x010001=65537)、0x80字节的RSA-1024模数、受害者UID、22个配置字节(将进一步详述)和aPLib压缩配置组成:

 该二进制文件使用aPLib-解压算法来解密不同的字符串。下图展示的是在加密过程中要避免加密的目录:

 以下文件将被勒索软件忽略:

如果文件的扩展名属于以下列表,那么就不对该文件进行加密:

该二进制文件将会删除名称中包含“backup”一词的文件夹:

利用该恶意软件未使用的一个特性,能够将以下字符串解压为其他字符串(我们的猜测是,攻击者试图杀死与SQL相关的进程,以加密数据库)。

以下进程将不会被该软件终止:

如果一个进程名称包含以下字符串,它将被杀死:

此外,还有一个要中止和删除的服务列表,具体如下图所示:

C2服务器的列表也是用同样的算法得到的:

该进程将显示一条消息,该消息将用于设置自定义壁纸,该壁纸包含针对受害者的重要指示:

赎金通知的内容也被写入进程内存中,如图所示:

下表描述了恶意软件根据上面解密的配置所要采取的操作:

该恶意软件使用NtQueryInstallUILanguage和NtQueryDefaultUILanguage API来确定系统的语言,并将结果与0x419(俄语标识符)进行比较。如果这两个值匹配,则恶意软件退出:

该恶意软件还会调用RegCreateKeyExW函数,该函数用于创建(如果已经存在,则打开)“Software\Microsoft\Cryptography”注册表项,如下所示: 

之后,恶意软件从上述注册表项中提取“MachineGuid”值,如下图所示:

该进程实现了一个自定义的哈希算法,生成8个小写的十六进制字符,(“MachineGuid”值是输入,该算法会应用8次): 

上面计算出的值(我们称它为RansomPseudoValue)将被用于以下结构:

◼服务名称:< RansomPseudoValue >

◼服务显示名称:< RansomPseudoValue >

◼赎金说明:README< RansomPseudoValue >.TXT

◼壁纸:%PROGRAMDATA%\< RansomPseudoValue >.bmp

◼每个加密文件将具有以下名称:< Original filename >< RansomPseudoValue >

◼图标文件:%PROGRAMDATA%\< RansomPseudoValue >.ico

◼已创建注册表项:HKCR\< RansomPseudoValue >\DefaultIcon=%PROGRAMDATA%\< RansomPseudoValue >.ico

该二进制程序使用SHTestTokenMembership API来验证用户是否属于Administrators组(0x220=544)。 

我们将根据用户的权限把分析过程分成3个不同的部分:低级权限、管理权限和SYSTEM权限。

低级权限

该恶意软件试图使用CMSTPLUA COM接口绕过UAC,详见如https://gist.github.com/api0cradle/d4aaef39db0d845627d819b2b6b30512。实际上,它是利用ZwOpenProcessToken来打开与进程相关的访问令牌的: 

NtQueryInformationToken函数被用来获取与令牌相关的组账户(0x2 = TokenGroups),它检查在TOKEN_GROUPS结构体中是否能找到管理员组: 

为了在当前线程上初始化COM库,需要调用CoInitialize例程,如图所示: 

到目前为止,这个二进制文件使用了很多低级别的API(来自ntdll)。比如,它使用ZwAllocateVirtualMemory API(0x3000 = MEM_COMMIT | MEM_RESERVE,0x4 = PAGE_READWRITE)分配了一个新的内存区域:

同时,我们还发现它调用了一个未公开的API函数,即LdrEnumerateLoadedModules: 

同时,它还通过名为Elevation:Administrator!new:{3E5FC7F9-9A51-4367-9063-A120244FBEC7}的对象运行了CoGetObject,具体如下所示:

总的来说,它将以系统权限重新启动恶意软件: 

管理权限

与第一种情况一样,该二进制代码使用ZwOpenProcessToken来打开与进程相关的访问令牌:

然后,利用NtQueryInformationToken API来检索该令牌的用户账户(0x1 = TokenUser):

然后,该恶意程序使用LookupAccountSidW来获取与作为输入的SID相关的账户名称,如图所示:

之后,进行3个不同的比较操作:将域名(在我们的例子中是计算机的名称)分别与“NT AUTHORITY”、“AUTORITE NT”和“NT-AUTORITAT”进行比较(简单来说,它试图确定用户账户是否为SYSTEM):

OpenSCManagerW例程用于建立与服务控制管理器的连接:

该进程尝试打开一个名为< RansomPseudoValue >的服务(此时还不存在):

由于该服务不存在,恶意软件会出于持久化目的而创建它,如下图所示:

启动新创建的服务,并且该二进制程序将自身作为服务启动: 

小结

在本文中,我们从技术角度为读者深入分析了勒索软件Darkside,由于篇幅过长,我们分为三篇文章进行发表,更多精彩内容,敬请期待!

参考及来源:https://cybergeeks.tech/a-step-by-step-analysis-of-a-new-version-of-darkside-ransomware/