概述
每当 USB 设备插入 Windows 机器时,操作系统可能会静默地从 Microsoft 下载软件包,并以 NT AUTHORITY\SYSTEM 身份执行厂商代码。这种情况不需要管理员权限,无需登录用户,甚至在某些环境中可以通过 RDP USB 重定向远程实现。
这是 DEF CON 34 演讲的发布套件。我们会发布所有内容,包括工具,方便你重现 PnP 部分并自行验证这些攻击原语。
- [00] 插头与打印:物理零点击链(Sierra + 索尼)
- [01] NoPlug 和 Pwn:RDP USB 重定向,无需硬件
- [02] PnP 内部结构与 PNP 模拟
- [03] 厂商组合:Wacom + Atheros LPE
- [04] 资料与脚本
攻击载体
每当 USB 设备插入 Windows 机器时,操作系统可能会静默地从 Microsoft 下载软件包,并以 NT AUTHORITY\SYSTEM 身份运行厂商代码。不需要管理员权限,也无需登录用户。在合适的条件下,它甚至可以远程工作,完全不需要在机器上插入任何物理设备。下面的攻击向量将引导你进入该安装流程,并对其中的供应商安全缺陷进行原语化利用。
[00] 插头与打印:物理零点击链(Sierra + 索尼)
实验环境:左侧是一台完全更新的 Windows 11 主机,没有用户登录,也没有预装任何软件。右侧是一台运行 FaceDancer 的 Linux 机器,用于模拟 USB 设备。整个过程从零点击到获得 SYSTEM 权限,实际运行时间大约需要五分钟。最后我们放置一个标记文件并打开一个 SYSTEM shell,以证明攻击的真实性。
这是安装路径被滥用的一个典型案例。我们从不同供应商处串联起低严重性漏洞(有些供应商甚至不认为这些是漏洞),使它们组合起来产生更大的影响。物理链的运行方式如下:
- 使用 FaceDancer 模拟某个特定的 Sierra 设备,然后轮询由该易受攻击组件创建的、具有 Everyone 读写权限的命名管道。
- 管道出现后,利用它修改机器的默认 DNS。我们搭建的 DNS 服务器会将所有流量重定向到 Google DNS,除了目标域名。
- 模拟 索尼设备。服务安装完成后,它会通过 HTTP 从索尼服务器下载组件。由于我们控制了 DNS,因此我们就成为了那些索尼服务器。
- 提供特制文件进行利用:以 SYSTEM 权限实现任意文件写入,将 DLL 写入
System32目录。 - 再次模拟 Sierra 设备,触发我们的 DLL 被加载。这在任何用户登录之前,就实现了
NT AUTHORITY\SYSTEM权限的任意代码执行。
Sierra Wireless:SwiService.exe
Sierra Wireless 服务以 SYSTEM 身份运行,并暴露一个具有 Everyone 读写权限的命名管道。任何本地用户或域用户都可以连接并调用 SetDNS 函数,无论是本地还是通过 SMB。我们将 DNS 指向攻击者地址,用自己的服务器替换索尼的查询。虽然可执行文件是硬编码的,接口名称来自系统查找,无法注入,但这并不重要——我们想要的效果(将 DNS 指向任意 IP)正是攻击所需。
索尼 FeliCa:felica_coinst.dll
根本原因在于签名目录文件中包含一个以 SYSTEM 身份运行的共同安装 DLL。在即插即用过程中,它通过明文 HTTP 获取配置文件,并信任接收到的所有信息。编排器通过 HTTP 拉取三个文本文件(安装列表、URL 列表和应用信息),并决定如何处理安装。
在下载这些文件时,它会通过提取 URL 中最后一个斜杠之后的所有内容来推导磁盘上的文件名。没有对点和反斜杠进行过滤:解析器只扫描到最后一个 /,然后切换到反斜杠进行路径穿越。提取的字符串被拼接后用作写入目标。这就是以 SYSTEM 权限在磁盘任意位置写入任意文件,内容完全由攻击者控制,我们直接将其写入 System32。我们无法控制索尼的服务器,因此利用 Sierra 的 DNS 漏洞来成为它。
两个来自不同厂商的低严重度漏洞,串联成以 SYSTEM 权限执行的任意代码执行。
[01] NoPlug 和 Pwn:RDP USB 重定向,无需硬件
上述所有功能都需要一个前提:使用 FaceDancer 模拟 USB 设备。一个显而易见的质疑是,这需要物理访问,必须插入设备。如果我们不需要物理接触呢?如果我们能通过正常的 RDP 会话、在机器上完全没有任何物理连接的情况下,通过网络到达同样的 PnP 安装路径呢?目标:利用一个拥有 RDP 访问权限但无管理员权限的标准用户,将其转化为 SYSTEM 权限,全程远程执行。
关键在于一个名为 RDP USB 重定向 的功能。其合法目的很简单:你将 USB 设备插入笔记本,它就会转发到远程会话中。问题在于,服务器根据客户端发送的 USB 描述符构建 PnP 设备节点。客户端描述硬件,服务器照单全收。另一端不一定需要存在真实设备。
策略门槛:umrdp.dll / termsrv.dll
设备到达后,服务器会打开终端服务策略密钥,检查 fDisableUSBRedir 之后再接通调用。这正是 Windows 承诺以 SYSTEM 身份安装驱动程序的地方。它由一个组策略设置保护:fDisablePNPRedir。我们逆向分析了服务器端 termsrv.dll。它从会话配置词中打包单个比特位(第 11 位),即策略,并在声告我们的设备之前检查该位。默认设置为禁用,只有当 fDisablePNPRedir 恰好为 0 时才启用。我们没有输入权;这完全是服务器端状态。那么问题来了:这扇门在哪里已经打开了?答案是那些有意启用 USB 重定向的环境,比如托管 VDI 部署。
英特尔 RealSense PoC
我们不制造真实设备,而是伪造一个。我们基于一个名为 aardwolf 的库编写了一个纯 Python 的 RDP 客户端,完全没有硬件。以普通用户身份认证,打开 URBDRC 通道,然后发送任意 VID 或 PID 的消息。当服务器请求 ADD_DEVICE 描述符时,我们即时合成。服务器的 USB 集线器驱动枚举了我们的虚拟设备,Windows PnP 的功能与物理演示中完全一致:匹配硬件 ID 并以 SYSTEM 身份安装驱动程序。
这次演示我们选择了不同的供应商——Intel RealSense 摄像头,以证明这不是一次性的。这本身就是一个精彩的特权提升漏洞。驱动由 Microsoft 签名,并通过 Windows Update 安装,安装过程中其共同安装程序会将可执行文件放入可写的用户目录,并以 SYSTEM 身份运行。该可执行文件在检查 System32 中的 CRYPTBASE.dll 之前,会先在自己的文件夹中寻找 DLL,而该文件夹可以由普通用户写入。一个系统进程,在我们可以控制的目录中搜索 DLL。这就是典型的 DLL 劫持,只不过现在我们可以在远程行动。作为普通用户,我们输入恶意 DLL,无需插入任何设备,最终写入只有 SYSTEM 才能触及的位置。
POC 1 // 标准用户 RDP,基于 URBDRC 伪造 Intel RealSense,以 SYSTEM 身份安装签名驱动,共同安装程序侧载 CRYPTBASE.dll,获得 SYSTEM 权限。没有插入任何硬件。
[02] PnP 内部结构与 PNP 模拟
拉远视角来看,我们真正滥用的是安装路径本身。Windows PnP 会很乐意从 Windows Update 获取并加载数百个易受攻击的签名包,完全信任,无需特权提升。PnP 变成了加载器。经典的前提条件——需要管理员权限才能植入东西——在启动时就消失了。我们通过两种方式到达了同样的路径:一种是通过物理 FaceDancer,另一种是通过 RDP 远程进行。在研究过程中,我们使用了第三条路径来打开黑匣子:PNP simulate,这是我们开发的一个工具。
PNP simulate 并非最终的攻击路径。它是我们复制即插即用安装流程以便在受控环境中进行测试的方式,每次测试都不依赖真实硬件。它不仅仅是打印 VID 和 PID。它通过设置 DI API 创建带有 USB 硬件 ID 的 ROOT 枚举设备,注册设备,在本地驱动存储中查找匹配,使用 DIInstallDevice、IUpdateSearcher 查询 Windows Update COM,并注册即插即用通知。
两种模式很重要。默认为仅查询:创建临时开发节点,查询,观察事件,清理现场。不会下载软件包,也不会留下持久化更改。用于发现目的。安装标志调用 CM_Setup_DevNode 时传入 CM_SETUP_DEVNODE_READY,强制开发节点进入真实安装路径。这为我们提供了一种受控的方式来比较发现过程和实际安装过程。
研究中的一个陷阱是:很容易说"Windows Update 返回了一个包,所以 Windows 会安装它。"但事实并非如此。Windows Update COM API 返回大量元数据:自动、手动、旧版和仅目录包。对于发现来说很有用,但对于利用来说,真正重要的是使用服务器端解析的设备安装服务,这是一条过滤得多的路径。许多候选包通过 Windows Update COM 看起来可用,但真正通过 PnP 路径自动下载的要少得多。
真实流程,分为四个阶段
第一阶段:USB 描述符(VID / PID / 类 / 接口)成为 Windows 与 INF 匹配的硬件 ID 字符串。
第二阶段:向开发节点提交身份。在真实的 USB 路径中,集线器会识别被模拟的设备并读取描述符,创建物理设备对象,使总线关系失效以告知 PnP 管理器有了新的子设备。PnP 管理器创建开发节点。在 PNP simulate 中,我们从用户模式重现,只保留我们关心的部分:创建设备信息集,设置硬件 ID,并注册设备。
第三阶段:CM_Setup_DevNode。我们不想仅依赖文档,因此使用 WinDbg 进行了考察。调用进入 LocalCMSetupDevNode 并最终到达 DeviceIoControl(IOCTL 0x47084F),进入配置管理器,即内核中 PnP 端。用户模式调用并不完成所有工作:它将一个动作推送到 PnP,动作被排队,真正的工作异步继续。这次捕获确认安装标志正在进入激活真实安装的路径。
第四阶段:PnP 工作器与设备安装服务。PnP 工作器查询设备 ID,解析兼容性问题,添加并启动开发节点,需要兼容包。这就是设备安装服务的用武之地:DSMSVC,在 svchost 内,以 SYSTEM 身份运行。它在本地驱动存储中查找;如果没有匹配,可以使用服务器端解析;如果该包可以自动安装,Windows 从 Windows Update 下载 CAB 文件,存入驱动存储,并启动安装序列,其中出现 DRVINST。如果该包带有共同安装程序、支持可执行文件、服务或额外逻辑,这些软件就会进入用户未通过 UAC 提示批准的特权路径。
[03] 厂商组合:Wacom + Atheros LPE
Windows 已接受硬件身份,对签名或已知包进行了解析,并进入了特权安装路径。但密码学信任和逻辑安全是有区别的。签名包并不意味着每个服务、共同安装程序、调试标志或注册表值都经过攻击角度的审计。没有 UAC 并不代表没有特权边界。这也是为什么供应商对话会变得复杂。通常没有溢出,没有真正的释放后使用,没有崩溃。存在的是接受用户或其他组件可控输入的特权逻辑。单独看,每个部分看起来都有一定功能性。综合来看,结果是安全影响。
Wacom:SYSTEM Shell
在 Wacom 服务二进制文件(作为签名包的一部分分发)中,我们发现了一个与硬编码值 7F 4C 6B 34 相关的比较逻辑。在注册表中,它表现为 REG_BINARY 类型的 PowerT 值。当服务在 HKLM\SYSTEM\CurrentControlSet\... 的正确键中看到这个值时,它会沿着一条路径执行,最终以 SYSTEM 身份运行 CMD。我们不会说它是后门。可能是调试存根、支持功能,或者是本不该暴露的内部路径。从攻击角度看,这是一个非常干净的漏洞。值名为 AutoAdminLogon,写入如下内容,周围有门控(门必须为零或不存在)。当检查通过时,WTabletServiceISD 调用 CreateProcessAsUserW,以 LocalSystem 身份运行,访问默认桌面并生成 CMD。这不是一个隐藏的 Session-0 进程,而是用户桌面上的交互式 SYSTEM shell。然而,写入该值本身需要标准用户所不具备的一件事:对 HKLM 的写权限。
POC 3 // Wacom 隔离:在 WTabletServiceISD 键下写入 PowerT(REG_BINARY,7F 4C 6B 34),重启服务,获得交互式 CMD,whoami 显示 NT AUTHORITY\SYSTEM。
Atheros:特权注册表写入
那么,我们是否有另一个同样由 PnP 安装的组件,可以帮我们完成那个特权写入部分?Atheros。经过审核,它与七年前(2019 年)的 CVE 匹配。我们原以为 Microsoft 会撤销证书,软件包也无法安装。但事实是:现在依然可以。软件包安装 AtherosSVC(管理员服务),以 LocalSystem 身份运行。它读取 C:\ProgramData\Atheros\AtherosServiceConfig.ini 并响应服务控制代码 133。在该控制代码上读取 INI 文件并执行注册表操作:创建键、打开键、删除键、设置值。用户控制输入,服务提供权限,结果是特权注册表修改。
打印监视器:桥梁与最后一条链
我们想要的直接链(Atheros 写入 PowerT,重启 Wacom,获得 SYSTEM shell)并不完全有效。Admin Service 的解析器逐个字符读取,因此生成的字节并不是 Wacom 所期望的格式。真正的攻击链很少能像你设想的那样干净。有效的路径是:我们用 Atheros 在 HKLM\SYSTEM\CurrentControlSet\Control\Print\Monitors\PocPortMon 下创建一个打印监视器条目,指向 C:\ProgramData\Atheros\PocPortMon.dll。Spooler 以 SYSTEM 身份运行;启动时会枚举已注册的打印监视器并加载该 DLL。标准用户可以在 ProgramData 中写入文件;Atheros 为我们写入特权注册表键;重启后 Spooler 以 SYSTEM 身份加载我们的 DLL。现在我们的 DLL 直接调用 RegSetValueEx 写入正确的 PowerT 字节,然后重启 Wacom 服务,从而生成交互式 SYSTEM shell。
- PnP 通过模拟的 USB 身份安装厂商软件(Wacom + Atheros)。
- Atheros 为我们提供特权注册表写入。
- 打印监视器为我们提供 SYSTEM 执行(Spooler 加载我们的 DLL)。
- Wacom 为我们提供 Shell。
POC 4 // 作为非特权用户的完整攻击链:通过 Cynthion 模拟 Wacom + Atheros,植入 PocPortMon.dll,Atheros 写入 HKLM,重启,Spooler 以 SYSTEM 格式加载 DLL,写入 PowerT,重启 Wacom,获得交互式 SYSTEM shell。
我们一开始并不是管理员。我们没有使用真正的厂商硬件。我们没有安装自己的恶意服务。我们通过 PnP 路径实现了这一切。对于物理红队行动来说,这是一种本地特权提升,有着充足的操作空间。你并不总是需要携带内核漏洞。
1万+

被折叠的 条评论
为什么被折叠?



