要点总结
- r77 是一款隐蔽的开源 rootkit,用于部署 XMRIG 加密货币矿机
- r77 使用多个模块来成功安装并保持持久性
- 攻击活动发起者大量依赖开源工具和脚本,可能是为了隐藏攻击来源或降低开发成本
前言
Elastic 安全实验室发现了一个恶意加密货币矿机,该矿机已在多个亚洲国家部署。该活动的所有者正在使用一个名为 r77 的开源用户层 rootkit。
r77 的主要目的是通过钩取重要的 Windows API 来隐藏系统上其他软件的存在,这使其成为网络犯罪分子进行隐蔽攻击的理想工具。通过利用 r77 rootkit,恶意加密货币矿机的作者得以躲避检测并继续其攻击活动而不被发现。
在本研究中,我们将重点介绍 r77 rootkit 的内部运作方式,并探讨其如何与加密货币矿机结合使用。我们希望提高人们对网络犯罪分子持续威胁的认识,并鼓励个人和组织采取积极措施来保护其系统和网络。
代码分析
概述
该 rootkit 由 4 个不同的模块组成
- 安装程序模块。
- 加载器模块。
- 服务模块。
- 核心模块。
我们将在下文中详细介绍每个模块和阶段。
安装程序模块
它的第一个任务是将加载器模块 PE 存储在注册表中,这是恶意软件作者常用的一种技术,用于在其系统上持久存储恶意代码。一旦加载器模块存储在注册表中,安装程序模块就会构建一个 PowerShell 命令,该命令从注册表中加载加载器模块并执行它,然后安装程序模块创建一个计划任务来运行该 PowerShell 命令。
安装程序查找存储为名为 EXE 的 PE 资源的加载器模块,然后在 HKEY_LOCAL_MACHINE\SOFTWARE 配置单元中创建一个名为 $77stager 的新注册表项,并将加载器模块写入该注册表项。
然后,安装程序构建一个 PowerShell 命令,使用 [Reflection.Assembly]::Load 方法以反射方式在内存中加载 .NET 加载器。此外,通过修补 AmsiScanBuffer API,使其始终返回一个 AMSI_RESULT_CLEAN 响应,从而绕过 Microsoft 的反恶意软件扫描接口 (AMSI)。AMSI_RESULT_CLEAN 表示扫描的内容为“已知良好”。未发现检测结果,并且结果在未来定义更新后可能不会更改。”然后,通过将变量名称替换为随机字符串来混淆 PowerShell 命令。
最后,安装程序创建一个计划任务,以使用 COM 对象执行 PowerShell 命令,该任务配置为使用 SYSTEM 帐户在启动时执行。
加载器模块
加载器是一个基于 .NET 的二进制文件,它负责取消钩取 DLL、调整 SeDebugPrivilege 设置、解密和解压服务模块,以及注入服务模块。这是通过 PPID 欺骗技术将进程挖空技术用于另一个合法进程下的新生成进程来实现的。
API 取消钩取
为了击败终端解决方案设置的用户层内联 API 钩取,加载器模块首先完全取消钩取包含 rootkit 使用的 API 的两个重要 DLL,即 NTDLL.dll 和 KERNEL32.dll。
此技术涉及以下步骤
- 检索 DLL:加载器模块从磁盘读取目标 DLL 文件。
- 将 DLL 映射到内存:加载器模块使用 CreateFileMapping 函数创建一个新的文件映射,这允许将 DLL 加载到进程的内存中。
- 分析 DLL 的节表:加载器模块分析新映射的 DLL 的节表,以识别存储可执行代码的相关节(通常称为 .text 节)。
- 覆盖代码节:一旦识别出 .text 节,加载器模块将已加载 DLL 中相应节的内容替换为来自新 .text 节的代码。
SeDebugPrivilege
接下来,加载器模块尝试获取 SeDebugPrivilege,这允许它检查和调整其他进程的内存。
此技术会触发 Elastic 的 可疑进程启用 SeDebugPrivilege 检测规则。
服务模块解密和解压缩
在加载器的资源部分中存储了同一服务模块的两个版本,一个 32 位版本和一个 64 位版本,将根据系统架构进行部署。
有效负载使用 GZip 压缩算法进行压缩,并使用简单的 XOR 进行解密。解压缩后,加载器使用前 4 个字节作为 XOR 密钥来解密剩余的数据。
父 PID 欺骗
为了使进程挖空注入看起来合法,使用了父 PID 欺骗技术来躲避威胁猎人和安全工具。此技术允许攻击者在他们想要的任何父进程下运行进程。
恶意软件首先获取正在运行的 winlogon.exe 进程的进程 ID,这是 Microsoft Windows 操作系统的一个组件。
然后它使用 5 个 Windows API
- OpenProcess:获取父进程句柄。
- InitializeProcThreadAttributeList:初始化属性列表。
- UpdateProcThreadAttribute:通过 PROC_THREAD_ATTRIBUTE_PARENT_PROCESS 属性设置父进程句柄。
- CreateProcess:在新欺骗的父进程下创建一个新进程
 工具,这是一个由俄罗斯公司 TektonIT 开发的用于远程管理的闭源程序,可用于远程控制受感染的机器并从远程位置发出命令。最后,该脚本在目标系统上创建了一个新的管理员用户 (adm),这可能会被用来执行其他攻击或窃取敏感数据。
检测逻辑
预防
检测
YARA
Elastic Security 创建了 YARA 规则来识别此活动。以下是用于识别 r77 rootkit 的 YARA 规则。
rule Windows_Rootkit_R77_1 {
meta:
author = "Elastic Security"
creation_date = "2022-03-04"
last_modified = "2022-04-12"
license = "Elastic License v2"
os = "Windows"
arch = "x86"
category_type = "Rootkit"
family = "R77"
threat_name = "Windows.Rootkit.R77"
reference_sample = "cfc76dddc74996bfbca6d9076d2f6627912ea196fdbdfb829819656d4d316c0c"
strings:
$a = { 01 04 10 41 8B 4A 04 49 FF C1 48 8D 41 F8 48 D1 E8 4C 3B C8 }
condition:
all of them
}
rule Windows_Rootkit_R77_2 {
meta:
author = "Elastic Security"
creation_date = "2023-05-09"
last_modified = "2023-05-09"
license = "Elastic License v2"
os = "Windows"
arch = "x86"
category_type = "Rootkit"
family = "R77"
threat_name = "Windows.Rootkit.R77"
reference_sample = "21e7f69986987fc75bce67c4deda42bd7605365bac83cf2cecb25061b2d86d4f"
strings:
$a1 = { 8C 20 88 00 00 00 42 8B 44 21 10 42 8B 4C 21 1C 48 2B D0 49 }
$a2 = { 53 00 4F 00 46 00 54 00 57 00 41 00 52 00 45 00 5C 00 24 00 37 00 37 00 63 00 6F 00 6E 00 66 00 69 00 67 00 }
condition:
all of them
}
rule Windows_Rootkit_R77_3 {
meta:
author = "Elastic Security"
creation_date = "2023-05-09"
last_modified = "2023-05-09"
license = "Elastic License v2"
os = "Windows"
arch = "x86"
category_type = "Rootkit"
family = "R77"
threat_name = "Windows.Rootkit.R77"
reference_sample = "3dc94c88caa3169e096715eb6c2e6de1b011120117c0a51d12f572b4ba999ea6"
strings:
$a1 = { 5C 00 5C 00 2E 00 5C 00 70 00 69 00 70 00 65 00 5C 00 24 00 37 00 37 00 63 00 68 00 69 00 6C 00 64 00 70 00 72 00 6F 00 63 00 36 00 34 00 }
$a2 = { 5C 00 5C 00 2E 00 5C 00 70 00 69 00 70 00 65 00 5C 00 24 00 37 00 37 00 63 00 68 00 69 00 6C 00 64 00 70 00 72 00 6F 00 63 00 33 00 32 00 }
condition:
all of them
}
rule Windows_Rootkit_R77_4 {
meta:
author = "Elastic Security"
creation_date = "2023-05-18"
last_modified = "2023-05-18"
license = "Elastic License v2"
os = "Windows"
arch = "x86"
category_type = "Rootkit"
family = "R77"
threat_name = "Windows.Rootkit.R77"
reference_sample = "91c6e2621121a6871af091c52fafe41220ae12d6e47e52fd13a7b9edd8e31796"
strings:
$a = { 33 C9 48 89 8C 24 C0 00 00 00 4C 8B CB 48 89 8C 24 B8 00 00 00 45 33 C0 48 89 8C 24 B0 00 00 00 48 89 8C 24 A8 00 00 00 89 8C 24 A0 00 00 00 }
condition:
$a
}
rule Windows_Rootkit_R77_5 {
meta:
author = "Elastic Security"
creation_date = "2023-05-18"
last_modified = "2023-05-18"
license = "Elastic License v2"
os = "Windows"
arch = "x86"
category_type = "Rootkit"
family = "R77"
threat_name = "Windows.Rootkit.R77"
reference_sample = "916c805b0d512dd7bbd88f46632d66d9613de61691b4bd368e4b7cb1f0ac7f60"
strings:
$r77_str0 = "$77stager" wide fullword
$r77_str1 = "$77svc32" wide fullword
$r77_str2 = "$77svc64" wide fullword
$r77_str3 = "\\\\.\\pipe\\$77childproc64" wide fullword
$r77_str4 = "SOFTWARE\\$77config"
$obfuscate_ps = { 0F B7 04 4B 33 D2 C7 45 FC 34 00 00 00 F7 75 FC 66 8B 44 55 90 66 89 04 4B 41 3B CE }
$amsi_patch_ps = "[Runtime.InteropServices.Marshal]::Copy([Byte[]](0xb8,0x57,0,7,0x80,0xc3)" wide fullword
condition:
($obfuscate_ps and $amsi_patch_ps) or (all of ($r77_str*))
}
rule Windows_Rootkit_R77_6 {
meta:
author = "Elastic Security"
creation_date = "2023-05-18"
last_modified = "2023-05-18"
license = "Elastic License v2"
os = "Windows"
arch = "x86"
category_type = "Rootkit"
family = "R77"
threat_name = "Windows.Rootkit.R77"
reference_sample = "96849108e13172d14591169f8fdcbf8a8aa6be05b7b6ef396d65529eacc02d89"
strings:
$str0 = "service_names" wide fullword
$str1 = "process_names" wide fullword
$str2 = "tcp_local" wide fullword
$str3 = "tcp_remote" wide fullword
$str4 = "startup" wide fullword
$str5 = "ReflectiveDllMain" ascii fullword
$str6 = ".detourd" ascii fullword
$binary0 = { 48 8B 10 48 8B 0B E8 ?? ?? ?? ?? 85 C0 74 ?? 48 8B 57 08 48 8B 4B 08 E8 ?? ?? ?? ?? 85 C0 74 ?? 48 8B 57 10 48 8B 4B 10 E8 ?? ?? ?? ?? 85 C0 74 ?? 48 8B 57 18 48 8B 4B 18 E8 ?? ?? ?? ?? 85 C0 74 ?? 48 8B 57 20 48 8B 4B 20 E8 ?? ?? ?? ?? 85 C0 74 ?? 48 8B 57 28 48 8B 4B 28 E8 ?? ?? ?? ?? 85 C0 }
$binary1 = { 8B 56 04 8B 4F 04 E8 ?? ?? ?? ?? 85 C0 74 ?? 8B 56 08 8B 4F 08 E8 ?? ?? ?? ?? 85 C0 74 ?? 8B 56 0C 8B 4F 0C E8 ?? ?? ?? ?? 85 C0 74 ?? 8B 56 10 8B 4F 10 E8 ?? ?? ?? ?? 85 C0 74 ?? 8B 56 14 8B 4F 14 E8 ?? ?? ?? ?? 85 C0 74 ?? 8B 56 18 8B 4F 18 E8 ?? ?? ?? ?? 85 C0 74 ?? 8B 56 1C 8B 4F 1C }
condition:
(all of ($str*)) or $binary0 or $binary1
}
参考
以下内容在上述研究中被引用
- https://github.com/microsoft/Detours
- https://github.com/xmrig/xmrig
- https://ru.wikipedia.org/wiki/Remote_Manipulator_System
观察结果
所有可观察对象也可在 下载 中以 ECS 和 STIX 格式提供。
本研究中讨论了以下可观察对象。
指示器 | 类型 | 名称 | 参考 |
---|---|---|---|
msupdate[.]info | 域名 | 不适用 | C2 |
5.133.65.53 | IPV4 | 不适用 | C2 |
5.133.65.54 | IPV4 | 不适用 | C2 |
5.133.65.55 | IPV4 | 不适用 | C2 |
5.133.65.56 | IPV4 | 不适用 | C2 |
916c805b0d512dd7bbd88f46632d66d9613de61691b4bd368e4b7cb1f0ac7f60 | SHA-256 | $77_Install.exe | 安装程序模块 |
9fb38412cac94255a3abbec80f15620098a0c85247690850c302a9ff060b5c0c | SHA-256 | 不适用 | 暂存模块 |
96849108e13172d14591169f8fdcbf8a8aa6be05b7b6ef396d65529eacc02d89 | SHA-256 | 不适用 | 64 位核心模块 |
aeb6a7b9ca890dc08259d7c239eb188e466210d48a17640671cba398bf69392f | SHA-256 | 不适用 | 32 位核心模块 |
91c6e2621121a6871af091c52fafe41220ae12d6e47e52fd13a7b9edd8e31796 | SHA-256 | 不适用 | 64 位服务模块 |
29bc88a316e3f34ed29c5358e459b9fbf3b7962a72cac388ab5c977dd990ea77 | SHA-256 | 不适用 | 32 位服务模块 |
10165e27e0db0a6708f346ddea657ab0409499f93eb8426a80864a966f0f401e | SHA-256 | RMS.exe | 远程操作系统 (RMS) |
757fa687a9b4d461ffda78d93e4d812003307a9b9747dce7fb469625429cc551 | SHA-256 | $77_oracle.exe | XMRIG 矿工 |
a7e31abe10be6bca44f0a846d631e578efe78c14f6bf1cf834cfb15469fc1d3a | SHA-256 | $77_Loader.exe | 加载 PowerShell 脚本的 .NET 二进制文件 |