导语:在狩猎WMI持久化异常时,安全研究人员在一台企业工作站上发现了一个极不寻常的后门程序。12KB大小,没有运行时库,没有加壳,导入表干净得像是正经软件。但它的配置存放方式彻底打破了常规——C2服务器地址藏在Windows desktop.ini文件的空格数量里。空格也能藏数据?这不是黑魔法,是进制编码的恶趣味变种。
一、发现背景
GEN Digital(GEN数字安全,原Genesec/NortonLifeLock)旗下 New Gen Threat Labs 研究人员在一次WMI持久化狩猎中,于一台企业 Windows 7 SP1 64位工作站上偶然发现了这个后门。
这台机器的特殊之处在于:二进制样本的全球感染量精确等于 1。
通常,低感染量意味着攻击失败了。但这一次,低 prevalence 更可能意味着:这根本不是撒网式的批量攻击,而是一次精心策划的定向入侵。一个手工打造的植入物,只出现在一台机器上——恰恰说明它可能正在完美运作。
二、后门伪装:Realtek 音频控制面板
后门二进制文件名为 RtkNGUI64.exe,与 Realtek 真实的音频控制面板程序同名。
它通过 WMI事件订阅 实现持久化,伪装成正常的系统行为:
MSFT_Intermittent-Run_TFilter
TargetInstance: SELECT * FROM __InstanceModificationEvent
WITHIN 60 WHERE TargetInstance ISA 'Win32_LocalTime'
AND TargetInstance.Hour = 19 AND TargetInstance.Minute = 50
每天 19:50 准时激活,发送 beacon,然后继续潜伏。大多数恶意 WMI 订阅的查询语句一看就不正常——但这一个,查询 Win32_LocalTime 在特定时间触发,任何管理员都可能写出这样的排程。
这正是它的高明之处:用合理的行为掩盖恶意的意图。
三、核心剖析:12KB 里有什么?
后门本体是一个 12,288 字节的 x64 可执行文件,没有任何 C 运行时库,不加壳,入口点直接进入主循环。
导入表干净: 仅依赖 6 个 DLL — KERNEL32、WININET、WS2_32、IPHLPAPI、SHLWAPI、ADVAPI32,共导入 48 个函数。没有 msvcrt.dll,而且这是作者刻意为之。
命令集极简: 仅有三个指令
system— 执行命令,30秒超时put— 写入文件time— 更改心跳间隔
通讯协议:
- 先发 ICMP ping 检测网络连通性
- ping 成功后发 HTTP POST 到
/version/check.php - beacon 格式:
a=<ID>&r=<结果>,无结果时r=none
四、精华:C2地址藏在空格数量里
这是整个后门最精彩的部分——它的配置文件根本不是普通的数据块,而是借用了 Windows desktop.ini 文件的格式。
编码原理
标准的 Windows Program Files desktop.ini 文件大小是 174 字节,包含 BOM、ShellClassInfo 区段、LocalizedResourceName 等内容。
攻击者在这个标准文件末尾追加自定义数据,而这些数据的编码方式极其巧妙:
每行结尾的空格数量 = 域名对应字符的 ASCII 码
例如,要编码 diagrtrack.com,每行分别对应:
| 行号 | 空格数 | ASCII字符 |
|---|---|---|
| 1 | 100 | d |
| 2 | 105 | i |
| 3 | 97 | a |
| 4 | 103 | g |
| 5 | 114 | r |
| 6 | 116 | t |
| 7 | 114 | r |
| 8 | 97 | a |
| 9 | 99 | c |
| 10 | 107 | k |
后门读取文件时,从字节 174 开始,逐行统计空格数量(UTF-16LE 编码,每字符占2字节),再将空格数转换为 ASCII 字符,拼出完整域名 diagrtrack.com。
这是一个 一元编码(Unary Encoding) 的经典案例——空格数量本身就是数据。
解码脚本
HEADER_LEN = 174
def decode(path):
with open(path, "rb") as fh:
payload = fh.read()[HEADER_LEN:]
counts, current, i = [], 0, 0
while i < len(payload):
if payload[i] == 0x0D:
counts.append(current)
current = 0
i += 4
continue
current += 1
i += 2 # UTF-16LE
if current:
counts.append(current)
return "".join(chr(c) for c in counts) + ".com"
typosquatting 的恶意幽默
C2 域名 diagrtrack.com 故意拼错了 Windows 的 DiagTrack 服务(微软的”连接用户体验和遥测”服务)。攻击者把后门的 C2 服务器伪装成 Windows 自己的遥测域名——这是一个充满恶意的玩笑。
暴露的指纹
由于每个字符的 ASCII 码直接决定空格数量,配置文件大小 = 174 + 2 × Σ(字符ASCII码) + 4 × 行数。
对于 diagrtrack.com,文件大小恰好是 2,318 字节。文件大小本身就是域名的指纹——即使不知道域名是什么,也可以从文件大小反推 C2 地址。
五、两个隐蔽细节
文件落地时的”假PE”技巧
put 指令在写入可执行文件时,先将内容 base64 解码后,把第一个字节 -1、第二个字节 +1,写入 tempcache.tmp,再重命名为目标路径,最后才 patch 回去正确的那两个字节。
也就是说,磁盘上的 PE 文件在落地瞬间,其 MZ 签名是损坏的(L[ 而不是 MZ),直到最后一次写操作才恢复正常。任何基于文件创建或重命名时刻扫描的安全工具,看到的是一个”非 PE 文件”。
字符串拼接躲字符串扫描
后门的 cmd.exe 不以完整字符串存在于二进制中,而是在调用时现场拼接:
wnsprintfA(buffer, 0xFFFF, "c%s%se /c %s", "md.", "ex", command);
"md." + "ex" = "mdex" → "cmd.exe"。字符串扫描工具 grep 这个二进制,只会找到破碎的片段。
六、时间线与归属分析
| 时间 | 事件 |
|---|---|
| 2020年7月23日 | diagrtrack.com 注册(隐私代理) |
| 2020年12月2日 | 后门编译(13:34 UTC) |
| 2020年12月2日 | 配置文件在受害者主机上创建(编译后约3小时) |
| 2020年12月23日 | GEN Digital 软件安装 |
| 2021年3月 | C2域名最后一次DNS响应 |
| 2021年7月 | 域名过期,未续期 |
关键洞察: 攻击者在 GEN Digital 软件安装 21天前 就已经完成了入侵。这意味着初始入口根本不在监控范围内。无论攻击者是怎么进来的,他们进入时这是一台”无人看守”的机器。
域名早已失效,但 WMI 订阅仍然每天 19:50 准时激活后门进程,试图连接一个已经不存在的服务器——然后无声地失败。
七、归属研判
研究人员在 VirusTotal 上对以下特征进行了全面关联搜索:
- 代码中的 format string
c%s%se /c %s - beacon 格式
a=%s&r=none /version/check.php路径- UTF-16 空格特征
全部返回空结果。
四种不同的特征,两两独立,没有任何样本在VirusTotal上有关联。这不是泄露的工具,不是开源改写,而是一个完全定制的专有后门,在野的唯一一个样本。
低感染量 = 工具失败?不,这个案例里低感染量 = 工具在正常工作。
八、检测与防御建议
针对此后门的防御思路:
- 监控 ProgramData 目录下的 desktop.ini 文件大小 — 超过224字节的 desktop.ini 值得警惕
- WMI订阅审计 — 检查名为”Realtek”或涉及 Win32_LocalTime 19:50 触发的 MSFT 订阅
- 进程行为监控 — RtkNGUI64.exe 尝试 DNS 解析 diagrtrack.com(或其变种)
- 文件完整性 — 关注 ProgramDatadesktop.ini 的创建和修改时间
九、参考资料
📖 GEN Digital 原版分析报告: 👉 https://www.gendigital.com/blog/insights/research/kb-backdoor
🔍 NVD 漏洞库: 👉 https://nvd.nist.gov(搜索 KB Backdoor 相关)
版权声明:本文由华盟网原创发布,保留所有权利。配图由华盟网授权使用。














暂无评论内容