简介
2025 年 10 月,Elastic Security Labs 在遥测中发现了一个新观察到的 Windows 后门。我们称之为 "NANOREMOTE "的全功能后门与REF7707中描述的恶意软件具有相同特征,并与FINALDRAFT植入软件相似。
该恶意软件的主要功能之一是利用Google Drive API 从受害者端点来回传输数据。这一功能最终为难以检测的数据窃取和有效载荷分期提供了渠道。恶意软件包括一个任务管理系统,用于文件传输功能,包括下载/上传任务排队、暂停/恢复文件传输、取消文件传输和生成刷新令牌。
本报告旨在提高防御者和组织对我们正在监控的威胁行为者及其不断发展的能力的认识。
关键要点
- 弹性安全实验室发现新的 Windows 后门
- NANOREMOTE 很可能是由与 FINALDRAFT 和 REF7707 有关联的间谍威胁行为者开发的
- NANOREMOTE 包括使用 Google Drive API 执行命令、发现/枚举和文件传输功能
- 该后门集成了 Microsoft Detours 和 libPeConv 等开源项目的功能。
- Elastic Defend 通过行为规则、机器学习分类器和内存保护功能防止 NANOREMOTE 攻击链
NANOREMOTE 分析
WMLOADER
观察到的攻击链由两个主要部分组成,即加载器(WMLOADER)和有效载荷(NANOREMOTE)。虽然本报告的重点是 NANOREMOTE,但我们将介绍加载器,以提供整个感染流程的背景情况。
WMLOADER以无效数字签名伪装成 Bitdefender 安全程序 (BDReinit.exe)。
程序执行后,会大量调用 Windows 函数 (VirtualAlloc /VirtualProtect),使进程准备好承载存储在文件中的嵌入式 shellcode。shellcode 位于 RVA (0x193041) 并使用滚动 XOR 算法解密。
该 shellcode 会在与 WMLOADER 相同的文件夹路径下查找名为wmsetup.log 的文件,然后使用 AES-CBC 和 16 字节 ASCII 密钥 (3A5AD78097D944AC) 开始解密。解密后,shellcode 会执行内存后门 NANOREMOTE。
根据之前的 shellcode 解密程序,我们可以在 VirusTotal 中搜索到针对 Bitdefender 和 Trend Micro 产品的其他相关样本。
纳米遥感
NANOREMOTE 是一个功能齐全的后门程序,可用于执行侦察、执行文件和命令,以及在受害者环境之间传输文件。植入程序是一个用 C++ 编写的 64 位 Windows 可执行程序,没有经过混淆处理。
NANOREMOTE 配置
我们观察到的 NANOREMOTE 样品经过预配置,可与硬编码的不可路由 IP 地址通信。我们认为该程序是由生成器生成的,因为我们没有看到任何交叉引用指向配置设置。
对于 Google Drive API 身份验证,NANOREMOTE 使用可使用多个客户端的管道分隔配置。|*| 分隔符用于分割单个客户端使用的字段,而|-| 则用作分隔客户端的标记。每个客户结构有三个字段:
- 客户 ID
- 客户秘密
- 刷新令牌
以下是格式示例:
Client_ID_1|*|Client_Secret_1|*|Refresh_Token_1|-|Client_ID_2|*|Client_Secret_2|*|Refresh_Token_2
开发人员有一个后备机制,通过名为NR_GOOGLE_ACCOUNTS 的环境变量接受这种配置。
界面/记录
NANOREMOTE 提供详细的控制台,显示应用程序的实时活动,包括时间戳、源代码位置和行为描述。
在执行 NANOREMOTE 的同一位置创建一个新的 Windows 目录,文件夹名为Log 。
新创建的日志文件 (pe_exe_run.log) 被放置在该文件夹中,其中包含与控制台打印输出相同的内容。
设置
在主工作循环开始之前,NANOREMOTE 会进行初始设置。恶意软件通过CoCreateGuid 生成唯一的 GUID,然后使用Fowler-Noll-Vo (FNV) 函数对 GUID 进行散列。在每次请求时,操作员使用此 GUID 识别单个机器。
恶意软件开发者有一个进程范围内的崩溃处理程序,当出现未处理异常时,它会创建一个运行进程的 Windows minidump,这很可能是用来分流程序崩溃的。
异常会在终止进程前产生转储。这是一种相当标准的做法,尽管MiniDumpWithFullMemory 在合法软件中可能不太常见,因为它最终可能产生较大的转储,并包含敏感数据。
使用相同的转储文件字符串格式 (%d%02d%02d%02d%02d%02d_sv.dmp) 在谷歌上进行快速搜索,结果仅有 1 ,来自一个中文软件开发网站。
网络通信
如前所述,NANOREMOTE 的 C2 与硬编码 IP 地址通信。这些请求通过 HTTP 发送,JSON 数据通过 POST 请求提交,这些请求经过 Zlib 压缩,并使用 16 字节密钥 AES-CBC 加密 (558bec83ec40535657833d7440001c00) 。所有请求的 URI 都使用带有 User-Agent (NanoRemote/1.0) 的/api/client 。
以下是用于 C2 加密/压缩的 CyberChef 配方:
加密前的每个请求都遵循一个模式,其中包括
- 命令 ID: 相关命令处理程序 ID
- 数据:特定命令对象,包含相应处理程序所需的键/值对
- ID: 分配给受感染主机的唯一机器标识符
下面是一个通过数据对象内的命令键触发执行 whoami 的请求示例:
{
"cmd": 21,
"data": {
"command": "whoami"
},
"id": 15100174208042555000
}
每个回复都采用类似的格式,使用前面的字段和另外两个字段。
- 输出:包含之前请求的命令处理程序的任何输出结果
- 成功:布尔标志,用于判断命令是否成功
下面是之前 whoami 命令的响应示例:
{
"cmd": 21,
"data": 0,
"id": 17235741656643013000,
"output": "desktop-2c3iqho\\rem\r\n",
"success": true
}
命令处理程序
NANOREMOTE 的主要功能由 22 命令处理程序驱动。下面是一个控制流程图(CFG),展示了用于调度不同处理程序的开关语句。
下面是命令处理程序表:
| 命令ID | 描述 |
|---|---|
| #1 | 收集基于主机的信息 |
| #2 | 修改信标超时 |
| #3 | 自行终止 |
| #4 | 按路径列出文件夹内容 |
| #5 | 按路径列出文件夹内容并设置工作目录 |
| #6 | 获取存储磁盘详细信息 |
| #7 | 创建新目录 |
| #8 #9 | 删除目录/文件 |
| #10 #11 | 拆卸(清除缓存、清理) |
| #12 | PE 加载器 - 从磁盘执行 PE |
| #13 | 设置工作目录 |
| #14 | 获取工作目录 |
| #15 | 移动文件 |
| #16 | 通过谷歌硬盘排队下载任务 |
| #17 | 通过谷歌硬盘排队上传任务 |
| #18 | 暂停下载/上传传输 |
| #19 | 简历下载/上传传输 |
| #20 | 取消文件传输 |
| #21 | 执行命令 |
| #22 | PE 加载器 - 从内存中执行 PE |
处理程序 #1 - 收集主机信息
该处理程序会枚举系统和用户详细信息,以剖析受害者环境:
- 使用
WSAIoctl和SIO_GET_INTERFACE_LIST获取内部和外部 IP 地址 - 通过
GetUserNameW - 通过
GetComputerNameW - 通过以下方式检查当前用户是否是管理员组的成员
IsUserAnAdmin - 读取恶意软件使用的进程路径。
GetModuleFileNameW - 使用
WinREVersion和ProductName值名从注册表中检索操作系统信息(产品构建)。 - 通过
GetCurrentProcessID
下面是发送到 C2 服务器的数据示例:
{
"cmd": 1,
"data": {
"Arch": "x64",
"ExternalIp": "",
"HostName": "DESKTOP-2C3IQHO",
"ID": 8580477787937977000,
"InternalIp": "192.168.1.1",
"OsName": "Windows 10 Enterprise ",
"ProcessID": 304,
"ProcessName": "pe.exe",
"SleepTimeSeconds": 0,
"UID": 0,
"UserName": "REM *"
},
"id": 8580477787937977000
}
处理程序 #2 - 修改信标超时
此处理程序可修改 NANOREMOTE C2 通信的信标超时间隔,恶意软件将根据操作员提供的秒数休眠。
下面是该请求的一个示例,NANOREMOTE 使用键 (interval) 和值 (5) 将信标超时时间修改为 5 秒。
{
"cmd": 2,
"data": {
"interval": 5
},
"id": 15100174208042555000
}
处理人 #3 - 自行终止
该处理程序负责将全局变量设置为 0 ,从而有效地提示 NANOREMOTE 拆机和进程退出。
处理程序 #4 - 按路径列出文件夹内容
该处理程序使用操作员提供的文件路径列出文件夹内容。每件物品的清单包括
- 项目是否为目录
- 项目是否标记为隐藏
- 上次修改日期
- 文件名
- 大小
处理程序 #5 - 列出文件夹内容并设置工作目录
该处理程序使用的代码与上一个处理程序(#4)相同,唯一的区别是它将进程的当前工作目录也设置为所提供的路径。
处理程序 #6 - 获取存储磁盘信息
该处理程序使用以下 Windows API 函数从机器上收集存储磁盘信息:
- 获取逻辑驱动器
- GetDiskFreeSpaceExW
- GetDriveTypeW
- GetVolumeInformationW
下面是一个 JSON 格式的请求示例,显示了返回的数据:
{
"cmd": 6,
"data": {
"items": [
{
"free": 26342813696,
"name": "C:",
"total": 85405782016,
"type": "Fixed"
}
]
},
"id": 16873875158734957000,
"output": "",
"success": true
}
处理程序 #7 - 创建新文件夹目录
该命令处理程序根据提供的路径创建一个新目录。
处理程序 #8, #9 - 删除文件、目录
该处理程序支持 #8 和 #9 命令 ID,分支是根据提供的文件路径动态选择的。它具有删除文件或指定文件夹的功能。
10 号、11 号搬运工 - 拆卸/清理
这两个处理程序使用不同的参数调用同一个拆解函数,递归释放堆分配、内部 C++ 对象以及与恶意软件运行时相关的缓存数据。这样做的目的是清理命令结构,防止内存泄漏或不稳定。
处理程序 #12 - 自定义 PE 加载器 - 从磁盘执行 PE
该处理程序包含一个自定义 PE 加载功能,用于加载存在磁盘上的文件。该功能利用标准 Windows API 和libPeConv库中的辅助代码,从磁盘加载 PE 文件,而无需使用传统的 Windows 加载器。
简而言之,它会从磁盘读取 PE 文件,将文件复制到内存中,手动映射各部分/页眉,准备文件,最后在内存中执行。这种实现方式是一种有意绕过用户模式挂钩和传统可见性的隐蔽和规避技术。举例来说,通过这种技术执行文件时,不会留下使用 procmon 启动该可执行文件的痕迹。
下面是该处理程序的输入,其中本地文件路径是在关键字(args)下提供的:
{
"cmd": 12,
"data": {
"args": "C:\\tmp\\mare_test.exe"
},
"id": 15100174208042555000
}
下面的截图显示了使用该技术成功执行测试可执行文件的情况:
在分析过程中,一个有趣的现象是采用了 libPeConv库,这是一个伟大而有用的项目,我们自己在内部使用它来完成各种与恶意软件相关的任务。NANOREMOTE 开发人员使用该库中的几个函数来简化与在内存中手动加载和执行 PE 文件有关的常见任务。以下是 NANOREMOTE 库所使用的函数:
-
default_func_resolver:通过动态加载 DLL 和检索导出函数的地址来解析 PE 文件中的函数。
-
hooking_func_resolver:通过名称从加载的 DLL 中读取函数的虚拟地址。
-
FillImportThunks:通过将每个导入函数解析为其在内存中的实际地址来填充导入表。
-
ApplyRelocCallback:当 PE 文件加载到与其首选基址不同的地址时,应用基址重定位。
该处理程序中另一个值得注意的地方是使用了开源挂钩库Microsoft Detours。该库用于拦截以下 Windows 功能:
- GetStdHandle
- RtlExitUserThread
- RtlExitUserProcess
- 致命退出
- ExitProcess
该运行时挂钩例程可拦截与终止相关的函数,以执行受控行为并提高弹性。例如,NANOREMOTE 可防止单个工作线程出现故障而终止整个 NANOREMOTE 进程。
处理程序 #13 - 设置工作目录
该处理程序使用键(路径)将工作目录设置为特定目录。下面是一个请求示例:
{
"cmd": 13,
"data": {
"path": "C:\\tmp\\Log"
},
"id": 15100174208042555000
}
处理程序 #14 - 获取工作目录
该处理程序将检索当前工作目录,下面是使用前一个处理程序(#13)设置目录后的响应示例。
{
"cmd": 14,
"data": 0,
"id": 11010639976590963000,
"output": "[+] pwd output:\r\nC:\\tmp\\Log\r\n",
"success": true
}
处理程序 #15 - 移动文件
该处理程序允许操作员使用带有两个参数(old_path、new_path)的 MoveFileExW 在受害计算机上移动文件,通过执行复制和删除文件操作将文件移动到不同的文件夹。
处理程序 #16 - 队列下载任务
该处理程序使用提供的 task_id 创建一个下载任务对象,然后将该任务排入下载队列。该实现使用 OAuth 2.0 标记来验证对 Google Drive API 的请求。威胁者利用这一功能将文件下载到受害者机器上。与谷歌服务器之间的加密通信使这些流量看起来合法,让企业无法检查或将其与正常使用区分开来。
在主工作线程中,有一个全局变量用于跟踪队列对象和处理恶意软件的等待任务。
使用 C2 服务器提供的各种字段处理任务:
- type
- 任务
- file_id
- 目标路径
- 文件大小
- md5
处理下载任务时,NANOREMOTE 将使用文件 ID(1BwdUSIyA3WTUrpAEEDhG0U48U9hYPcy7)检索托管在 Google Drive 上的文件大小。接下来,恶意软件会通过 WinHttpSendRequest 下载文件,然后使用 WinHttpWriteData 将文件写入机器。
下面是显示下载过程的控制台输出:
随着威胁组织继续滥用可信云平台进行数据外渗和有效载荷托管,这种恶意软件特征给组织带来了独特的挑战。这种没有任何上下文的流量很容易混入合法流量,使依赖网络可视性的防御者难以检测。
处理程序 #17 - 队列上传任务
该处理程序的工作方式与前一个处理程序(#16)类似,但它创建了一个上传队列任务,并将该任务排入上传队列。威胁行为者使用该处理程序将文件从受害者机器上传到对手控制的 Google Drive 账户。
以下字段由操作员通过 C2 服务器提供:
typetask_idupload_namesource_pathfile_sizemd5
以下是恶意软件通过 Google Drive API(/upload/drive/v3/files )上传测试文件时产生的网络流量。
下图显示了上传过程中的控制台。
下面是之前使用我们自己的 Google Drive 测试账户上传文件功能的演示截图。
以下是该处理程序的响应:
{
"cmd": 17,
"data": {
"file_id": "1qmP4TcGfE2xbjYSlV-AVCRA96f6Kp-V7",
"file_name": "meow.txt",
"file_size": 16,
"md5": "1e28c01387e0f0229a3fb3df931eaf80",
"progress": 100,
"status": "uploaded",
"task_id": "124"
},
"id": 4079875446683087000,
"output": "",
"success": true
}
处理程序 #18 - 暂停下载/上传传输
该处理程序允许操作员通过传递 task_id 来暂停 NANOREMOTE 管理的任何下载和上传任务。
处理程序 #19 - 恢复下载/上传传输
该处理程序允许操作员使用任务 ID 恢复 NANOREMOTE 管理的任何暂停的下载或上传任务。
处理程序 #20 - 取消文件传输
该处理程序允许操作员通过 task_id 取消 NANOREMOTE 管理的任何下载/上传任务。
处理程序 #21 - 命令执行
这是对手在受害者机器上执行命令时使用的主要处理程序。它的工作原理是生成新进程,并通过 Windows 管道返回输出。这是大多数后门的核心功能,被对手用于直接访问,以枚举环境、执行横向移动和执行附加有效载荷。
下图显示了调用该处理程序时 NANOREMOTE 的进程树。恶意软件会生成 cmd.exe,然后启动指定的命令--在本例中就是 whoami.exe。
处理程序 #22 - 从内存执行已编码的 PE
该处理程序在现有的 NANOREMOTE 进程中加载并执行 Base64 编码的 PE 文件。编码后的 PE 文件由 C2 服务器使用 pe_data 字段提供。如果程序需要命令行参数,则使用键(参数)。
下面是使用测试程序显示控制台输出的示例:
与 FinalDraft 相似
从代码相似性和行为角度来看,FINALDRAFT 和 NANOREMOTE 都有重叠之处。
许多功能在两个植入系统中都有明显的代码重复使用。例如,两者都遵循相同的顺序,即通过 CoCreateGuid 生成 GUID,使用Fowler-Noll-Vo (FNV)函数对其进行散列,并在释放缓冲区之前执行相同的堆验证检查。
用于发送和接收请求的大部分 HTTP 相关代码也显示出相似性。下面是一个控制流程图示例,显示了这两个恶意软件家族所使用的 HTTP 请求的设置/配置。
在分析过程中,我们发现 WMLOADER 会从一个名为 wmsetup.log 的硬编码文件中解密相应的有效载荷,这个文件名与我们在今年早些时候发布的PATHLOADER 用于部署 FINALDRAFT 的文件名相同。
另一个有趣的发现是,我们发现了一个样本(wmsetup.log)来自 VirusTotal,最近于 2025-10-03 从菲律宾上传。
我们下载了该文件,将其与 WMLOADER 放在一起,然后执行加载器。它成功解密了wmsetup.log 文件,发现了 FINALDRAFT 植入物。
下面是一张并排图,显示使用相同的 AES 密钥成功解密了 FINALDRAFT 和 NANOREMOTE。
我们的假设是,WMLOADER 使用了相同的硬编码密钥,因为它是同一构建/开发流程的一部分,可以与各种有效载荷协同工作。目前还不清楚这些植入物背后的威胁组织为什么不旋转密钥,可能是为了方便或测试。这似乎是另一个强烈的信号,表明 FINALDRAFT 和 NANOREMOTE 共享代码库和开发环境。
NANOREMOTE 通过 MITRE ATT&CK
Elastic 使用MITRE ATT&CK框架来记录威胁针对企业网络使用的常见策略、技术和程序。
战术
策略代表了技术或子技术的原因。 这是对手的战术目标:采取行动的原因。
技术
技术代表对手如何通过采取行动来实现战术目标。
减轻纳米遥感
在执行 NANOREMOTE 的实验室环境中,使用Elastic Defend 触发了许多不同的警报。
为防御者验证的主要行为之一是滥用合法服务,如 Google Drive API。下面是一个示例,当使用 NANOREMOTE 与 Google API 交互下载和上传文件时,使用 "连接到常见滥用的网络服务 "规则触发警报。
此外,还通过Memory Threat Detection Alert: Shellcode Injection 警报检测到利用 C2 服务器的 Base64 编码文件加载 PE 的技术。
检测/预防
- 利用硬件断点的潜在规避方法
- 通过无效代码签名进行潜在逃避
- 未签名模块中的未备份 Shellcode
- 从低信誉模块执行 Shellcode
- 图片空心来自 Unusual Stack
- 连接常用的网络服务
- 内存威胁检测警报:Shellcode 注入
雅拉
Elastic Security 已创建 YARA 规则来识别此活动。
rule Windows_Trojan_NanoRemote_7974c813 {
meta:
author = "Elastic Security"
creation_date = "2025-11-17"
last_modified = "2025-11-19"
license = "Elastic License v2"
os = "Windows"
arch = "x86"
threat_name = "Windows.Trojan.NanoRemote"
strings:
$str1 = "/drive/v3/files/%s?alt=media" ascii fullword
$str2 = "08X-%04X-%04x-%02X%02X-%02X%02X%02X%02X%02X%02X" ascii fullword
$str3 = "NanoRemote/" wide
$str4 = "[+] pwd output:" wide
$str5 = "Download task %s failed: write error (wrote %llu/%zu bytes)"
$seq1 = { 48 83 7C 24 28 00 74 ?? 4C 8D 4C 24 20 41 B8 40 00 00 00 BA 00 00 01 00 48 8B 4C 24 28 FF 15 ?? ?? ?? ?? 85 C0 }
$seq2 = { BF 06 00 00 00 89 78 48 8B 0D ?? ?? ?? ?? 89 48 ?? FF D3 89 78 78 8B 0D ?? ?? ?? ?? 89 48 7C FF D3 89 78 18 8B 0D }
condition:
4 of them
}
rule Windows_Trojan_WMLoader_d2c7b963 {
meta:
author = "Elastic Security"
creation_date = "2025-12-03"
last_modified = "2025-12-03"
license = "Elastic License v2"
os = "Windows"
arch = "x86"
threat_name = "Windows.Trojan.WMLoader"
reference_sample = "fff31726d253458f2c29233d37ee4caf43c5252f58df76c0dced71c4014d6902"
strings:
$seq1 = { 8B 44 24 20 FF C0 89 44 24 20 81 7C 24 20 01 30 00 00 }
$seq2 = { 41 B8 20 00 00 00 BA 01 30 00 00 48 8B 4C C4 50 FF 15 }
condition:
all of them
}
观察结果
本研究讨论了以下可观察的结果。
| 可观测 | 类型 | 名称 | 参考 |
|---|---|---|---|
| fff31726d253458f2c29233d37ee4caf43c5252f58df76c0dced71c4014d6902 | SHA-256 | BDReinit.exe | WMLOADER |
| 999648bd814ea5b1e97918366c6bd0f82b88f5675da1d4133257b9e6f4121475 | SHA-256 | ASDTool.exe | WMLOADER |
| 35593a51ecc14e68181b2de8f82dde8c18f27f16fcebedbbdac78371ff4f8d41 | SHA-256 | mitm_install_tool.exe | WMLOADER |
| b26927ca4342a19e9314cf05ee9d9a4bddf7b848def2db941dd281d692eaa73c | SHA-256 | BDReinit.exe | WMLOADER |
| 57e0e560801687a8691c704f79da0c1dbdd0f7d5cc671a6ce07ec0040205d728 | SHA-256 | 纳米遥感 |
