2022年2月,卡巴斯基实验室研究人员首次观察到将shellcode放入Windows事件日志的技术。这种技术允许在文件系统中隐藏“无文件”的最后阶段特洛伊木马。这种对活动事件日志的关注不仅限于存储shellcode。dropper模块还修复了与事件跟踪(ETW)和反恶意软件扫描接口(AMSI)相关的Windows原生API函数,使感染过程更加隐蔽。除了事件日志之外,攻击者的工具集中还有许多其他技术。除此之外,开发人员还增加了侦察功能、可以冒充合法域的C2网络域以及受害者使用的现有软件名称。为了使攻击更加隐蔽,攻击者使用Linode、Namecheap、DreamVPS上的虚拟专用服务器。一种比较常见的方法是使用大量的反检测解密器。攻击者使用不同的编译器,从微软的cl.exe或MinGW下的GCC到最新版本的Go。此外,为了避免被发现,一些模块使用数字证书进行签名。研究人员认为它是由攻击者发布的,因为遥测数据没有显示任何用它签名的合法软件,只有在这次活动中使用的恶意代码。关于laststager木马,攻击者决定使用多个基于HTTP和命名的管道。显然,除了事件日志,攻击者对内存注入也很着迷,很多RAT命令都与之相关并被大量使用。除了上述自定义模块和技术外,攻击者还使用了一些商业渗透测试工具,如CobaltStrike和SilentBreak的工具集。感染链研究人员从记忆中的最后一个阶段开始,然后使用遥测技术重建了几个感染链。该活动具有很强的针对性,并使用了大量工具,包括商业工具。该活动包括各种技术和模块,让我们将其分为几类来从技术上描述该活动,例如商业渗透测试套件、围绕它们的自定义反检测包装器以及最后的stager木马。商业工具集是:Anti-InspectionWrapper-大量使用系统调用库的Go解密器,这使CobaltStrike模块能够多次编码并使用AES256CBC加密blob,这是首次观察到Go与CobaltStrikeCondition的使用。Anti-detectionwrapper-一个库启动器,在MinGW环境下用GCC编译。这个stager的唯一可能原因是反检测。反检测包装器-AES解密器,使用VisualStudio编译器编译;最后是stagerRAT-基于HTTP的木马,可能是原始名称ThrowbackDLL.dll和drxDLL.dll,但代码比旧版本的SilentBreak的Throwback更复杂。最后是stagerRAT——命名为基于管道的木马,可能的原始名称是monolithDLL.dll和SlingshotDLL.dll。根据文件名,最终的stager模块可能是商业Slingshot版本的一部分。同样,我们认为一些定制的模块(例如包装器和最终阶段器)可能是商业产品的一部分。分类之后,我们就可以对模块一一进行分析了。初始感染我们观察到的最早的攻击阶段发生在2021年9月。CobaltStrike模块通过说服目标在合法站点file.io上下载.rar链接并自行运行来传播。内部CobaltStrike模块的数字证书如下(在使用同一活动期间,由15个不同的stagers从wrapper到laststagers签名):由于所有目标主机被感染的方式不同,我们将仅描述一个观察到的案例。由于能够使用木马将代码注入任何进程,攻击者可以自由地广泛使用此功能将下一个模块注入Windows系统进程或受信任的应用程序(如DLP)。牢记截断的进程注入,甚至模仿Web域注册,我们可以将攻击过程描述为相当迭代:对某些模块进行初始侦察,然后准备其他攻击。商业工具集关于商业工具,SilentBreak和CobaltStrike工具集的使用在这次活动中很明显。名为ThrowbackDLL.dll和SlingshotDLL.dll的木马让我们想起了Throwback和Slingshot,它们都是SilentBreak框架中的工具,与释放器(sb.dll)关联的“sb”很可能是供应商名称的缩写。这里要提一下,二进制文件中有几个.pdb路径,包含项目目录C:\Users\admin\source\repos\drx\和其他非Throwback或Slingshot命名的模块,如drxDLL.dll。但是,加密功能与公开可用的Throwback代码中的相同。反检测设计对于反检测包装器,使用了不同的编译器。除了MSVC之外,还使用了Go编译器1.17.2和MinGW下的GCC。解密器千差万别,下表列出了它们包含的功能:几种编译器——可以使用Go和C++模块进行相同的AES256CBC解密;白名单启动器-WerFault.exe映射启动器到进程地址空间的自动运行副本;数字证书-15个使用“快速投资”证书签名的文件,我们没有观察到任何用它签名的合法文件具有空函数的地址空间;将shellcode保留在事件日志中——这是攻击者的主要创新,使用nextstager加密的shellcode被分成8KB块并保存在事件日志的二进制部分;C2网络域名仿制——攻击者在header中注册了一个ERP网络域名;这层感染链解密,映射到内存并启动代码。在本文中,我们将只介绍CobaltStrike的Go解密启动器。主包中的函数名称被破坏,Main.init从与事件日志创建相关的kernel32.dll和ntdll.dll库(WriteProcessMemory和其他函数)中解码WindowsAPI函数名称。二进制文件中的每个名称连续四次采用base64编码。使用WriteProcessMemory,带有“xorrax,rax;ret”的滴管在内存中编码以下函数:EtwNotificationRegister、EtwEventRegister、EtwEventWriteFull、EtwEventWriteFull、EtwEventWrite。在Main.start中,恶意软件会检查主机是否在域中,并且仅在为真时才采取行动。然后动态解析上面函数的地址。nextstager使用AES256(CBC模式)加密,密钥和IV以base64编码。使用这种方法,研究人员需要编写一些脚本来收集下一个模块的加密部分。解密后还需要进行进一步的数据转换,得到最终的可移植可执行文件。laststager类型Laststager有两种通信机制——使用RC4加密的HTTP通信机制和使用命名管道的非加密通信机制。后一种方法在技术上可以与网络上可见的任何外部主机通信,但在Windows环境中,命名管道建立在SMB协议之上,几乎从不对外网开放。所以这些模块很可能用于横向移动。在介绍了恶意软件集之后,我们现在将描述感染链,研究人员在其中使用CobaltStrike渗透测试套件进行滴管注入。用DLL中的Dropper实现订单劫持研究人员从wrapper-dropper动态库开始自定义模块分析。此代码被注入到Windows进程中,例如explorer.exe。在加载到启动器进程的虚拟地址空间后,在其单个入口点,释放器删除由先前的暂存器或执行创建的文件。首先,模块将原来合法的操作系统故障处理程序WerFault.exe复制到C:\Windows\Tasks。然后它将加密的二进制资源放入同一目录中的wer.dll文件中,以进行典型的DLLOrder劫持。为了持久化,该模块将新创建的WerFault.exe设置为自动运行,在SoftwareMicrosoft\Windows\CurrentVersion\RunWindowsSystemRegistry分支中创建一个WindowsProblemReporting值。Dropper不仅将启动器放在磁盘上以进行侧载,而且还将带有shellcode的信息性消息写入现有的WindowsKMS事件日志。被删除的wer.dll是一个加载程序,如果shellcode隐藏在Windows事件日志中,它不会造成任何伤害。释放器在事件日志中搜索类别为0x4142(ASCII中的“AB”)的记录,该记录以密钥管理服务为源。如果未找到,则通过ReportEvent()WindowsAPI函数(lpRawData参数)将一个8KB的shellcode块写入信息日志消息。从1423开始,创建的事件ID会自动递增。wer.dll中的启动器这个启动器由第一个stager放置在Tasks目录中,代理所有对wer.dll的调用并将其导出到原始合法库。在入口点,一个单独的线程将上面所有的8KB片段组合成一个完整的shellcode并运行它。由WerFault.exe的合法副本创建的相同虚拟地址空间用于所有这些代码。为了防止WerFault继续其错误处理过程,DLL使用典型的Blackbone蹦床来修复启动器的入口点以防止合法启动器执行。在主线程中,wer.dll找到它的入口点并用一个简单的函数修复它。上面截图中的WaitAndExit()将简单地使用日志收集线程ID调用WaitForSingleObject(),然后退出,这意味着真正的WerFault.exe错误处理代码永远不会执行:映射到其地址空间的欺骗性DLL会阻止它。Windows事件日志中的ShellcodeLauncher将控制权转移到收集到的Shellcode的第一个字节。在这篇论文中,研究人员为next函数准备了三个参数:nextstager木马的地址,它也包含在从事件日志中提取的数据中;此木马中加载的派生函数名称的标准ROR13哈希(0xE124D840);字符串“dave”的地址和常量“4”,它们成为导出函数的参数,可以通过散列找到;解析下一个Windows可移植可执行文件以定位其入口点是非常典型的。为了使下一个stager的木马不那么显眼,攻击者从标题中删除了“MZ”魔法。在木马入口点调用代码后,shellcode还会搜索请求导出并调用它。除了搜索入口点并调用外,shellcode还通过硬编码的hash搜索木马出口,并运行找到的函数,参数为“dave”和“4”HTTP木马与之前的辅助模块相比,对于最后stager,我们会更详细的介绍。C++模块显然使用了SilentBreak(现在是NetSPI)的Throwback公共存储库中的代码:基于XOR的加密函数,一些示例的原始文件名,例如ThrowbackDLL.dll等。让我们从前面提到的Load()导出函数开始。这就像上面的WerFault补丁(该函数在主木马线程上等待),但它会忽略任何参数,因此不使用“dave”和“4”。此启动器可能支持比这更多的模块。TargetedDiscovery此模块使用单字节XOR密钥来解密C2域,在本例中,只有一个域,eleed[.]online。木马能够处理其中的许多,以“|”分隔字符和加密。为了进一步通过纯HTTP进行通信,木马从用户代理“Mozilla5.0”的集合中随机选择一个C2。恶意软件通过收集以下信息生成跟踪字符串,这些信息也由“|”分隔:SOFTWARE\Microsoft\Cryptography中MachineGUID的值;计算机名称;使用GetAdaptersInfo获得的本地IP地址;体系结构(x86或x64);操作系统版本;当前进程是否有SeDebugPrivilege;跟踪识别器还将“1.1”附加到字符串(可能是恶意软件版本)和当前配置的休眠时间。与C2的加密HTTP通信在HTTP通信之前,模块通过发送带有硬编码32字节长RC4密钥的空(但仍加密)ICMP数据包来检查连接。与任何其他字符串一样,此密钥使用基于Throwback异或的算法加密。如果ping80端口的控制服务器成功,则向控制服务器发送上述跟踪数据。作为响应,C2共享用于木马主循环的加密命令。木马命令码的命令功能:0——再次跟踪识别目标;1—执行命令,木马在新的进程中执行接收到的命令,并将结果返回给C2;2—从URL下载并保存到给定的3—设置一个新的休眠时间,如果C2没有响应要执行的命令,则将此时间(以分钟为单位)用作超时。随机化公式为(0,9-1,1之间的随机数)*睡眠时间;4——睡眠指定分钟数而不改变配置。5-列出具有PID、路径、所有者、名称和父数据的进程;6-将shellcode注入并运行到目标进程的地址空间中。要注入同一进程,命令参数应为“本地”。与事件日志中的shellcode一样,此代码将运行提供的PE入口点和通过哈希找到的特定导出。99-终止特洛伊木马和C2之间的会话。该活动中使用的另一个木马是基于管道命名的,因此命令系统更有意义,包括权限提升、屏幕截图、不活动时间测量等。转向另一种最后阶段的木马类型,它被发现被注入到像edge.exe这样的进程中。该管道命名木马所在位置为C:\Windows\apds.dll,而原来合法的同名MicrosoftHelpDataServicesModuleLibrary位于C:\Windows\System32。木马的主要工作周期在一个单独的线程中。该恶意软件还导出一个Load()函数,其唯一目的是等待工作线程,这对于该活动的模块来说是典型的。首先,木马主线程获取原始apds.dll并导出,并在木马镜像后保存到内存中新分配的堆缓冲区中。然后木马编辑自己导出的函数数据,使其可以通过以下精心制作的存根调用原来的apds.dll导出,其中地址是从真正的apds.dll中解析出来的地址:ThistrampolinecodeistakenfromBlackboneWindowsmemory黑客库(remotemmemory::BuildTrampoline函数)。DLL劫持并不是什么新鲜事,我们已经看到这种技术被多次用于代理合法函数,但是仅仅用一个短存根重新创建自导出来调用原始合法函数是不常见的。该模块然后创建一个名为“MonolithPipe”的双工管道并进入其主循环。对导出的函数执行上述操作后,该模块轻度使用体系结构和Windows版本信息来跟踪主机的身份。木马还使用提到的罕见常量初始化一个随机的11字节ASCII字符串,例如此处的init_keys函数。结果用作唯一的会话ID。恶意软件连接到端口443上的硬编码域(在本例中为https://opswat[.]info:443),并向C2端的submit.php发送POST请求。HTTPS连接选项设置为在服务器端接受自签名证书。在此示例中,C2通信使用RC4算法和Dhga(81K1!392-!(43
