引言
随着网络攻击技术的不断演变,恶意代码加载器逐渐成为恶意代码执行的关键组成部分。此类加载器是一种用于将各种恶意代码加载到受感染的系统中的恶意工具,通常负责绕过系统安全防护,将恶意代码注入内存中并执行,为后续的特洛伊木马类型恶意代码的部署奠定基础。加载器的核心功能包括持久性机制、无文件内存执行以及多层次规避技术。
安天 CERT 将近几年历史跟踪储备的典型恶意加载器家族有关信息汇总成专题报告,并持续追踪新的流行加载器家族。本项目专题将聚焦加载器技术细节,深入挖掘其在攻击链中的核心功能,包括其混淆技术、加密机制以及注入策略等。此外,我们也会不断完善自身安全产品能力,采取有效技术方案进一步提升针对加载器的识别率和准确率,帮助用户组织提前发现并阻止潜在威胁。
1 概述
ArmouryLoader 加载器最早于 2024 年被发现,曾被用于投递 SmokeLoader 和 CoffeeLoader 等恶意代码家族。该加载器通过劫持华硕 Armoury Crate 系统管理软件的导出函数进行加载,因此被命名为 ArmouryLoader。ArmouryLoader 加载器具备提权、持久化以及投递目标载荷的功能,并具有一定对抗 EDR(端点检测和响应)能力,使后续投递的载荷更容易突破系统防线。
ArmouryLoader 在加载阶段会调用 OpenCL 解密载荷,需要运行环境具有 GPU 或 32 位 CPU 才能正常运行,能够起到规避沙箱和虚拟机环境的作用。ArmouryLoader 在投递目标载荷时,还会利用系统中合法 DLL 的代码段来读取敏感内存、调用系统函数,并在此基础上伪造调用栈,隐藏系统调用的发起者,以此来规避 EDR 检测。通过以上手段,ArmouryLoader 具有较强的隐蔽性,使其在沙箱和终端环境均难以被检测,提高了目标载荷投递的成功率,对用户的系统安全构成威胁。
该加载器详细信息参见安天病毒百科。
图 1 ‑ 1 长按识别二维码查看 HijackLoader 加载器详细信息
2 ArmouryLoader 加载器生存技术举例分析
2.1 混淆技术分析
ArmouryLoader 具有三种混淆代码的方式,分别为增加无用指令、代码自解密和使用 OpenCL 解密。
其中 ArmouryLoader 在第一阶段和第三阶段拥有无用指令填充的混淆代码。
图 2 ‑ 1ArmouryLoader 添加的无用指令
在第二、四和六阶段均有自解密代码以干扰分析。
图 2 ‑ 2Armoury 自解密代码
此外 ArmouryLoader 在第三阶段还会用 OpenCL 解密代码,增加分析难度并增加了对运行环境设备的要求。
图 2 ‑ 3ArmouryLoader 使用 OpenCL 解密代码
2.2 提权技术分析
ArmouryLoader 在第五阶段会尝试使用 CMSTPLUA COM 组件进行提权,在提权时 ArmouryLoader 会将自身伪装成 explorer.exe,随后调用提权函数获取 Administrator 权限。
图 2 ‑ 4ArmouryLoader 使用 COM 组件进行提权
2.3 持久化技术分析
ArmouryLoader 会通过计划任务实现持久化。根据版本不同,ArmouryLoader 会使用系统工具 schtasks 或计划任务 COM 组件实现持久化。
无论持久化的方式如何,当具有管理员权限时,ArmouryLoader 会选择通过用户登录触发并获取最高权限,否则 ArmouryLoader 将会以普通权限每隔 30 分钟执行一次。
图 2 ‑ 5 以最高权限运行的计划任务
此外 ArmouryLoader 还会对持久化的文件加以系统、隐藏和只读属性,并修改 ACL 拒绝用户修改和删除文件。
图 2 ‑ 6ArmouryLoader 设置文件属性
2.4 对抗技术分析
ArmouryLoader 会通过合法 DLL 中的特殊 gadget 读取敏感位置内存。
图 2 ‑ 7ArmouryLoader 通过 gadget 读取敏感内存数据
ArmouryLoader 在第三阶段和第八阶段调用敏感函数时还会通过伪造调用栈避免检测。
图 2 ‑ 8ArmouryLoader 伪造函数调用栈
ArmouryLoader 还会通过 Halo's Gate 获取系统函数调用号,具有一定的反 syscall hook 能力,能够直接进行系统调用。
图 2 ‑ 9ArmouryLoader 使用 Halo's Gate 技术搜索系统调用号
3 攻击流程
ArmouryLoader 共具有八个阶段,每个阶段相对独立,分步完成最终载荷的投递工作。ArmouryLoader 的一、三、五、七阶段负责完成特定的恶意行为,而二、四、六、八阶段负责加载下一阶段的 PE 载荷。
表 3 ‑ 1ArmouryLoader 不同阶段恶意行为
加载阶段 | 恶意行为 |
第一阶段 | 劫持 Armoury Crate 导出函数,运行第二阶段 shellcode |
第二阶段 | 解密并运行第三阶段 PE 文件 |
第三阶段 | 通过 OpenCL 解密并运行第四阶段 shellcode |
第四阶段 | 解密并运行第五阶段 PE 文件 |
第五阶段 | 进行提权及持久化,并运行第六阶段 shellcode |
第六阶段 | 解密并运行第七阶段 PE 文件 |
第七阶段 | 将第八阶段的 shellcode 注入到 64 位 dllhost.exe |
第八阶段 | 加载并运行目标载荷 |
4 样本分析
4.1 样本标签
表 4 ‑ 1ArmouryLoader 样本标签
病毒名称 | Trojan/Win32.ArmouryLoader |
原始文件名 | ArmouryA.dll |
MD5 | 5A31B05D53C39D4A19C4B2B66139972F |
处理器架构 | x86 |
文件大小 | 1.41 MB ( 1,480,552 字节 ) |
文件格式 | BinExecute/Microsoft.EXE [ :X86 ] |
时间戳 | 2023-12-13 15:31:16 |
数字签名 | ASUSTeK COMPUTER INC.(数字签名无效) |
加壳类型 | 无 |
编译语言 | Microsoft Visual C/C++ ( 19.16.27049 ) |
VT 首次上传时间 | 2024-09-12 18:34:23 |
VT 检测结果 | 33/72 |
4.2 ArmouryLoader 加载器第一阶段
ArmouryA.dll 是华硕 Armoury Crate 程序的一部分,ArmouryLoader 加载器通过劫持 ArmouryA.dll 导出函数 freeBuffer 实现运行。
该函数中包含有大量无用代码以干扰安全人员对其分析,并最终会解密并执行第二阶段载荷。
图 4 ‑ 1ArmouryLoader 解密并执行第二阶段代码
4.3 ArmouryLoader 加载器第二阶段
在 ArmouryLoader 第二阶段,拥有大量自解密代码以阻碍静态分析。
图 4 ‑ 2ArmouryLoader 自解密代码
在第二阶段,ArmouryLoader 会通过 PEB 加载 CreateThread 函数,并创建一个新线程执行后续逻辑。
图 4 ‑ 3ArmouryLoader 创建新线程执行后续逻辑
在新线程中,ArmouryLoader 会从二阶段载荷中读取第三阶段的 PE 文件,并加载到内存中执行。
图 4 ‑ 4ArmouryLoader 加载第三阶段 PE 文件
4.4 ArmouryLoader 加载器第三阶段
在第三阶段,ArmouryLoader 会加载 OpenCL 库,并通过 OpenCL 解密第四阶段载荷。该阶段会通过 OpenCL 库调用 Nvidia、AMD 或 Intel 设备进行 shellcode 解密。
图 4 ‑ 5ArmouryLoader 寻找 OpenCL 可用设备
随后 ArmouryLoader 会将两个字符串异或生成解密密钥,再将密钥与密文传入 OpenCL 设备中进行异或解密,得到下一阶段的 shellcode 进而执行。
图 4 ‑ 6ArmouryLoader 使用 OpenCL 设备解密 shellcode
在后续的版本中,该阶段载荷增加了大量混淆,使其难以分析。
图 4 ‑ 7ArmouryLoader 第三阶段混淆
在后续版本中,还对通过构造 ROP 链的方式对函数的帧栈进行伪造以对抗栈回溯。以程序调用 GetModuleHandleW 为例,该图中函数将会通过 ret 4 指令将 EIP 设置为 GetModuleHandleW 函数地址,随后再出栈四个字节。此时栈顶将留下 GetModuleHandleW 函数的返回地址 RtlCreateMemoryBlockLookaside+88,以及函数的参数 OpenCL.dll 的字符串指针。其中 RtlCreateMemoryBlockLookaside+88 实际上为 jmp [ EBX ] 的汇编指令,当 GetModuleHandleW 函数返回时,将会从 EBX 地址中读取函数真正的返回值,并设置到 EIP 上,以归还程序的控制流。
图 4 ‑ 8ArmouryLoader 构造 ROP 链对抗栈回溯
4.5 ArmouryLoader 加载器第四阶段
在第四阶段,ArmouryLoader 将解密并加载第五阶段 PE 文件并在内存中执行。
该阶段同样拥有自解密逻辑,但加密的层数较少,并使用 loop 指令控制循环而非第二阶段的 jnz。
图 4 ‑ 9ArmouryLoader 执行自解密逻辑
在完成解密后 ArmouryLoader 将会在内存中加载 PE 文件并执行。
图 4 ‑ 10ArmouryLoader 加载 PE 文件到内存
4.6 ArmouryLoader 加载器第五阶段
在第五阶段,ArmouryLoader 会先检测程序是否具有提升权限或属于 System 用户组,并根据权限的不同选择不同的持久化位置。
图 4 ‑ 11ArmouryLoader 检测进程权限
随后 ArmouryLoader 会复制自身到 %PROGRAMDATA% 或 %LOCALAPPDATA% 下,并设置文件系统、隐藏和只读属性。
图 4 ‑ 12ArmouryLoader 移动自身到特定目录
之后 ArmouryLoader 还会添加文件的 ACL 列表来禁止用户删除或修改自身程序。
图 4 ‑ 13ArmouryLoader 修改文件 ACL 列表
之后 ArmouryLoader 会通过 schtasks 创建一个名为 AsusUpdateServiceUA 每隔 30 分钟运行一次的计划任务来实现持久化。
图 4 ‑ 14ArmouryLoader 通过 schtasks 创建计划任务实现持久化
如果具有管理员权限,ArmouryLoader 则会在用户登录时以最高权限执行。
图 4 ‑ 15ArmouryLoader 以最高权限运行计划任务
在较新的版本中,ArmouryLoader 会尝试利用 COM 组件进行提权,此时 ArmouryLoader 会先修改 PEB 和 LDR_DATA_TABLE_ENTRY 中的进程信息。
图 4 ‑ 16ArmouryLoader 修改进程信息
随后通过 COM 组件 CMLuaUtil 进行提权。
图 4 ‑ 17ArmouryLoader 使用 COM 组件进行提权
在后续更新中,ArmouryLoader 使用 COM 组件替代 schtasks 程序来创建计划任务。
图 4 ‑ 18ArmouryLoader 使用 COM 组件创建计划任务
当不具有 System 权限时,计划任务将每 10 分钟触发一次。
图 4 ‑ 19ArmouryLoader 设定每 10 分钟触发一次的计划任务
当具有 System 权限时,ArmouryLoader 将设置以最高权限运行程序。
图 4 ‑ 20ArmouryLoader 设置计划任务运行权限
此时 ArmouryLoader 计划任务将登录触发。
图 4 ‑ 21ArmouryLoader 设置计划任务登录触发
随后运行 shellcode 执行下一阶段。
图 4 ‑ 22ArmouryLoader 执行第六阶段载荷
4.7 ArmouryLoader 加载器第六阶段
第六阶段与第四阶段样本功能相同,负责解密和加载下一阶段 PE 文件。
图 4 ‑ 23ArmouryLoader 完成重定向工作并调用下一阶段 PE 文件入口点
4.8 ArmouryLoader 加载器第七阶段
在第七阶段,ArmouryLoader 将创建 64 位的 dllhost.exe 进程,并将 shellcode 注入其中,以将运行环境从 32 位更改为 64 位。
ArmouryLoader 首先关闭文件重定向,并创建一个 64 位的 dllhost.exe 进程。
图 4 ‑ 24ArmouryLoader 关闭文件重定向
随后 ArmouryLoader 会搜索一些 64 位的 DLL 以便劫持主进程,在该过程中 ArmouryLoader 将频繁使用天堂之门技术执行 64 位代码。
图 4 ‑ 25ArmouryLoader 通过天堂之门执行 64 位代码
通过天堂之门,ArmouryLoader 可以调用 64 位 DLL 中的函数。如图所示,ArmouryLoader 通过 get_dll64、get_func64 和 call_func64 可以实现 64 位函数的搜索和调用。再对特定的函数进行封装以实现像调用普通函数一样调用 64 位函数。
图 4 ‑ 26ArmouryLoader 对 64 位的 NtGetContextThread 进行封装
最后通过劫持主进程的方式在 dllhost.exe 中执行 64 位 shellcode。
图 4 ‑ 27ArmouryLoader 劫持 64 位 dllhost.exe 主进程
4.9 ArmouryLoader 加载器第八阶段
在第八阶段,ArmouryLoader 首先会获取 ZwAddBootEntry、NtAllocateVirtualMemory 和 NtProtectVirtualMemory 函数地址,并搜索对应的系统调用号。
图 4 ‑ 28Armoury 搜索函数及系统调用号
在新版 ArmouryLoader 中,ArmouryLoader 会在 ntdll 中搜索 mov rax, [ rax ] ;ret; 的 gadget,并通过该 gadget 读取敏感内存区域,以欺骗 EDR 读取行为是由 ntdll 发出的。
图 4 ‑ 29ArmouryLoader 通过 gadget 间接读取数据
ArmouryLoader 会尝试在函数中搜索特定字节序列来获取调用号。
图 4 ‑ 30ArmouryLoader 搜索系统调用号
如果目标函数被 hook,则会导致 ArmouryLoader 搜索字节序列失败,进而导致无法获取系统调用号。此时 ArmouryLoader 会使用 Halo's Gate 技术进一步搜索系统调用号。该技术将搜索邻近的 Zw 函数,从中获取系统调用号。并根据搜索到的临近函数与目标函数之间的距离推算出目标函数的系统调用号。
图 4 ‑ 31ArmouryLoader 使用 Halo's Gate 技术搜索系统调用号
在新版 ArmouryLoader 中,该算法进一步完善。ArmouryLoader 不再假定 Zw 函数大小为 32 字节,而通过遍历函数导出表计算出最小的 Zw 函数间距,从而获取 Zw 函数大小。
图 4 ‑ 32ArmouryLoader 计算 Zw 函数最小间距
在搜索完系统调用号后,ArmouryLoader 会使用 NtAllocateVirtualMemory 和 NtProtectVirtualMemory 为最终的目标载荷申请内存空间。该过程中 ArmouryLoader 会先计算将会使用 ZwAddBootEntry 函数中的 syscall 配合系统调用号调用系统函数。并在这基础上伪造调用栈。
该过程将在 kernel32.dll 中搜索 jmp [ rbx ] 的 gadget,用于在函数调用结束后返还控制流。
图 4 ‑ 33Armoury 搜索 jmp [ rbx ] gadget
随后 ArmouryLoader 通过 .pdata 节中的 ExceptionDir 获取函数对应的 RUNTIME_FUNCTION 信息,从而寻找函数的 UnwindInfo,其中 UnwindInfo 包含了函数的帧栈大小信息。
图 4 ‑ 34ArmouryLoader 搜索函数的 RUNTIME_FUNCTION 信息
之后 ArmouryLoader 通过 UnwindInfo 计算 jmp [ rbx ] gadget 所在函数以及 BaseThreadInitThunk 和 RtlUserThreadStart 的帧栈大小,用于后续的伪造。
图 4 ‑ 35ArmouryLoader 计算函数栈大小
随后 ArmouryLoader 将 jmp [ rbx ] gadget 置于 syscall 的返回地址,而函数真正的返回地址的指针置于 rbx 寄存器中以实现返还控制流。并在后续的调用栈上将部署 BaseThreadInitThunk 和 RtlUserThreadStart 函数的帧栈,以欺骗 EDR 让其误以为 syscall 是从 RtlUserThreadStart 到 BaseThreadInitThunk 再经由 kernel32 中某个函数发出的。
图 4 ‑ 36ArmouryLoader 伪造调用栈
在分配完内存空间后,ArmouryLoader 将最终的目标载荷复制到指定内存区域,并完成重定向工作,调用程序入口点完成投递。根据最终的 C2 域名可知,ArmouryLoader 投递的目标载荷为 CoffeeLoader。
图 4 ‑ 37CoffeeLoader C2 地址
5 IoCs
IoCs
90065F3DE8466055B59F5356789001BA
6 样本对应的 ATT&CK 映射图谱
图 6 ‑ 1 技术特点对应 ATT&CK 的映射
具体 ATT&CK 技术行为描述表:
表 6 ‑ 1ATT&CK 技术行为描述表
ATT&CK 阶段 / 类别 | 具体行为 | 注释 |
持久化 | 利用计划任务 / 工作 | ArmouryLoader 通过计划任务实现持久化 |
滥用提升控制权限机制 | ArmouryLoader 通过 COM 组件进行提权 | |
防御规避 | 反混淆 / 解码文件或信息 | ArmouryLoader 拥有大量异或加密的代码段 |
ArmouryLoader 通过 OpenCL 解密代码 | ||
ArmouryLoader 通过天堂之门执行 64 位代码 | ||
修改文件和目录权限 | ArmouryLoader 通过添加 ACL 记录禁止用户更改和删除 | |
隐藏行为 | ArmouryLoader 为持久化的文件添加隐藏、系统和只读属性 | |
间接执行命令 | ArmouryLoader 通过系统 DLL gadget 读取目标内存 | |
ArmouryLoader 通过 syscall 直接调用系统函数 | ||
ArmouryLoader 伪造调用函数调用栈 | ||
仿冒 | ArmouryLoader 伪装华硕系统管理软件,具有无效的数字签名 | |
混淆文件或信息 | ArmouryLoader 代码具有混淆 | |
ArmouryLoader 通过哈希检索 API |
7 安天智甲助力用户防御加载器威胁
经过测试,安天智甲终端安全系列产品(以下简称 " 智甲 ")依托安天自研威胁检测引擎和内核级主动防御能力,可以有效查杀和防御本次发现病毒样本。
智甲可对本地磁盘进行实时监测,对新增文件自动化进行病毒检测。针对此次威胁,当用户通过接收邮件附件、微信传输、网络下载等方式将 ArmouryLoader 加载器存储至本地时,智甲会立即对该病毒进行告警并清除恶意文件,防止用户启动文件导致终端遭受攻击。
图 7 ‑ 1 发现病毒时,智甲第一时间捕获并发送告警
智甲还为用户提供统一管理平台,管理员可通过平台集中查看网内威胁事件详情,并批量进行处置,提高终端安全运维效率。
图 7 ‑ 2 智甲管理中心助力管理员实现高效的终端安全管理
附录:安天澜砥威胁检测分析垂直大模型自动化分析结
安天澜砥威胁检测分析垂直大模型能对样本进行自动化分析,部分解析内容如下:
根据提供的日志和分析结果,以下是详细的判定结论和解释:
1. 判定结论
评估结果:可疑(准确度:约 95%)
1. 详细解释
2. 特征匹配与判定依据:
恶意 API 调用:日志中多次出现与证书相关 API 的调用,如 GetDeviceIndex、FreeEnvironmentStrings、CertGen 等。这些 API 通常用于处理证书和安全相关的任务,恶意软件常利用这些 API 进行恶意操作,如绕过证书验证、获取私钥等。
字符串分析:日志中包含大量与证书相关的 URL 和字符串,例如 crl3.digicert.com、ocsp.digicert、cacerts.digicert.com 等。这些域名通常与数字证书相关的 CA 机构相关。
混淆与编码:日志中出现的混淆代码片段(如 ?? 表示未被选中作为特征使用)可能用于隐藏恶意行为,增加了检测的难度。
异常行为模式:日志中多处出现重复的字节模式(如 04 81 AD 30 81 AA 30 53 A0 51 A0 4F 86 4D 68 74 74 70 3A 2F 2F 63 72 6C 33 2E 64 69 67 69 63 65 72 74 2E 63 6F 6D),可能用于数据填充或隐藏恶意代码。
· 恶意代码特征:
证书相关操作:存在与证书相关的 API 调用,可能用于获取、验证或使用证书进行恶意通信。
混淆与加密:日志中包含大量混淆代码,增加了检测的复杂性,可能用于隐藏恶意行为。
异常字符串:出现多个与数字证书相关的域名和路径,可能用于绕过安全检测或进行恶意通信。
·评估准确度:
高可信度特征:日志中存在多个与恶意代码特征匹配的特征,增加了检测的准确性。
潜在的模糊性:部分特征(如 ?? 表示未被选中作为特征使用)可能隐藏了恶意行为,但整体特征仍显示出较高的可疑性。
· 结论
根据上述分析,日志中包含多个与证书相关且可疑的 API 调用和字符串,这些特征符合恶意软件的典型行为模式。因此,分析工具判定该文件为 Trojan.Win32.ShipCome(或类似的恶意软件家族)是合理的。
准确度评估:约 95%
按照国标草案给出威胁分类为 Trojan.Win32.SpyBind,自动提取特征生成的 YARA 规则如下:
rule Trojan.Win32.ShipCome:Trojan { meta: description = " 这是一段由 VILLM V2 模型生成的 YARA 规则。用于检测 Trojan.Win32.ShipCome" strings: $a = {f7 d3 4f 33 f8 c1 c6 17} $b = {c1 ce 17 33 f8 47 f7 d3} $c = {4e 33 c3 33 cf f7 d0 33 c5 c1 cf 17 4e 4b} $d = {f7 d0 f7 d0 87 c7 f7 d2} $e = {4b 33 cd 87 c1 ff e0} condition: all of them }
安天澜砥威胁检测分析垂直大模型是国内首个通过国家网信办备案的威胁检测生成式算法。模型基于安天赛博超脑 20 余年积累的海量样本特征工程数据训练而成,训练数据包括文件识别信息、判定信息、属性信息、结构信息、行为信息、主机环境信息、数据信息等,支持对不同场景下向量特征进行威胁判定和输出详实的知识理解,形成应用不同需求和场景的多形态的检测方式,提升后台隐蔽威胁判定能力,进一步为安全运营赋能。
图 8 ‑ 1 安天澜砥威胁检测分析垂直大模型样本分析结果
参考资料
[ 1 ] . 安天 .Trojan/Win32.ArmouryLoader 病毒详解与防护 - 计算机病毒百科 [ R/OL ] . ( 2025-07-07 )
https://www.virusview.net/malware/Trojan/Win32/ArmouryLoader
登录后才可以发布评论哦
打开小程序可以发布评论哦