【即插即攻】将 USB 自动安装变成 Windows 11 的完整系统接管
原创
骨哥说事
骨哥说事
骨哥说事
2026年8月12日 09:24
上海
在小说阅读器读本章
去阅读
| *声明:*文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由用户承担全部法律及连带责任,文章作者不承担任何法律及连带责任。 |
防走失:https://gugesay.com/
不想错过任何消息?设置星标↓ ↓ ↓
摘要
每当将USB设备插入Windows计算机时,操作系统可能会从Microsoft(微软)静默下载一个软件包,并以 NT AUTHORITY\\SYSTEM 权限执行供应商代码。这可能发生在无需管理员权限、无需用户登录的情况下,在某些环境中甚至可以通过RDP(远程桌面协议)USB重定向远程实现。
这是DEF CON 34演讲的发布套件。我们公布所有内容,包括工具,以便您可以重现设备与网络连接组件并自行检查这些原语(primitives)。
作者简介
Alejandro Hernando 0xedh
red_team_operator(红队操作员) · vulnerability_researcher(漏洞研究员)
Alejandro Hernando 是一个拥有超过十年进攻性网络安全实战经验的红队操作员和安全研究员。在他的整个职业生涯中,他评估、利用并帮助修复了商业和专有系统中的安全漏洞,开发了PoC(概念验证)漏洞利用程序、进攻和防御工具,并进行了深入的的安全研究。他的方法结合了应用研究和真实世界的操作经验,其驱动力来自持续学习以及磨炼攻防策略。
攻击向量
每当将USB设备插入Windows计算机时,操作系统可能会从Microsoft静默下载一个软件包,并以 NT AUTHORITY\\SYSTEM 权限执行供应商代码。这可能发生在无需管理员权限和无需用户登录的情况下。在适当的条件下,它也可以远程工作,而根本无需在机器上插入任何设备。下面的攻击向量描述了每种达到该安装流程的路径及其最终交付的供应商代码原语。
[00] 即插即攻:物理零点击利用链(Sierra + Sony)
环境设置:左边是一台完全更新的Windows 11计算机,没有用户登录,没有预装任何东西。右边是一台带有FaceDancer(一种USB设备仿真硬件)的Linux机器,用于模拟USB设备。整个过程无需任何点击,即可从无权限提升到SYSTEM。实际运行大约需要五分钟。最后我们放置一个标记文件并弹出一个SYSTEM权限的命令行窗口,以证明这是真实的。
POC 0:零点击物理攻击链,从无用户登录的Windows 11到获取SYSTEM权限的命令行窗口
这是安装路径允许的一个例子。我们将来自不同供应商的低严重性漏洞串联起来(有些供应商甚至不认为它们是漏洞),让它们共同产生更大的影响。物理攻击链的运行过程如下:
- 使用FaceDancer模拟一个特定的 Sierra 设备,然后轮询由该易受攻击组件自身创建的一个无限制权限的命名管道(named pipe)。
- 一旦管道存在,就利用它来更改机器的默认DNS。我们提供一个DNS服务器,将除了我们目标域之外的所有请求都重定向到Google的DNS。
- 模拟一个 Sony 设备。一旦其服务安装完成,它会从Sony服务器通过HTTP下载组件。我们控制了DNS,所以我们就是那些Sony服务器。
- 提供特定的文件来进行利用:实现一个任意路径写入(arbitrary write)作为SYSTEM。我们将一个DLL写入到
System32目录。 - 再次模拟Sierra设备,让我们植入的DLL被加载。这就在任何用户登录之前,实现了以
NT AUTHORITY\\SYSTEM权限执行任意代码。
物理攻击链,步骤1到7:Sierra设置DNS,Sony将DLL写入System32,Sierra重新加载它,最终获得SYSTEM权限。
Sierra Wireless: SwiService.exe
Sierra Wireless服务以SYSTEM权限运行,并暴露了一个具有 Everyone(所有人)读写权限的ACL(访问控制列表)的命名管道。任何本地用户或域用户都可以连接到该管道并调用 SetDNS 函数,无论是在本地还是甚至通过SMB(服务器消息块)。我们将这个DNS指向攻击者地址,并用我们自己的服务器替换Sony相关的DNS查询。该可执行文件对 netsh 的命令路径是硬编码的,接口名称来自系统查询且不可注入。但这并不重要:我们想要的效果——将DNS指向任何IP——正是此次攻击所需要的。
Sony FeliCa: felica\_coinst.dll
根本原因是一个带有协同安装(co-installer)DLL的签名目录文件,该DLL以SYSTEM权限运行。在即插即用(Plug and Play)过程中,它通过明文HTTP获取配置文件,并完全信任收到的所有内容。它的协调模块通过HTTP拉取三个文本文件(一个安装列表,一个URL列表和一个应用信息文件),并决定要安装什么。
当它下载这些文件时,它会提取URL中最后一个正斜杠之后的所有内容作为存储在磁盘上的文件名。没有对点号或反斜杠进行过滤:解析器只扫描 /,因此URL可以先全部使用正斜杠直到最后一个,然后为了路径遍历(path traversal)在最后一部分切换为反斜杠。提取出来的字符串会被连接到 TEMP(临时)目录路径后,并用作写入目标。这是一个任意文件写入(arbitrary file write),以SYSTEM权限,内容完全由攻击者控制,我们将其直接写入 System32 目录。我们控制了Sony的服务器,所以我们利用Sierra的DNS漏洞来伪装成Sony服务器。
两个低严重性的供应商代码问题,来自两个不同的供应商,串联在一起导致以SYSTEM权限执行任意代码。
[01] 无插即攻:RDP USB重定向,无需硬件
上述攻击都需要一个东西:USB设备,用FaceDancer模拟。显而易见的反对意见是,你需要物理接触,你必须插入某个设备。如果我们不需要呢?如果我们能够通过网络,从一个普通的RDP(远程桌面协议)会话,达到相同的设备即插即用(PnP)安装路径,而完全无需在机器上插入任何东西呢?目标:将一个具有RDP访问权限的标准用户,没有管理员权限,远程提升为SYSTEM权限。
关键在于一个名为 RDP USB重定向 的功能。它的合法目的很简单:你将USB设备插入你的笔记本电脑,它会被转发到你的远程会话中。但问题在于:服务器根据客户端发送的USB描述符(descriptors)来构建PnP设备节点。客户端描述硬件,服务器只是相信它。另一端并不需要有真实的设备。
策略网关:umrdp.dll / termsrv.dll
当我们的“设备”到达时,服务器会打开终端服务策略注册表项,检查 fDisableUSBRedir 的值,然后才会到达 ADD_DEVICE 调用。正是这一行代码向PnP管理器宣告了我们的幽灵(phantom)设备,也就是Windows承诺以SYSTEM权限安装驱动程序的时刻。它被一个组策略(Group Policy)设置所限制:fDisablePNPRedir。我们逆向分析了服务器端。termsrv.dll 打包了会话配置字中的一个比特(bit 11),这就是 fDisablePNPRedir 策略,umrdp.dll 在宣布我们的设备之前会检查这个比特位。默认情况下它是禁用的,只有当值恰好为0时才允许设备通过。没有来自我们的输入;这是纯粹的服务器端状态。因此,进攻性的问题是:哪里已经打开了这个门? 那些有意启用了USB重定向的环境,例如托管的VDI(虚拟桌面基础设施)部署。
Intel RealSense PoC
我们伪造而不是使用真实设备。我们在一个名为 aardwolf 的库之上,编写了一个纯Python的RDP客户端,完全不需要任何硬件。我们以普通用户身份进行身份验证,打开URBDRC通道,并为我们想要的任意VID(供应商ID)或PID(产品ID)发送 ADD_DEVICE 消息。当服务器请求描述符时,我们动态合成它们。服务器的USB集线器驱动程序枚举我们的幽灵设备,而Windows PnP则完全执行了物理演示中的操作:它匹配硬件ID并安装驱动程序,以SYSTEM权限。
对于这个演示,我们选择了一个不同的供应商,一个Intel RealSense摄像头,以表明这不是一次性现象。它本身就是一个很好的本地权限提升(Local Privilege Escalation, LPE)。该驱动程序由Microsoft签名并从Windows Update安装,在安装期间,其协同安装程序将一个可执行文件放到一个用户可写的目录中,并以SYSTEM权限运行它。该可执行文件在检查 System32 之前,会先在其自身文件夹中寻找一个DLL,而这个文件夹可以被普通用户写入。一个SYSTEM进程,在我们控制下的目录中搜索DLL。这是典型的DLL劫持,只不过现在我们可以在远程触发它。作为一个标准用户,我们将恶意的 CRYPTBASE.dll 放入 C:\\Intel\\RSDCM 目录,在没有插入任何硬件的情况下触发漏洞利用,最终写入只有SYSTEM才能写入的 C:\\Windows 目录。
POC 1:通过标准用户的RDP会话伪造Intel RealSense设备,在没有插入硬件的情况下获取SYSTEM权限
[02] PnP内部机制与PNP模拟工具
进一步深入。我们真正在滥用的正是安装路径本身。Windows PnP会很乐意从Windows Update为您获取并加载数百个有漏洞的已签名软件包,完全可信,无需提升权限。PnP成为了加载器。 传统的先决条件——即您需要管理员权限来放置某些文件并启动它——就这么消失了。我们通过两种方式到达了相同的路径:物理方式使用FaceDancer,以及远程方式通过RDP。在研究过程中,我们使用了第三种路径来打开黑匣子:PNP模拟工具,这是我们开发的一个工具。
PNP模拟不是最终的利用路径。它是我们以可控方式重现即插即用安装流程的方法,而不需要在每次测试中都依赖真实硬件。它做的不仅仅是打印VID和PID。它使用Setup DI(设备安装)API创建一个具有USB硬件ID的 \_ROOT\_枚举设备,使用 DIF_REGISTER_DEVICE 注册设备,使用 DIInstallDevice 在本地的驱动程序存储区(Driver Store)中寻找匹配项,使用 IUpdateSearcher 查询Windows Update COM(组件对象模型),并使用 CM_Register_Notification 注册即插即用通知。
有两种模式很重要。默认是 仅查询模式:它创建临时的设备节点,进行查询,观察事件,然后清理。它不会下载软件包或留下持久性更改。对侦察(discovery)很有用。使用 安装标志 时,它会调用 CM_Setup_DevNode 并设置 CM_SETUP_DEVNODE_READY,这会将设备节点强制推入真正的安装路径。这为我们提供了一种将侦察与实际安装进行比较的受控方法。
研究中的一个陷阱:很容易说“Windows Update返回了一个软件包,所以Windows会安装它。” 这不正确。Windows Update COM API会返回大量元数据:自动(automatic)、手动(manual)、旧版(old)和仅目录(catalog-only)软件包。对于侦察,IUpdateSearcher 非常有用。对于漏洞利用,重要的是 设备安装服务 使用的 服务器端解析,这是一个过滤严格得多的路径。许多候选驱动通过Windows Update COM查询时会匹配到。但真正通过PnP路径实现自动下载的则少得多。
真实的流程,分为四个阶段
阶段1,身份识别。 使用FaceDancer,我们呈现一个模拟的USB设备。Windows读取设备描述符,获取VID、PID和设备类别,然后读取配置描述符和接口描述符。根据这些信息,它构建硬件ID,这些字符串之后将与INF(设备信息)文件进行比较。如果我们控制描述符,我们就控制了Windows试图解析的硬件ID。
阶段1:FaceDancer模拟USB设备,设备/配置/接口描述符,Windows构建硬件ID USB\\VID_XXXX&PID_YYYY,然后进行INF匹配
阶段2,身份到设备节点。 在真实的USB路径中,集线器看到模拟的设备,读取描述符,创建一个物理设备对象(Physical Device Object, PDO),并使总线关系无效,以通知PnP管理器它有了一个新的子设备。PnP管理器创建一个设备节点。在PNP模拟中,我们从用户模式再现了我们关心的部分:创建一个设备信息集(SetupDiCreateDeviceInfo),设置硬件ID(SetupDiSetDeviceRegistryProperty),并注册设备(SetupDiCallClassInstaller + DIF_REGISTER_DEVICE)。
阶段3,CM\_Setup\_DevNode。 我们不仅想依赖文档,所以我们用WinDbg观察它。该调用进入 LocalCMSetupDevNode,最终到达带有IOCTL 0x47084F 的 DeviceIoControl,进入内核中的配置管理器(Configuration Manager)和PnP部分。用户态调用并不完成所有工作:它将一个操作推入PnP,该操作被排队,真正的工作会异步继续。这个跟踪结果证实了安装标志进入了激活真实安装的路径。
阶段4,PnP工作线程和设备安装服务。 PnP工作线程查询设备ID,解决兼容性问题,添加并启动设备节点,并需要一个兼容的软件包。这就是设备安装服务出现的地方:DSMSVC,在 svchost 内部,以SYSTEM权限运行。它在本地的驱动程序存储区中查找;如果没有匹配项,它可以使用服务器端解析;如果软件包可以自动安装,Windows会从Windows Update下载CAB(压缩包)文件,将其暂存在驱动程序存储区中,并启动安装序列,此时 DRVINST 出现。如果软件包带来了协同安装程序、支持的可执行文件、服务或额外逻辑,该软件将进入用户从未通过UAC(用户账户控制)提示批准的特权路径。
POC 2:在模拟的Wacom设备上对PNP模拟工具进行仅查询模式与安装模式的比较,右侧是SetupAPI日志,以及WinDbg在CM\_Setup\_DevNode和IOCTL 0x47084F处的断点
[03] 供应商代码组合利用:Wacom + Atheros LPE
Windows已经接受了一个硬件身份标识,根据已签名或已知的软件包进行解析,并进入了一个特权安装路径。但 密码学信任 和 逻辑安全 之间存在区别。一个已签名的软件包并不意味着其中的每个服务、协同安装程序、调试标志或注册表值都已经从进攻性角度进行了审计。而且没有UAC(用户账户控制)提示并不意味着没有特权操作。这也是与供应商沟通常常变得复杂的原因。通常没有溢出(overflow),没有释放后使用(use-after-free),没有崩溃(crash)。有的是接受由用户或其他组件控制的输入的特权逻辑。分开看,每个部分都可以辩解为功能。合在一起,结果就产生了安全影响。
Wacom:SYSTEM权限命令行窗口
在Wacom服务二进制文件(作为软件包的一部分签名并分发)中,我们发现了一个与硬编码值的比较。在注册表字节中,它显示为 7F 4C 6B 34。当服务在正确的注册表键下看到这个值时,它会遵循一条最终导致以SYSTEM权限运行CMD的路径。我们不会声称这是一个后门。它可能是一个调试存根(stub)、支持功能,或者是一个本不应该暴露的内部路径。从进攻性角度来看,这是一个非常干净的缺陷。键值名称为 PowerT,以 REG_BINARY 类型写入 HKLM\\SYSTEM\\CurrentControlSet\\... 下,并且在键 AutoAdminLogon 周围有一个判断条件(其值必须为0或不存在)。当检查通过时,以LocalSystem(本地系统)权限运行的 WTabletServiceISD 会在 默认 桌面上调用 CreateProcessAsUserW,并启动CMD。这不是一个隐藏的会话0进程。它是在用户桌面上的一个交互式的SYSTEM权限命令行窗口。然而,它本身需要一样标准用户所没有的东西:对 HKLM(HKEY\_LOCAL\_MACHINE)的写入权限。
POC 3:Wacom独立演示,在WTabletServiceISD键下写入PowerT值并重启服务以获取一个交互式的SYSTEM权限命令行窗口
Atheros:特权注册表写入
那么,我们是否还有另一个同样由PnP安装的组件,可以为我们写入那个特权部分呢?Atheros。在审查它之后,它匹配了一个七年前的CVE。我们认为Microsoft应该已经撤销了证书,软件包将不再安装。剧透:它仍然会安装。该软件包安装了 AtherosSVC(管理员服务),以LocalSystem权限运行。它读取 C:\\ProgramData\\Atheros\\AtherosServiceConfig.ini 并响应服务控制代码 133。在该控制代码下,它读取INI文件并执行注册表操作:创建键、打开键、删除键、设置键值。由用户控制输入,服务提供特权,结果就是一次特权注册表修改。
打印监视器:桥梁,以及最终的利用链
我们最初想要的直接利用链(Atheros以REG\_BINARY类型写入 PowerT,重启Wacom服务,得到SYSTEM权限命令行窗口)并不完全奏效。因为Admin Service(管理员服务)的解析器是逐个字符读取的,所以它生成的字节与Wacom期望的字节不同。真正的利用链很少像你希望的那样干净。可行的路径是:我们使用Atheros在 HKLM\\SYSTEM\\CurrentControlSet\\Control\\Print\\Monitors\\PocPortMon 下创建一个打印监视器(Print Monitor)条目,指向 C:\\ProgramData\\Atheros\\PocPortMon.dll。打印后台处理程序(Spooler)以SYSTEM权限运行;当 spoolsv 启动时,它会枚举已注册的打印监视器并加载该DLL。普通用户可以在ProgramData目录下放置 PocPortMon.dll;Atheros为我们写入特权注册表键;重启后,Spooler以SYSTEM权限加载我们的DLL。现在我们的DLL直接调用 RegSetValueEx 来用正确的字节写入 PowerT,然后重启Wacom服务,从而产生交互式的SYSTEM权限命令行窗口。
- PnP从模拟的USB身份标识安装供应商软件(Wacom + Atheros)。
- Atheros为我们提供了一次特权注册表写入。
- 打印监视器为我们提供了SYSTEM权限的代码执行(Spooler加载我们的DLL)。
- Wacom为我们提供了命令行窗口。
POC 4 // 作为非特权用户的完整利用链:通过Cynthion(FaceDancer使用的Python库)模拟Wacom + Atheros设备,放置PocPortMon.dll,Atheros写入HKLM,重启系统,Spooler以SYSTEM权限加载DLL,写入PowerT,重启Wacom,获得交互式SYSTEM权限命令行窗口。
我们并非以管理员身份开始。我们没有使用真实的供应商硬件。我们没有安装自己的易受攻击的服务。我们利用了通过PnP途径到达机器的软件中的功能性和逻辑性缺陷。对于物理红队行动来说,这是一个有足够操作空间的本地权限提升(LPE)。你并不总是需要携带一个内核漏洞。
发布文件
代码和PoC已公开。点击任意文件下载,重现PnP部分或自行检查原语。
| 文件 | 描述 | 对应攻击向量 |
|---|---|---|
usb_trigger.py |
FaceDancer脚本,用于模拟演示中使用的USB身份标识(VID/PID, 描述符)。 | [00] 物理 |
rdp_usb_pnp.py |
纯Python RDP客户端,通过URBDRC通道伪造USB设备(无需硬件),以标准用户身份远程触发PnP驱动程序安装。 | [01] RDP |
pnp_simulate.c |
PNP模拟工具的源代码:设备节点创建、Setup DI、Windows Update COM、仅查询模式与安装模式标志。 | [02] 内部机制 |
build.bat |
pnp_simulate.c 的MSVC构建脚本:通过vswhere加载VS工具集并编译工具。 |
[02] 内部机制 |
wacom_powert.reg |
Wacom PoC:PowerT注册表值及将服务转变为交互式SYSTEM权限命令行窗口的步骤。 | [03] 供应商代码 |
官方媒体资料
| 项目 | 位置 | 状态 |
|---|---|---|
| 演讲录像 | DEF CON 媒体 | 待定 |
| 幻灯片 PDF | DEF CON 媒体 | 待定 |
| 演示视频 | DEF CON 媒体 | 待定 |
原文:https://plugandpwn.com/
- END -
感谢阅读,如果觉得还不错的话,动动手指给个三连吧~
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。









评论