Reolink 桌面应用程序(版本 8.18.12)在其缓存清理调度器(coverCacheClearScheduler)功能中存在操作系统命令注入漏洞。该应用程序使用从位于 %LOCALAPPDATA% 内的配置文件中读取的临时文件夹路径来构造操作系统 shell 命令。由于该路径值缺乏适当的输入清理,攻击者可以操纵该路径以注入任意操作系统命令。
该漏洞由调度器触发,调度器每天凌晨 3:00 自动运行,为攻击者提供了系统上的持久性。此外,注入的命令作为合法的、经过数字签名的 Reolink.exe 进程的一部分执行,从而通过规避安全解决方案的检测来实现隐蔽性。
该应用程序初始化一个调度器,每天凌晨 3:00 运行:
{
key: "clearCoverCacheRegularly",
value: function () {
if (this.coverCacheClearScheduler) {
var e = new Date(),
t = new Date(
e.getFullYear(),
e.getMonth(),
e.getDate(),
3,
0,
0,
).getTime();
(e.getTime() > t &&
(t = new Date(
e.getFullYear(),
e.getMonth(),
e.getDate() + 1,
3,
0,
0,
).getTime()),
this.coverCacheClearScheduler.add({
id: this.clearCoverCacheTaskId,
name: "clearCoverCache",
unit: r.ETaskUnit.DAY,
interval: 1,
args: !1,
execute: this.removeCoverCacheDir,
nextTime: t,
isInExact: !0,
}),
this.coverCacheClearScheduler.start());
}
},
}
调度器执行的函数使用以下逻辑构造 shell 命令字符串:
p(
"darwin" === process.platform
? "rm -rf ".concat(t)
: "rd /s /q ".concat(t),
function (t) {
//...
在 Windows 上,生成的命令为:
rd /s /q %LOCALAPPDATA%\Temp\reolink\<TEMP_FOLDER>\playback-covers
在 macOS 上,生成的命令为:
rm -rf ~/Library/Caches/reolink/<TEMP_FOLDER>/playback-covers
由于 <TEMP_FOLDER> 未经过适当清理,攻击者可以通过文件夹名称操纵注入额外命令,从而导致命令执行:
rd /s /q %LOCALAPPDATA%\Temp\reolink\& <COMMAND> &\playback-covers
rm -rf ~/Library/Caches/reolink/& <COMMAND>; echo /playback-covers
触发该攻击需要修改本地文件,这需要另一个漏洞、恶意软件执行或对系统的物理访问。
虽然初始触发相对困难,但一旦成功,攻击效果非常显著,因为它通过每天凌晨 3:00 自动重新执行有效负载来提供持久性。这种持久性还因该应用程序作为物理安全工具的性质而得到增强,此类工具通常 24/7 保持运行。它还支持“开机启动”功能,确保有效负载在重启后仍然存活。
此外,攻击者获得了显著的隐蔽性。该命令作为受信任的、经过数字签名的 Reolink.exe 进程的一部分执行,使其在绕过 EDR 和应用程序白名单解决方案方面非常有效。这是一种经典的“离地攻击”(LOTL)技术。
该攻击可以通过运行 poc.py 来执行,该脚本会修改本地配置文件。这是通过链接与加密不足相关的其他漏洞(CVE-2025-56801 和 CVE-2025-56802)实现的,这些漏洞用于解密和重新加密配置文件。
通常,有效负载只会在凌晨 3:00 触发。然而,由于该应用程序未使用 ASAR 打包,可以修补代码以立即触发漏洞用于演示目的。
执行结果如下:
https://github.com/user-attachments/assets/44bf4d84-b8bf-4f4a-853c-07380ce26783
更多详细信息,请参阅 CVE-2025-56801(AES-CFB IV 生成漏洞)和 CVE-2025-56802(AES-CFB 密钥生成和管理漏洞)。
要从根本上解决此操作系统命令注入漏洞,必须避免将来自不受信任的外部来源(如用户配置文件)的值直接包含到操作系统 shell 命令字符串中。推荐的解决方案是使用将路径视为纯数据而非命令的原生 API 来替代 rd 或 rm 等 shell 命令,例如 Node.js 的 fs.rm()。此方法可完全消除此类漏洞。
如果绝对无法避免构造 shell 命令,则必须实现防御性逻辑,严格验证并清理或转义所有可能导致命令注入的特殊字符,例如 &、| 和 ;。