EN
lanyun
technologies
银河实验室 深谙安全之道,热衷技术创新
LABORATORIES 银河实验室

检测

兰眼检测:

图片

概述

提到勒索软件,一定绕不过Darkside。其一,在去年五月份,其攻击了Colonial Pipeline,该公司是美国主要的燃料管道运营商之一,此次攻击导致其被迫关闭了美国东部沿海各州的关键燃油运输网络,产生的影响十分严重;其二,其技术手段与多个勒索软件组织十分相似,包括上文中提及的Lockbit,甚至最近火热的Lockbit3.0前置阶段所用手法与其高度相似。

分析

 

1、基本流程

流程图:

图片

2、细节分析

2.1 载入DLL及API

Darkside恶意样本首先创建一个用于解密DLL及API的buffer。

图片

随后其调用一个嵌套解密函数对密文进行解密,以得到对应的DLL和API。何为嵌套,可以看到其将每一个DLL或API所对应密文的长度和0xFF进行“%”和“/”操作,通过该操作将密文进行切片,并将切片后的密文传入嵌套函数decrypt_buffer中进行解密,解密算法不复杂,通过动调或脚本都可得到对应的明文,因此本文对此不再进行过多赘述。

 

得到DLL相关的明文后,其会调用LoadLibraryA来加载对应的DLL,并再次调用解密函数,解密该DLL对应的API信息;得到对应的API信息后,调用GetProcAddress来获取对应函数的地址,并将其存入数组中,方便后续取用;且Darkside在使用完对应的解密信息后,会调用clean函数将内存中的明文擦除。

图片2.2 解密配置文件

Darkside在完成对DLL和API的解密后,其开始解密后续运行中所需的配置信息。因Darkside设置的解密函数对每次输入的待解密密文有长度上的限制,其通过遍历查找“0xEFBEADDE”进而得到需解密的密文对应的长度,随后调用解密函数对其进行解密。

图片

解密后,发现Darkside还对解密后的信息,进行了aPLib解压,才得到最终可用的配置信息。

图片

随后其将解压后的配置信息,拷贝到指定的内存中,方便后续使用。

图片

2.3 探测系统环境

Darkside在完成解密及装载工作后,其调用NtQueryInformationProcess来查看程序是否运行在WOW64环境中。

图片

随后再调用函数check_OS_version来确定具体的操作系统版本。

图片

2.4 鉴权与提权

在鉴权和提权阶段,Darkside的操作与上一篇文章中Lockbit2.0在此处的操作十分相似。Darkside首先调用函数IsUserAnAdmin来判断受害者是否具有Admin权限,若不具备Admin权限则会调用check_token对其子权限进行进一步检查,其中主要是对token_groups的信息进行校对,如图可见其校验受害者是否具有ECURITY_BUILTIN_DOMAIN_RID和DOMAIN_ALIAS_RID_ADMINS这两个子权限(Administrator组为S-1-5-32-544)。

图片

经过鉴权后,若受害者不具备上述权限,其将通过COM组件绕过UAC后完成提权操作。

图片

Darkside解密出字符串“explorer.exe”,并将该值赋给PEB的ProcessParameters字段中的ImagePathName和CommandLine,并调用LdrEnumerateLoadedModules以完成自身的伪装,即其将以“explorer.exe”的身份来操作COM组件对象。

图片

利用COM组件进行UAC绕过以达到提权的具体操作可以查看Microsoft的官方文档(链接:https://learn.microsoft.com/en-us/windows/win32/com/the-com-elevation-moniker)。Darkside解密出字符串“Elevation:Administrator!new:{3E5FC7F9-9A51-4367-9063-A120244FBEC7”。为何Darkside选取该CLSID作为后续操作的对象,通过查询注册表可以看到其属于“cmstplua.dll”,因而Darkside以该值作为对象调用CoGetObject来获取COM组件中的ICMLuaUtil接口。

图片

图片

随用其通过ICMLuaUtil接口调用函数Shellexec以命令行的方式重新启动自身,达到提权的目的。
图片

2.5 调整token权限

Darkside通过GetTokenInformation来获取TokenPrivileges的相关信息,并将token权限修改为SE_PRIVILEGE_ENABLED,最后调用函数AdjustTokenPrivileges使其生效。

图片

2.6 模拟安全上下文

Darkside会尝试让其自身进程进行模拟安全上下文。若成功,Darkside的进程可通过获取到的用户token来模拟客户端,以完成所有访问控制操作。其通过调用函数GetTokenInformation来获取TokenUser的相关信息(SID),再调用LookupAccountSidW通过获取到的SID,来检索是否有NT AUTHORITY、AUTORITE NT或NT-AUTORITÄT这三种域和该SID相关联。

图片

若受害者与上文中提及的任意一个域相关联,其会调用WTSGetActiveConsoleSessionId和WTSQueryUserToken来获取该用户的token,该token将应用于加密阶段。

图片2.7 处理GUID

为了后续的校验操作,Darkside对受害者的GUID进行了一些处理。其先解密出“SOFTWARE\Microsoft\Cryptography”,以利用其中的CRC32错误校验函数对GUID进行处理。

图片Darkside将“0xDEADBEEF”作为第一次调用RtlComputeCrc32的初始值,每次进行CRC32运算后,再进行异或操作。

图片再将经上述操作得到的结果转化为字符串。

图片 

2.8 创建互斥体

关于释放日志记录和赎金记录的内容本文不再过多进行赘述,此小节对Darkside的互斥体创建过程进行阐述,其通过调用GetModuleFileNameW、CreateFileW、GetFileSize和ReadFile将文件的内容读入缓冲区,并通过CRC32对内容进行处理,得到对应的校验和,随后解密出“Global\XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX”,并用得到的校验和替换字符串中的“X”。

图片通过调用OpenMutexW和CreateMutexW完成互斥体的检查和创建。

图片2.9 加密相关

2.9.1 校验计算机语言

Darkside和Lockbit2.0一样也会对受害者计算机的默认语言进行校验,其通过函数GetSystemDefaultUILanguage和GetUserDefaultLangID来获取计算机默认语言,判断其是否为俄语,若计算机默认语言为俄语,Darkside将会立刻退出,不会执行后续的加密操作。

图片2.9.2 收集并发送受害者信息

Darkside先解密出格式化字符串,随后通过get_systeminfo获取用户名,主机名,系统版本,架构等等,并将这些信息添入到对应的位置;再解密出对应的勒索软件版本,并将这些信息按照解密出的格式化字符串进行格式化。

图片Darkside在发送受害者信息之前会对已格式化的字符串进行加密操作,以防明文传输。

图片随后Darkside解密出网络连接需要的配置信息,并调用InternetOpenW和InternetConnectW来获取Firefox/80.0的应用句柄,并通过443端口连接到C2服务器。

图片建立连接后,Darkside通过HttpOpenRequestW向C2服务器发送POST请求;并解密出所需的HTTP报文头,再调用InternetSetOptionW完成Internet相关设置;最后发送带有害者信息(已加密)的数据包。

图片2.9.3 清空回收站

Darkside首先通过GetLogicalDriveStringsW和GetDriveTypeW来找到受害者主机上的所有驱动器,再进入clean_recycle_bin去寻找每个驱动器上的回收站文件夹,并进行删除操作。

图片其通过FindFirstFileExW和FindNextFileW来循环遍历驱动器,以找到“*recycle*”文件夹。

图片找到“*recycle*”文件夹后,递归遍历其中每一个文件夹,并调用delete_recycle_data将其中内容擦除。

图片删除手法十分简单明了,此处不再进行过多赘述,主要就是递归查找的思路。

图片2.9.4 删除卷影文件

Darkside在删除卷影文件时,与Lockbit2.0存在一些差异,其会根据系统版本通过不同的方式删除卷影文件,其中32位通过COM组件,64位通过powershell。

图片 

当系统是32位系统时,Darkside调用CoInitializeEx、CoInitializeSecurity和CoCreateInstance来创建属于wbemprox.dll的对象,通过创建的对象连接到本机的“root/cimv2”命名空间,并获得IWbemServices句柄,通过该句柄进行SQL查询(SELECT * FROM Win32_ShadowCopy)找到受害者主机上的所有卷影文件,并将这些文件删除。

图片当系统是64位系统时,Darkside先解密出一段字符串“powershell -ep bypass -c"(0..61)|%{$s+=[char][byte]('0x'+'4765742D576D694F626A6563742057696E33325F536 861646F77636F7079207C20466F72456163682D4F626A656374207B245F2E44656C65746528293B7 D20'.Substring(2*$,2))};iex $s”,在对该字符串再进行61次解密后,得到最终的指令“Get-WmiObject Win32_Shadowcopy | ForEach-Object {$.Delete();}”,利用powershell执行,获取到受害者主机上的所有Win32_Shadowcopy对象,并将其删除。

图片2.9.5 终止进程和服务

Darkside在进行加密前和Lockbit2.0一样会根据配置信息中解密出来的服务以及程序列表,将列表中对应的服务和程序终止。

对于服务,Darkside通过调用OpenSCManagerW打开服务控制管理器,并用EnumServicesStatusExW来检索所有具有SERVICE_WIN32状态的服务,这些服务若在需被杀死的列表中,其会调用ControlService和DeleteService将该服务终止并删除。

图片 

图片对于进程,Darkside通过NtQuerySystemInformation获取SYSTEM_PROCESS_INFORMATION,并将其中的信息与进程列表进行比较,若其存在于名单中将调用TerminateProcess来终止进程。

图片2.9.6 本地加密

Darkside会对受害者主机上的DRIVE_FIXED、DRIVE_REMOVABLE、DRIVE_REMOTE这三种驱动器进行加密。

图片

2.9.7 网络共享文件夹加密

Darkside调用GetAdaptersInfo和inet_addr来获取网络上其他主机的地址,将获取到的地址传递给get_hostname来获取对应的主机名称。

图片Darkside会再创建一个线程,并利用SendARP和gethostbyaddr通过之前已经获取到的地址信息,来得到对应的主机名。

图片再根据获取到的主机名,通过NetShareEnum来检索网络共享文件夹,最后调用encrypt对这些文件夹进行加密。

图片2.9.8 发送加密信息

在加密完成后,Darkside会和发送受害者信息时进行类似的操作,将ID、UID、加密文件数、加密文件大小、未加密文件数、加密时间这些信息进行格式化和加密后,发送给C2服务器。

图片2.9.9 encrypt浅析

Darkside的加密手法和Lockbit2.0中所使用的加密手法有着一定的相似之处,但加密速度却存在着极大的差距,在细节分析时也会加入一些对产生速度差异原因的一些猜测。

Darkside会先利用GetDiskFreeSpaceExW来查看目标驱动器是否有0x6400000字节的剩余空间,检查空间主要是为了确保加密记录可以被完整存放,若空间不足,则不会对该驱动器进行加密。随后,其还会通过GetTickCount来记录加密时间。

图片Darkside和Lockbit2.0相同,都会调用CreateIoCompletionPort创建两个I/O完成端口,该端口用于接收需要加密的文件;并根据处理器的数量(2个线程/处理器,最高不超过64个线程)来创建加密线程,实现多线程加密。

图片Darkside遍历文件夹和判断文件是否可以进行加密的操作与Lockbit2.0基本相同,本文中不再对相同的部分进行过多的赘述。其遍历方式也为递归遍历,主要进行了:目录访问控制列表的获取、释放赎金文件、判断文件夹属性、并且根据文件白名单,后缀白名单,以及文件hash判断该文件是否可以加密。但与Lockbit2.0不同的是Darkside仅使用主线程进行文件夹遍历,并没有像Lockbit2.0那样为每个文件夹创建一个线程进行遍历操作,结合后面的分析,基本可以确定是因遍历效率太低导致其加密速度不及Lockbit2.0。

图片 

图片

Darkside会在加密前检查该文件是否已被加密,具体操作方式如图。

图片

若目标文件被进程占用,其在获取到与该进程相关的文件信息后,对这些文件进行校验,标记出可以进行加密的文件后,调用TerminateProcess结束该进程。

图片对于加密算法,Lockbit2.0选择使用AES(块式对称加密)中的CBC模式对文件进行加密,用非对称加密算法对AES的密钥进行加密;而Darkside选择使用Salsa20流式加密算法对文件进行加密,同样使用RSA-1024非对称加密算法对流密钥进行加密。

Darkside通过循环调用RtlRandomEx(替代了随机流生成器),生成一个64位的流密钥,与标准的Salsa20算法所使用的密钥格式是不同的。

图片 

再生成加密流密钥所需的RSA-1024密钥,生成过程涉及大数计算,不再进行过多赘述。

图片将所需信息填入到对应的结构中,发送给I/O完成端口,由子线程进行加密操作。加密操作即Salsa20算法的加密操作,不再讨论具体实现细节,其加密速度是Lockbit2.0中所使用的AES的3倍。

图片其也和Lockbit2.0一样分为四个加密阶段:阶段零即从文件中读取0x80000个字节到加密缓冲区,并将加密阶段改为阶段一。

图片阶段一即通过流密钥对文件进行加密操作,每次加密0x80000个字节后,将加密内容写入文件,并更新文件加密状态。

图片阶段二即将流密钥及其校验和写到被加密文件的末尾。

图片阶段四即清理线程关闭文件句柄,并在次调用GetQueuedCompletionStatus接收新的待加密文件。

图片3.10 自删除

Darkside通过GetModuleFileNameW和GetShortPathNameW来获取恶意样本的短路径,随后解密出所需要的指令,并用ShellExecuteW完成指令的执行,其中“/F”的作用就是将短路径扩展成完整路径。

图片 

总结

Darkside所选用的流式密码加密速度是Lockbit2.0所选用AES算法速度的3倍,但其整体加密速度却远远低于Lockbit2.0,其主要原因是没有采用多线程的方式去遍历文件夹,导致遍历速度过慢,造成了加密线程饥饿的情况,拖慢了整体速度;另外其流密钥的生成方式有所不同,通过微软所提供的RtlRandomEx函数来生成随机数进行拼接,因不知RtlRandomEx函数的具体实现方式,其是否是一个安全的伪随机序列有待考证。除以上两点外,该恶意样本整体流程十分完善,值得深入分析和探索

图片

- End -

京公网安备 11010802024705号  京ICP备20030588号 Copyright © 兰云科技 www.lanysec.com 版权所有