在2022年2月,无文件卡巴斯基实验室的恶意研究人员首次观察到将shellcode放入Windows事件日志的技术。该技术允许在文件系统中隐藏“无文件”最后stager的软件木马。这种对活动中事件日志的新藏关注不仅限于存储 shellcode
。 Dropper 模块还修复了与事件跟踪 (ETW) 和反恶意软件扫描接口 (AMSI) 相关的匿处 Windows 原生 API 函数 ,以使感染过程更加隐蔽。无文件 除了事件日志之外,恶意攻击者的软件工具集中还有许多其他技术
。其中
,新藏开发者在功能中增加了侦察,匿处可以模仿合法域名的服务器租用无文件 C2 Web 域名,以及受害者使用的恶意现有和软件的名称。为了使攻击更加隐蔽 ,软件攻击者使用 Linode
、新藏Namecheap
、匿处DreamVPS 上的虚拟专用服务器
。 一种更常见的方法是使用大量的反检测解密器。攻击者使用不同的编译器,从微软的建站模板 cl.exe 或 MinGW 下的 GCC 到最新版本的 Go。此外,为避免被检测到,某些模块使用数字证书进行签名
。研究人员认为它是由攻击者发布的,因为遥测数据没有显示任何与之签名的合法软件,只有这次活动中使用的恶意代码
。 关于最后stager的特洛伊木马
,攻击者决定使用多个基于 HTTP 和命名管道。模板下载显然 ,除了事件日志之外,攻击者还痴迷于内存注入,许多 RAT 命令与它相关并且被大量使用
。除了上述自定义模块和技术外,攻击者还使用了一些商业渗透测试工具,如 Cobalt Strike 和 SilentBreak 的工具集 。 研究人员从内存中的最后一个stager开始研究
,然后使用遥测技术,重建了几个感染链,该活动的针对性很强,且使用的大量工具还包括商业工具。香港云服务器 该活动包括各种技术和模块,让我们把它分成几类来从技术上描述这个活动 ,比如商业渗透测试套件 、围绕它们的自定义反检测包装器和最后stager的木马。 商业工具集有: 同样,我们认为定制的一些模块(如包装器和最后stager)可能是商业产品的一部分。分类之后 ,我们准备一个一个地分析模块 。 我们观察到的最早攻击stager发生在 2021 年 9 月。Cobalt Strike 模块的传播是通过说服目标下载合法站点 file.io 上的 .rar 链接并自行运行来实现的。内部 Cobalt Strike 模块的数字证书如下(在使用相同的活动期间,从 wrapper 到 last stagers 签署了 15 个不同的 stager): 由于所有目标主机的感染情况不同 ,我们将仅描述观察到的一种情况
。由于能够使用木马将代码注入任何进程,攻击者可以自由地广泛使用此功能将下一个模块注入 Windows 系统进程或受信任的应用程序(如 DLP)
。 记住截断的进程注入,甚至模仿 Web 域注册,我们可以将攻击过程描述为非常迭代(quite iterative)
:对一些模块进行初始侦察,然后准备额外的攻击 。 关于商业工具 ,这次活动中使用 SilentBreak 和 Cobalt Strike 工具集的痕迹非常明显。名为 ThrowbackDLL.dll 和 SlingshotDLL.dll 的木马让我们想起 Throwback 和 Slingshot
,它们都是 SilentBreak 框架中的工具,而与 dropper (sb.dll) 关联的“sb”可能是供应商名称的缩写。 这里我们要提一下,二进制文件中的几个 .pdb 路径包含项目的目录 C:\Users\admin\source\repos\drx\ 以及其他未以 Throwback 或 Slingshot 命名的模块,例如 drxDLL.dll。但是,加密函数与公开可用的 Throwback 代码中的相同
。 对于反检测包装器,使用了不同的编译器
。除了 MSVC,Go 编译器 1.17.2 和 MinGW 下的 GCC 都在使用
。解密器差异很大 ,它们包含的功能如下表所示: 这层感染链解密 、映射到内存并启动代码
。本文我们将仅介绍 Cobalt Strike 的 Go 解密启动器。 主包中的函数名称被混淆了,Main.init 从与事件日志创建相关的 kernel32.dll 和 ntdll.dll 库(WriteProcessMemory 和其他函数)中解码 Windows API 函数名称 。二进制文件中的每个名称都连续四次使用 base64 编码。使用 WriteProcessMemory,拥有“xor rax, rax; ret”的dropper在内存中编码以下函数:EtwNotificationRegister、EtwEventRegister、EtwEventWriteFull、EtwEventWriteFull
、EtwEventWrite。 在 Main.start 中 ,恶意软件会检查主机是否在域中,并且只有在它为真时才起作用。然后动态解析上述函数的地址。下一个stager使用 AES256(CBC 模式)加密,密钥和 IV 使用 base64 编码。 使用这种方法
,研究人员需要编写一些脚本来收集下一个模块的加密部分。解密后 ,要获得最终的可移植可执行文件,还需进一步转换数据
。 Last stager 有两种通信机制——使用RC4加密的HTTP通信机制和使用命名管道的非加密通信机制
。后一种方式在技术上能够与任何网络可见的外部主机通信
,但在Windows环境中,命名管道是建立在SMB协议之上的
,它几乎不会对外部网络开放。所以这些模块很可能用于横向移动。 在对恶意软件集进行了介绍之后,我们现在将描述感染链 ,研究人员使用 Cobalt Strike 渗透测试套件进行Dropper注入。 研究人员从 wrapper-dropper 动态库开始自定义模块分析 。此代码被注入到诸如 explorer.exe 之类的 Windows 进程中。在加载到启动程序进程的虚拟地址空间后,在其单个入口点,dropper 删除由先前stager或执行创建的文件。 首先,该模块将原始合法的操作系统错误处理程序 WerFault.exe 复制到 C:\Windows\Tasks。然后
,它将一个加密的二进制资源放置到同一目录中的wer.dll文件中,以进行典型的DLL order劫持。为了持久化
,该模块将新创建的WerFault.exe设置为自动运行,在Software Microsoft\Windows\CurrentVersion\Run Windows系统注册分支中创建一个Windows问题报告值 。 dropper 不仅将启动器放在磁盘上进行侧载,而且还会将带有 shellcode 的信息消息写入现有的 Windows KMS 事件日志。 被删除的wer.dll是一个加载器,如果没有隐藏在Windows事件日志中的shellcode
,它不会造成任何伤害。dropper在事件日志中搜索类别为 0x4142(ASCII 中的“AB”)并以密钥管理服务作为源的记录
。如果没有找到,则通过 ReportEvent() Windows API 函数(lpRawData 参数)将 8KB 的 shellcode 块写入信息记录消息。从 1423 开始,创建的事件 ID 会自动递增。 这个启动器 ,被第一个stager放到 Tasks 目录中,它代理所有对wer.dll的调用,并将其导出到原始合法库 。在入口点,一个单独的线程将所有上述 8KB 片段组合成一个完整的 shellcode 并运行它
。由合法 WerFault.exe 的副本创建的相同虚拟地址空间用于所有这些代码 。 为了防止 WerFault 继续其错误处理过程
,DLL 使用典型的 Blackbone trampoline修复启动器的入口点 阻止合法启动器执行的方法很新颖。在主线程中 ,wer.dll 找到它的入口点并用一个简单的函数对其进行修复。上面屏幕截图中的 WaitAndExit() 只会使用日志收集线程 ID 调用 WaitForSingleObject() ,然后退出,这意味着永远不会执行真正的 WerFault.exe 错误处理代码
:映射到其地址空间的欺骗性 DLL 会阻止它。 启动器将控制传输到收集的 shellcode 的第一个字节。在本文中,研究人员为下一个函数准备了三个参数
: 解析下一个 Windows 可移植可执行文件以定位其入口点的做法是非常典型的
。为了让下一个stager的木马不那么显眼 ,攻击者清除了标题中的“MZ”魔法。在木马的入口点调用代码后,shellcode 还会搜索请求导出并调用它 。 除了搜索入口点并调用它,shellcode 还通过硬编码哈希搜索木马导出,并使用参数“dave”和“4”运行找到的函数 相比之前的辅助模块,对于最后一个stager
,我们会介绍的更详细一些
。 C++ 模块显然使用了 SilentBreak(现为 NetSPI)的 Throwback 公共存储库中的代码
:基于 XOR 的加密函数 ,一些示例的原始文件名,例如 ThrowbackDLL.dll 等
。让我们从前面提到的Load()导出函数开始。这就像上面的WerFault补丁(函数在主木马线程上等待),但是它忽略了任何参数,所以“dave”和“4”没有被使用。这个启动器可能支持比这个更多的模块
。 该模块使用单字节 XOR 密钥解密 C2 域
,在此示例中,只有一个域 eleed[.]online。该木马能够处理其中的许多,以“|”字符分隔并加密 。为了进一步通过普通HTTP进行通信 ,木马从用户代理“Mozilla 5.0”的集合中随机选择一个C2
。 该恶意软件通过收集以下信息生成一个追踪字符串,也用“|”分隔 : 追踪识别器还将“1.1”附加到字符串(可能是恶意软件版本)和当前配置的睡眠时间 。 在HTTP通信之前,该模块使用硬编码的32字节长的RC4密钥发送空(但仍然加密)的ICMP数据包来检查连接 。与任何其他字符串一样 ,此密钥使用基于Throwback xor的算法加密 。 如果ping端口为80的控制服务器成功,则将上述追踪数据发送到该控制服务器。作为回应
,C2共享木马主循环的加密命令。 代码的命令功能: 本次活动中使用的另一个木马是基于管道命名的 ,这样命令系统更有意义 ,包括特权升级、截图、非活动时间测量等 。继续使用另一种最后stager的木马类型,发现它被注入到了像edge.exe这样的进程中。 木马的位置是 C:\Windows\apds.dll,具有相同名称的原始合法 Microsoft 帮助数据服务模块库位于 C:\Windows\System32 中。木马的主要工作周期是在一个单独的线程 。该恶意软件还导出一个Load()函数,其唯一目的是等待一个工作线程,这是该活动的模块的典型。 首先 ,木马主线程获取原始apds.dll并导出 ,并将其保存到内存中木马映像之后的一个已分配的新堆缓冲区中。然后
,木马会编辑自己导出的函数数据 ,这样它就可以通过如下精心制作的存根调用原始的apds.dll导出 ,其中的地址就是从真正的apds.dll解析出来的地址: 这个trampoline代码取自Blackbone Windows内存黑客库(remotemmemory::BuildTrampoline函数) 。DLL劫持并不是什么新鲜事,我们已经多次看到这种技术被用于代理合法函数,但仅用短存根重新创建自导出来调用原始合法函数却很不寻常。然后,该模块创建一个双工命名的管道“MonolithPipe”,并进入它的主循环
。 在对导出函数进行上述操作后,该模块会轻微地使用架构和 Windows 版本信息对主机进行追踪识别。木马还使用提到的稀有常量初始化一个随机的 11 字节 ASCII 字符串,例如这里的 init_keys 函数 。结果用作唯一的会话 ID。 恶意软件连接到端口 443 上的硬编码域(在本例中为 https://opswat[.]info:443),并向 C2 端的 submit.php 发送 POST 请求 。 HTTPS 连接选项设置为接受服务器端的自签名证书。在本例中
,C2通信使用Dhga(81K1!392-!(43<KakjaiPA8$#ja密钥的RC4算法加密
。对于基于管道命名的木马
,常用的命令有: 研究人员现在已经介绍了该活动的三个层面,有趣的是,研究人员观察到一个木马具有如上表所示的完整命令集
,但仍然使用rc4加密的HTTP与C2通信,而不是指定管道
。最后一个stager的示例看起来像一个模块化的平台 ,攻击者能够根据他们当前的需要组合其功能。 研究人员认为这些代码是自定义的(木马、包装器),与以前已知的活动或以前注册的SilentBreak工具集模块没有相似之处。现在研究人员不愿意给这个活动命名,而是坚持只用“SilentBreak”。 本文翻译自:https://securelist.com/a-new-secret-stash-for-fileless-malware/106393/






