漏洞深度解析:Zoom周界网络服务风险与防护)
部署过 Zoom 的企业安全团队大概率已经留意到一条编号为 CVE-2024-48972 的漏洞消息安全研究者把它命名为 Zoomsday说它是一个能让攻击者在 Zoom 会议中接管参会设备的远程代码执行漏洞。攻击者的操作路径并不复杂只要与受害者进入同一个会议发一条恶意链接受害者点击后攻击就可能发生。这个漏洞的高风险之处不仅在于后果严重更在于它攻击的是大多数用户完全不熟悉的组件Zoom 客户端的周界网络服务Perimeter Network ServicePNS和自定义 URI 协议处理器。接下来我会从漏洞成因、攻击链路、本地验证、加固方案和排查方法几个层面把这条漏洞拆解成可操作的安全知识。1. 先理解 Zoomsday 漏洞的成因而不是只背编号1.1 这不是会议功能漏洞而是边界通信组件的漏洞Zoom 客户端不是单进程程序。它至少可以分为几个模块负责界面交互的主程序、负责音视频编解码和处理的多媒体组件、负责网络穿越和链路建立的周界网络服务以及一批自定义 URL 协议处理器。周界网络服务解决的问题很实际企业网络里存在 NAT、防火墙、复杂代理策略Zoom 需要在各种网络环境下建立可靠的双向连接。PNS 就是那个负责把客户端和 Zoom 的全球网络基础设施连接起来的底层通道。在正常业务中这个模块应该在后台默默工作。但安全研究者发现PNS 在处理某些特殊请求时缺少足够校验而 Zoom 又把一批系统级 URL 协议例如zoommtg://注册到了 Windows 注册表。任何一个浏览器、邮件客户端、聊天工具在遇到这种协议头时都会把后续请求转交给本地 Zoom 客户端。这两个机制叠加就成了漏洞入口。这里要注意Zoom 会议房间本身是走加密传输的会议内部普通用户的权限边界也比较清晰。这个漏洞攻击的不是“会议内说话”这种功能层而是“客户端如何唤起本机进程并执行外部指令”这一层。把关注点放在这层才能理解为什么一个会议链接可能导致设备被接管。1.2 漏洞的攻击前提与影响范围先明确攻击门槛攻击者需要与受害者处于同一个 Zoom 会议中。攻击者需要通过会议聊天、私聊或外部方式发送一个恶意链接。受害者需要点击该链接连接才会被交给 Zoom 客户端处理。攻击者利用 PNS 解析请求过程中的缺陷最终在受害者的设备上执行任意代码。所以这个漏洞不是完全无条件的零点击漏洞。但“同一个会议加点击一次链接”的门槛仍然很低。如果一个员工处于任何包含外部参与者的会议中而外部参与者又刻意发送了一条链接就存在被攻击的可能。从影响范围看公开披露信息将问题定位在 Windows 桌面客户端。漏洞一旦利用成功攻击者可以拿到当前登录用户上下文下的代码执行权限进而完成密钥窃取、横向移动、持久化驻留等动作。对于企业会议场景这台设备往往是办公电脑价值很高。维度要点漏洞编号CVE-2024-48972组件位置周界网络服务Perimeter Network Service触发入口自定义 URI 协议处理流程攻击前提与受害者处于同一 Zoom 会议并诱导其点击链接利用后果在受害者设备上执行任意代码影响平台Windows 桌面客户端旧版本具体以官方公告为准1.3 为什么叫 Zoomsday“Zoomsday” 是安全研究者对这个漏洞起的代称不是 Zoom 官方漏洞名称。名字的含义很简单这个漏洞让一次普通会议变成“末日”级别的安全事件。研究者通过该命名强调攻击一旦成立一次通话就能演变为设备级入侵。由于视频会议已经成为企业内部沟通的常态化基础设施这样一个低门槛远程代码执行漏洞获得的关注度自然很高。需要留意的是Zoomsday 只是传播中的代称。在企业内部通报、漏洞管理平台登记、SRC 跟踪时仍然应该以 CVE 编号和 Zoom 官方安全公告为准。2. 攻击链路拆解从会议链接到设备接管接下来把攻击链路拆开看看每一步发生了什么。这里不提供可执行的利用代码因为真实利用测试必须在获得授权的隔离环境中进行。把链路拆清楚目的是让应急响应人员知道在哪个环节可以看到异常、在哪个环节设置拦截点。2.1 第一步攻击者进入目标所在的会议攻击者只需要拥有一个 Zoom 账号然后想办法出现在目标的会议中。现实中公开会议链接、被转发到社群的会议链接、允许外部参会者开放的会议室都会扩大攻击者的接触面。如果是内部会议攻击者可以先通过钓鱼或者社会工程手段拿到会议号如果是公网开放会议甚至不需要额外社交。这一步没有技术难度却决定了漏洞能否被触发。安全运营团队平时关注的重点往往是“会议是否加密”“主持人权限是否可控”但容易被忽略的一点是外部参与者一旦进入会议就拥有了向聊天窗口发送内容的能力。2.2 第二步URI 协议处理器被触发Zoom 在 Windows 安装时会注册多个自定义协议常见的有zoommtg://、zoomus://、zoomphonecall://等。这些协议的作用是让网页或邮件里的“点击加入会议”按钮可以直接唤起本机 Zoom 客户端自动带上会议号、密码、显示名称等参数。从 Windows 系统角度看这等同于注册了一台本地应用的“入口”。浏览器一旦发现链接以zoommtg://开头就会查询注册表把完整链接传给 Zoom 客户端。问题在于这个入口的参数校验本应由 Zoom 客户端完成。如果客户端只校验会议号是否合法而忽略其他字段攻击者就能在链接中附加额外指令并把指令拼接到 PNS 的请求参数里。检查点在 Windows 上管理员可以用下面的命令查看相关协议当前指向的可执行文件$schemes (zoommtg,zoomus,zoomphonecall) foreach ($scheme in $schemes) { $key Registry::HKEY_CLASSES_ROOT\$scheme\shell\open\command $item Get-ItemProperty -Path $key -ErrorAction SilentlyContinue if ($item) { Write-Host ({0} - {1} -f $scheme, $item.(default)) } else { Write-Host ({0} - 未注册 -f $scheme) } }正常情况下该命令会输出来自 Zoom 安装目录的可执行文件路径。如果看到路径被指向一个临时目录或陌生文件就需要立即告警。2.3 第三步恶意请求进入周界网络服务当 Zoom 主程序收到 URL 后会解析其中的参数。公开分析普遍认为问题出在 PNS 对传入网络地址、代理配置或通道参数的信任上。攻击者可以让 PNS 在建立通道时访问攻击者控制的地址并把本地网络请求从一个“内部连接”变成“可控外部请求”。这个环节是漏洞的核心也是安全团队最难监控的部分。因为 PNS 与 Zoom 云端的通信是加密的网络层只能看到客户端和某个 Zoom 服务器 IP 建立了 TLS 连接无法看到里面还掺杂了攻击者注入的指令。2.4 第四步远程代码执行当攻击者控制 PNS 发起的外部请求后可以利用响应内容触发客户端解析缺陷最终写入并执行攻击者提供的二进制内容。到这一步攻击者就获得了目标设备上当前用户权限的代码执行能力。可以进行的后续操作包括但不限于读取当前用户桌面的敏感文件。通过已登录的浏览器会话窃取企业应用权限。植入持久化任务等待设备重启。利用内网可达性继续横向移动。从攻击链看每个阶段的特点可以整理成一张表攻击阶段攻击者动作依赖条件可观察信号进入会议加入目标会议会议号或邀请链接外部参会者进入通知发送链接通过聊天发送恶意链接会议允许聊天聊天记录中有外链触发协议引导目标点击链接目标操作系统注册了协议客户端日志中出现 URL 解析记录注入请求构造恶意参数进入 PNSPNS 缺少输入校验日志、流量难以直观发现接管设备执行来自攻击者的代码请求校验缺陷利用链成立异常进程、文件、网络连接3. 防御视角下的本地验证用命令确认暴露面对于普通用户看到安全新闻后第一反应是“我中招了吗”。对于管理员第一反应应该是“我的客户端基线现在还安全吗”。下面这组检查可以在 Windows 办公电脑上执行用来确认客户端是否还停留在旧版本、协议处理器是否被劫持、PNS 进程是否异常。3.1 检查 Zoom 客户端版本版本检查是优先级最高的一步。升级到官方安全版本后漏洞利用链就会被补丁阻断。可以用 PowerShell 读取安装目录下主程序的产品版本$paths ( $env:ProgramFiles\Zoom\bin\Zoom.exe, ${env:ProgramFiles(x86)}\Zoom\bin\Zoom.exe ) foreach ($p in $paths) { if (Test-Path $p) { $info (Get-Item $p).VersionInfo Write-Host (路径: {0} -f $p) Write-Host (版本: {0} -f $info.ProductVersion) Write-Host (文件版本: {0} -f $info.FileVersion) } else { Write-Host (未找到: {0} -f $p) } }命令执行后把输出结果与 Zoom 官方安全公告中的修复版本进行对比。如果版本低于修复版说明当前仍然存在暴露风险。这里要注意Zoom 桌面客户端可能存在多个安装位置32 位和 64 位路径都要检查。3.2 检查自定义协议处理器是否被篡改Zoomsday 利用的是zoommtg等协议链路的缺陷。协议处理器本身被注册是正常现象如果被修改到非 Zoom 目录就是另一种异常信号。将下面的注册表检查命令放到多台主机上执行输出到一个汇总文件方便对比基线$output () $schemes (zoommtg,zoomus,zoomphonecall) foreach ($scheme in $schemes) { $key Registry::HKEY_CLASSES_ROOT\$scheme\shell\open\command $item Get-ItemProperty -Path $key -ErrorAction SilentlyContinue if ($item) { $output [PSCustomObject]{ Scheme $scheme Command $item.(default