Plug and Trust: How Windows Decides What to Do When You Plug In a USB Device
In the 250 ms between physical insertion and class-driver attach, Windows executes eleven kernel-mode operations and trusts ~256 bytes of self-described descriptors.
Permalink1. The Thirty-Second Trust Decision
A user plugs a USB-C thumb drive into a Windows 11 25H2 corporate laptop at 10:42:17 in the morning. Roughly a quarter-second later, the operating system has executed eleven kernel-mode operations to decide what kind of device it is and which driver to load. The "quarter-second" is editorial framing, not a spec-mandated deadline. The only piece USB-IF actually fixes is the 100 ms attach-debounce window T_ATTDB defined in the USB 2.0 specification §7.1.7.3 (Connect and Disconnect Signaling) [1]; the rest of the budget is implementation-dependent. A typical USB 2.0 thumb drive on a 2024-era xHCI controller, with the function driver already in the local store, lands in the 200-300 ms range. A first-time Windows Update fetch, a slow descriptor read, or a multi-configuration device can stretch it to a second or more. None of those eleven operations consulted the user. None of them verified a cryptographic signature from the peripheral. The entire decision rests on roughly 256 bytes of self-described metadata that the device handed the host on insertion.
Here is the sequence, in the order Windows executes it:
- Port-status-change interrupt fires on the xHCI host controller.
- The host controller's driver issues a port reset.
- Downstream-port speed detection runs: Low, Full, High, Super, or Super+ Speed.
- The hub addresses the device at the default address (zero) and asks for the first eight bytes of the
USB_DEVICE_DESCRIPTOR. SET_ADDRESSassigns a non-default bus address.- The hub fetches the full eighteen-byte device descriptor.
- The hub fetches the configuration descriptor, including all interface and endpoint sub-descriptors.
- If the descriptor indicates a composite device, the generic parent splits it into per-interface child devices.
- The Plug-and-Play manager synthesizes hardware IDs and compatible IDs from the descriptor fields.
- The driver-store INF database is searched with a rank-scored matching algorithm; the chosen driver is verified against the Kernel-Mode Code Signing policy.
- The class driver attaches to the new device node and begins serving I/O.
Microsoft's own architecture documentation confirms the pipeline: the xHCI host controller driver, the host-controller extension, and the hub driver -- usbhub3.sys, the binary that enumerates devices and creates physical device objects -- are all KMDF-based [2]. The rank-scored INF match comes straight from the Plug-and-Play manager's documented behavior [3]. The signature check is governed by the same Kernel-Mode Code Signing policy that has gated every kernel driver since 64-bit Windows Vista shipped in 2007 [4].
Eleven kernel-mode operations. Zero human decisions. Roughly 256 bytes of self-described metadata. That is the size of the trust gap between physical insertion and the moment a class driver begins reading and writing data inside the Windows kernel.
The load-bearing primitive in that pipeline is the USB descriptor: a small block of bytes the peripheral emits when asked, naming what kind of device it claims to be, who claims to have made it, and what features it claims to support. Windows must trust those bytes to choose a driver. There is no out-of-band channel to verify them. There is no signature on the descriptor itself.
This article is a walk through what Windows does verify, what it cannot verify, and where the gap lives. The trust posture is older than USB itself, and the failure modes are older than Windows 2000. We will start with the inheritance.
2. The Pre-USB Removable-Media Trust Model
- A user in Lahore inserts a 5.25-inch floppy into an IBM PC clone. Whatever 512 bytes sit at sector zero of that diskette will execute as part of the operating-system boot path before any code that came with the machine runs. The trust model Windows still uses for USB peripherals in 2026 was carved into silicon that year.
The IBM PC's boot ROM, by design, copied sector zero of whatever bootable medium was present into memory and jumped to it. That contract -- inserted media is trusted media -- shipped in 1981 and was demonstrated as catastrophic within five years. The Brain virus appeared in 1986 [5]; Stoned in 1987 [6]; Michelangelo was first discovered on 3 February 1991 in Australia and produced its global panic on March 6, 1992 [7]. Each one used the boot-sector primitive that Wikipedia's standard reference on boot sectors documents [8]. The Brain virus shipped with a literal copyright notice in the boot sector, naming the Alvi brothers and giving an address in Lahore: a piece of self-documenting malware authored when virus authors did not yet expect to be prosecuted. The address-and-phone-number pattern is a recurring forensic curiosity from the 1986-1990 era.
A USB descriptor is a small, structured block of bytes that a USB peripheral returns when the host asks for it. There are five standard descriptor types in the USB 1.0 specification (device, configuration, string, interface, endpoint) and several class-specific descriptors (HID report descriptors, audio control units, mass-storage CSW formats) layered on top. The device descriptor names a vendor ID, a product ID, a device class, and the maximum packet size for the default control pipe. The string descriptors carry the human-readable manufacturer, product, and serial-number text that Windows displays in Device Manager and that Defender for Endpoint per-serial allow-lists key on. The host has no out-of-band channel to verify any of these fields; the peripheral's self-declaration is its identity for the purpose of driver selection.
Microsoft inherited the contract from DOS and refined it. AutoRun, which the Wikipedia reference documents verbatim, "was introduced in Windows 95 to ease application installation for non-technical users and reduce the cost of software support calls ... a feature of Windows Explorer (actually of the shell32 dll) ... enables media and devices to launch programs by use of command listed in a file called autorun.inf, stored in the root directory of the medium" [9]. Windows 95 RTMed on August 24, 1995. The original design intent was CD-ROM application installation -- read-only optical media, written once at the factory, shipped in a sealed jewel case. The trust assumption matched the physical reality.
Four months after Windows 95 shipped, the USB Implementers Forum was formed. Wikipedia preserves the date and the founder list verbatim: "The USB-IF was initiated on December 5, 1995, by the group of companies that was developing USB ... Compaq, Digital Equipment Corporation, IBM, Intel, Microsoft, NEC and Nortel" [10]. Microsoft was a co-author of the contract that would govern peripheral trust on every Windows machine for the next thirty years.
A Vendor ID is a 16-bit number that the USB Implementers Forum sells to a device manufacturer for $6,000 per year [10]. A Product ID is a 16-bit number the manufacturer assigns to a specific product within their VID space. The pair forms the most-specific hardware ID Windows uses to select a USB driver, in the form USB\VID_xxxx&PID_xxxx. The USB-IF Vendor-ID fee is the only economic gate between an arbitrary firmware author and a "trusted" identity in Windows's driver-store search; it is not a cryptographic gate of any kind.
The first complete USB specification followed quickly. Wikipedia's USB article puts it verbatim: "Designed January 1996 ... Produced Since May 1996 ... Designer: Compaq, DEC, IBM, Intel, Microsoft, NEC, Nortel" [11]. USB 1.0 defined the five standard descriptors, the bus enumeration handshake, and -- the load-bearing architectural choice -- the device-class architecture in which the peripheral declares its own class, subclass, and protocol. A USB keyboard reports bInterfaceClass=0x03 (HID) because it says it is a keyboard. The host has no other source of that fact.
Three years later, the protocol's storage cousin arrived. The USB Mass Storage Class Bulk-Only Transport, Revision 1.0, was published in September 1999 [12]. That specification is the protocol on which Windows 2000's usbstor.sys and every modern thumb-drive driver are built. It defines a stripped-down SCSI command set tunneled over USB bulk endpoints; it does not define any peripheral-authentication mechanism.
The inheritance is structural. AutoRun shipped in 1995, designed for write-once optical media in a sealed jewel case. Windows 2000 extended AutoRun to every mounted volume -- including the new USB thumb-drive class. A 1995 trust model for trusted physical media now protected read-write USB sticks anyone could carry between machines. Forty years later, that line in the lineage has not been redrawn.
Diagram source
timeline
title Pre-USB removable-media trust, 1981 to 2000
1981 : IBM PC ships : Boot ROM jumps to sector 0 of inserted media
1986 : Brain virus : Lahore : First in-the-wild boot-sector virus
1987 : Stoned virus : Boot-sector class established
1991 : Michelangelo discovered : 3 February 1991, Australia
1992 : Michelangelo media panic : Trigger date 6 March 1992
1995 : Windows 95 RTM : AutoRun introduced for CD-ROM installers
1995 : USB-IF founded December 5 : Seven-company consortium
1996 : USB 1.0 designed January : Device-class architecture: peripheral declares its own class
1999 : USB Mass Storage 1.0 : Bulk-Only Transport specification
2000 : Windows 2000 usbstor.sys : AutoRun extends to USB volumes Timeline sources, in row order: [8] for the IBM PC boot-sector contract; [5], [6], and [7] for the named-virus lineage and the 1992-not-1991 Michelangelo panic date; [9] for the Windows 95 / AutoRun introduction; [10] for the USB-IF founding date and seven-company consortium; [11] for the USB 1.0 January 1996 design date and the device-class architecture; [12] for the USB Mass Storage Class Bulk-Only Transport 1.0 specification.
If the trust model is forty years old, the failure modes must be older than USB. They are. The first fifteen years of USB on Windows were a transport in search of a security model, and the bill came due in two famous worms.
3. The Pre-Hardening Era, 1996 to 2010
For its first fifteen years on Windows, USB was a transport in search of a security model. Drivers were unsigned on 32-bit. AutoRun was on. Descriptors were trusted. The bill was paid in two worms.
The Generation-1 stack was a USB 1.1 design retrofitted onto Windows 95 OSR2.1 in 1997 and refined for Windows 2000. The host-controller drivers (Usbuhci.sys, Usbohci.sys, and later Usbehci.sys for USB 2.0 high speed) sat below a single port driver, Usbport.sys; the hub driver was usbhub.sys. Microsoft's USB-3.0 architecture page documents the older 2.0 stack as the predecessor of the modern KMDF chain [2]. On 32-bit Windows, none of these binaries needed a Microsoft-trusted signature to load.
Windows 2000 added usbstor.sys, the function driver implementing the USB Mass Storage Class Bulk-Only protocol [12]. Suddenly a thumb drive was a first-class read-write filesystem the user could carry between machines, and AutoRun -- a 1995 contract for CD-ROM application installers -- applied to it. The original autorun.inf was a sensible primitive. Insert a sealed jewel case, run the vendor's setup wizard, get a new application. Extending the contract to user-writable USB sticks broke the cardinal assumption: that the media's content was set by a trustworthy party at the factory and could not be modified in the field.
KMCS is the Windows policy that requires every kernel-mode binary -- every .sys file Windows loads into ring zero -- to carry a digital signature chaining to a Microsoft-trusted root certificate. KMCS has been mandatory on 64-bit Windows since Vista shipped in 2007. Microsoft Learn documents the signing-by-version matrix, the SHA-256 algorithm requirement, and the post-2016 narrowing of the cross-signed-CA exception. KMCS prevents an attacker from loading an arbitrary .sys file into the kernel. It does not, by itself, prevent an attacker from feeding malicious data to an already-signed .sys file.
The Conficker worm, first detected in November 2008, industrialized the AutoRun-on-USB era. Wikipedia summarizes its origin verbatim: "first detected in November 2008 ... uses flaws in Windows OS software (MS08-067 / CVE-2008-4250) and dictionary attacks on administrator passwords to propagate ... The first variant of Conficker, discovered in early November 2008, propagated through the Internet by exploiting a vulnerability in a network service (MS08-067)" [13]. Conficker rode two completely separate vectors: a Server Service vulnerability (a path-canonicalization overflow in srvsvc.dll reachable over SMB on TCP 445 and via NetBIOS over TCP/IP on TCP 139) over the network [14], and autorun.inf-driven AutoPlay execution on inserted USB drives. The two propagation paths are independent and worth distinguishing.
Stuxnet followed in 2010. Wikipedia's article puts the timing and the vector verbatim: "Stuxnet is a malicious computer worm first uncovered on 17 June 2010 ... It is typically introduced to the target environment via an infected USB flash drive, thus crossing any air gap" [15]. The technical primitive that let Stuxnet cross air gaps onto Iranian centrifuge-control PCs was CVE-2010-2568, a flaw in the Windows Shell's processing of .LNK shortcut icons. NIST's National Vulnerability Database entry preserves the verbatim characterization: "Windows Shell in Microsoft Windows XP SP3, Server 2003 SP2, Vista SP1 and SP2, Server 2008 SP2 and R2, and Windows 7 allows local users or remote attackers to execute arbitrary code via a crafted (1) .LNK or (2) .PIF shortcut file, which is not properly handled during icon display in Windows Explorer, as demonstrated in the wild in July 2010, and originally reported for malware that leverages CVE-2010-2772 in Siemens WinCC SCADA systems" [16]. Microsoft Security Bulletin MS10-046 shipped the patch [17].
"Windows Shell in Microsoft Windows XP SP3, Server 2003 SP2, Vista SP1 and SP2, Server 2008 SP2 and R2, and Windows 7 allows local users or remote attackers to execute arbitrary code via a crafted (1) .LNK or (2) .PIF shortcut file, which is not properly handled during icon display in Windows Explorer, as demonstrated in the wild in July 2010." -- NIST, National Vulnerability Database, CVE-2010-2568 [16]
Patch Tuesday, February 2011 closed the AutoRun pipeline outside Windows 7. Brian Krebs covered the rollout verbatim at the time: "Microsoft also issued an update that changes the default behavior in Windows when users insert a removable storage device, such as a USB or thumb drive. This update effectively disables 'autorun,' a feature of Windows that has been a major vector for malware over the years. Microsoft released this same update in February 2009, but it offered it as an optional patch. The only thing different about the update this time is that it is being offered automatically to users who patch through Windows Update or Automatic Update" [18]. The update originally shipped as an optional Windows-7-era fix; Microsoft made it automatic for XP, Vista, Server 2003, and Server 2008 in February 2011.
Six months later, the descriptor-parser surface itself was named for the first time. Andy Davis of NCC Group gave "USB -- Undermining Security Barriers" at Black Hat USA 2011. The verified NCC Group publication archive carries the talk and a one-line abstract [19]. Davis fuzzed USB descriptors against the Windows kernel parser and demonstrated that the parser itself -- not the application layer, not AutoRun -- was kernel-mode adversarial-input attack surface. The talk did not name a single bug class; it named the class of bugs: anything that parses adversarial bytes in ring zero in a memory-unsafe language.
Why did none of these fixes survive structurally? Each was a single-bug closure. Disabling AutoRun did nothing about HID injection. Patching the LNK parser did nothing about the descriptor-parser surface. Signing kernel binaries did not change what those binaries trusted at runtime. Each fix shrank one bug class by one. The premise -- that a USB peripheral's self-declaration is its identity -- was untouched.
The post-2010 hardening of USB on Windows would change the surfaces around the descriptor parser. None of it would change the descriptor parser's contract.
4. Generation by Generation: Ten Acts of Hardening
The post-2010 hardening of USB on Windows is a ten-act story: signing, lockdown, watershed, silicon, policy. Each act addressed one premise, and exactly one premise, of the trust failure that came before it. None of them changed the foundational contract.
Generation 2 -- Vista x64 Kernel-Mode Code Signing (2007). Every USB function and class driver had to chain to a Microsoft-trusted root and use SHA-2 once 64-bit Vista landed. Microsoft Learn carries the signing-by-version matrix and the cross-signed-CA carve-out verbatim, including the post-2015 narrowing in which "Cross-signed drivers are still permitted if ... The PC was upgraded from an earlier release of Windows to Windows 10, version 1607 ... Drivers was signed with an end-entity certificate issued prior to July 29th 2015 that chains to a supported cross-signed CA" [4]. Companion documentation describes the broader driver-signing pipeline [20]. For the full reinvention of code-identity verification on Windows, the sibling article on Windows app identity is the canonical reference [21].
Generation 3 -- AutoRun and LNK lockdown (2009-2011). Already covered in Section 3. KB971029 and MS10-046, taken together, closed the autorun.inf-driven AutoPlay vector and the LNK-icon parsing flaw used by Stuxnet [18] [16].
Generation 4 -- The descriptor-parser surface and the USB 3.0 stack (2011-2012). Andy Davis named the surface at Black Hat 2011 [19]. Windows 8 in 2012 shipped a new USB 3.0 stack written from scratch on Microsoft's Kernel-Mode Driver Framework. The architectural reference confirms the rebuild verbatim: "Microsoft created the USB 3.0 drivers by using Kernel Mode Driver Framework (KMDF) interfaces ... Usbhub3.sys ... Manages USB hubs and their ports ... Enumerates devices and other hubs ... Creates physical device objects (PDOs)" [2]. The new stack changed the codebase the descriptor parser ran in. It did not change the contract the descriptor parser had to honor.
The Human Interface Device class is a USB device-class specification originally designed for keyboards, mice, joysticks, and similar input devices. A USB device declares itself HID by setting bInterfaceClass=0x03 in its interface descriptor. Once Windows accepts that declaration, the device is allowed to inject keyboard and pointer events into the active session as if a human were operating a physical keyboard. The HID class has no provision for authenticating that the device is, in fact, a keyboard rather than a reprogrammed thumb drive emulating one; the class definition is itself the attack surface.
Generation 5 -- BadUSB watershed (Black Hat USA 2014). Karsten Nohl, Sascha Krißler, and Jakob Lell of SR Labs presented BadUSB -- On Accessories That Turn Evil [22]. The SR Labs slide deck's title page is preserved verbatim, with all three authors named, on a mirrored PDF [23]; Wikipedia's BadUSB article also preserves the three-author attribution and the underlying primitive: "USB flash drives can contain a programmable Intel 8051 microcontroller" [24]. Wired's contemporaneous press coverage credited only Nohl and Lell; Krißler's name was dropped in the popular write-up. The SR Labs slide deck and the Wikipedia article both preserve the full three-author attribution. Press attributions of conference talks routinely shed authors; the slide-deck title page is the durable source. Two months after Black Hat, Adam Caudill and Brandon Wilson released the Psychson toolchain at DerbyCon 2014, demonstrating end-to-end reflash of the Phison PS2251-03 controller. The repository README confirms the lineage verbatim: "this is 8051 custom firmware written in C ... firmware patches have only been tested against PS2251-03 firmware version 1.03.53 ... DriveCom ... EmbedPayload ... Injector ... Huge thanks to the Hak5 team for their work on the excellent USB Rubber Ducky" [25]. Wired's October 2014 follow-up carries Caudill's verbatim release rationale from the DerbyCon stage: "The belief we have is that all of this should be public. It shouldn't be held back. So we're releasing everything we've got" [26]. The same article quotes Nohl's verbatim architectural verdict on the underlying protocol: "to prevent USB devices' firmware from being rewritten, their security architecture would need to be fundamentally redesigned ... it could take 10 years or more to iron out the USB standard's bugs and pull existing vulnerable devices out of circulation" [26].
"It could take 10 years or more to iron out the USB standard's bugs and pull existing vulnerable devices out of circulation." -- Karsten Nohl, SR Labs, quoted in Wired, October 2014 [26]
Generation 6 -- HID-as-weapon era (2010-present). The Hak5 USB Rubber Ducky -- introduced in 2010 by Hak5 founder Darren Kitchen, who pioneered the keystroke-injection technique [27] -- commercialized the HID-injection primitive four years before BadUSB was disclosed. The Mark II hardware is still sold today [28], and DuckyScript v1 (2011) and v3 (2022) are documented end-to-end on the Hak5 documentation portal [27]. The commercial HID-injection device predates the academic disclosure by four years. By the time BadUSB hit Black Hat in August 2014, Hak5 had already been selling a packaged keystroke-injection thumb drive at consumer prices for the better part of a decade. "BadUSB" academicized what penetration testers were already shipping in mailers. The O.MG Cable, released by Mischief Gadgets, embedded the implant inside a USB-A-to-Lightning charging cable form factor and put a WiFi beacon inside it. The product page states the design intent verbatim: "O.MG Cables are hand made USB cables with an advance WiFi implant inside. Designed to allow Red Teams to emulate sophisticated attack scenarios previously only capable with $20,000 cables" [29]. The FBI's March 2020 FLASH alert -- reported by BleepingComputer at the time -- confirmed organized cybercriminal actors mailing the same primitive: "Hackers from the FIN7 cybercriminal group have been targeting various businesses with malicious USB devices acting as a keyboard when plugged into a computer ... These USB drives are configured to emulate keystrokes that launch a PowerShell command to retrieve malware from server controlled by the attacker" [30]. The FBI repeated the warning with a follow-on FLASH alert in January 2022 that extended the targeting to transportation, insurance, and defense companies [24].
Generation 7 -- Thunderbolt DMA and Thunderclap (NDSS 2019), Thunderspy (2020). Theodore Markettos, Colin Rothwell, Brett Gutstein, Allison Pearce, Peter Neumann, Simon Moore, and Robert Watson of Cambridge, Rice, and SRI demonstrated peripheral DMA attacks against IOMMU-on platforms via shared-IOMMU-context attacks. Their NDSS 2019 paper concludes verbatim: "Windows only uses the IOMMU in limited cases and remains vulnerable" [31]. One year later, Björn Ruytenberg of Eindhoven University released Thunderspy, a family of seven vulnerabilities extending the attack surface to firmware-reflash of the Thunderbolt controller itself: "All the attacker needs is 5 minutes alone with the computer, a screwdriver, and some easily portable hardware" [32]. Wikipedia preserves the May 10, 2020 disclosure date [33].
Generation 8 -- Kernel DMA Protection (Windows 10 1803, April 2018). This is the first Windows USB-adjacent defense that targeted trust below the descriptor parser rather than the parser itself. Microsoft Learn names the primitive verbatim: "Windows uses the system Input/Output Memory Management Unit (IOMMU) to block external peripherals from starting and performing DMA, unless the drivers for these peripherals support memory isolation (such as DMA-remapping) ... By default, peripherals with DMA Remapping incompatible drivers are blocked from starting and performing DMA until an authorized user signs into the system or unlocks the screen" [34]. Per-driver opt-in is documented separately [35]. The same Microsoft Learn page is explicit about what KDP does not defend: "Kernel DMA Protection feature doesn't protect against DMA attacks via 1394/FireWire, PCMCIA, CardBus, or ExpressCard". A USB 2.0 thumb drive performs no DMA at all; KDP is silent on it.
Kernel DMA Protection is the Windows defense that uses the platform's IOMMU (Intel VT-d, AMD-Vi, or an ARM equivalent) to confine externally connected PCIe-class peripherals to device-private memory windows. With KDP armed, a Thunderbolt or USB4 peripheral cannot read arbitrary kernel memory by issuing DMA requests, even if its driver is malicious or buggy. KDP is opt-in at three levels: silicon (the platform must have an IOMMU), firmware (the UEFI must publish DMAR / IVRS tables), and driver (the driver must declare DmaRemappingCompatible=1 in its INF). KDP does not protect against attacks delivered through descriptor parsing, HID injection, or mass-storage exfiltration.
Generation 9 -- USB Type-C UCM stack (Windows 10 1607, 2016). The User-mode Connector Manager class extension family -- UcmCx.sys, UcmUcsiCx.sys, UcmTcpciCx.sys -- brought Power Delivery, Alternate Mode (DisplayPort, Thunderbolt, USB4), and bidirectional power-role negotiation into the Windows driver model. Microsoft Learn names the architecture verbatim: "UCM is designed by using the WDF class extension-client driver model" [36].
Generation 10 -- Defender, ASR, and Device Control unification (2018-2024). The Attack Surface Reduction rule set, documented in Microsoft's ASR-rule-to-GUID matrix [37], includes the rule Block untrusted and unsigned processes that run from USB with GUID b2b3f03d-6a65-4f7b-a9c7-1c7ef74a9ba4. Microsoft Defender for Endpoint Device Control followed, generally available in 2024, with per-VID/PID, per-serial-number, per-operation, and per-user policy primitives [38]. Together with the older Group Policy Device Installation Restrictions framework [39] and the system-defined Device Setup Class GUIDs [40], these form the deployable enterprise triangle around the BadUSB / HID-injection problem.
Diagram source
timeline
title Ten generations of Windows USB hardening
1996 : Gen 1 : Original USB stack ships ; unsigned 32-bit drivers
2007 : Gen 2 : KMCS on Vista x64 ; mandatory signed kernel binaries
2009-2011 : Gen 3 : AutoRun and LNK lockdown ; KB971029 and MS10-046
2011 : Gen 4 : Andy Davis names the descriptor parser surface
2012 : Gen 4 cont. : USB 3.0 KMDF stack ships in Windows 8
2014 : Gen 5 : BadUSB watershed ; SR Labs at Black Hat
2010-2024 : Gen 6 : HID-as-weapon era ; Rubber Ducky to O.MG Cable
2019-2020 : Gen 7 : Thunderclap and Thunderspy ; IOMMU is not enough
2018 : Gen 8 : Kernel DMA Protection ; Windows 10 1803
2016 : Gen 9 : USB Type-C UCM stack ; Windows 10 1607
2018-2024 : Gen 10 : ASR, Device Control, GPO triangle ; Defender for Endpoint Sources, in row order: [2] for the USB 2.0 stack and the USB 3.0 KMDF rewrite; [4] for the Vista x64 signing transition; [18] and [16] for the AutoRun-and-LNK lockdown; [19] for the Andy Davis Black Hat 2011 talk; [23] and [24] for the BadUSB three-author SR Labs disclosure; [28], [27], [29], and [30] for the HID-as-weapon lineage; [31] and [32] for the IOMMU attack family; [34] and [35] for Kernel DMA Protection; [36] for the Type-C UCM stack; [37], [38], [39], and [40] for the modern enterprise policy triangle.
Ten generations of hardening, each closing a single attack surface, each leaving the descriptor-trust contract intact. The single defense that should close it -- USB-IF Authentication 1.0, published January 2019 -- is the next section's reckoning.
5. The Modern USB Stack as a Multi-Stage Verifier
We have walked forty years of inheritance and ten generations of layered hardening. Now we are going to do the thing the rest of this article rests on: walk a single USB device, from the millisecond it makes electrical contact to the moment a class driver attaches to it, through the nine stages Windows 11 25H2 actually executes -- by named binary, by descriptor, by trust decision.
Those nine stages are a reorganisation of §1's eleven kernel-mode operations, not a different list. §1's three physical-detection operations -- port-status interrupt, port reset, speed detection -- fuse into Stage 1; §1's three default-address descriptor operations (initial 8-byte fetch, SET_ADDRESS, full 18-byte fetch) fuse into Stage 2; §1's combined INF-search-and-KMCS operation splits into Stages 6 and 7; and a new Stage 9 covers the IOMMU enforcement Kernel DMA Protection performs after the class driver attaches. The arithmetic is eleven minus two minus two plus one plus one equals nine. The StudyGuide question 1 at the foot of this article retains the §1 framing for exam purposes; the per-stage walk below uses the §5 reorganisation.
Diagram source
sequenceDiagram
participant Dev as USB device
participant XHCI as usbxhci.sys (host controller)
participant Hub as usbhub3.sys (hub driver)
participant CCGP as usbccgp.sys (composite parent)
participant PnP as PnP manager
participant IO as I/O manager
participant Cls as Class driver (e.g. hidclass.sys)
Dev->>XHCI: Stage 1 -- electrical attach + port status change
XHCI->>Dev: Port reset + speed detection
XHCI->>Hub: New device on port N (default address 0)
Hub->>Dev: Stage 2 -- GET_DESCRIPTOR (device, first 8 bytes)
Hub->>Dev: SET_ADDRESS
Hub->>Dev: GET_DESCRIPTOR (device, full 18 bytes)
Hub->>Dev: Stage 3 -- GET_DESCRIPTOR (config, first 9 bytes)
Hub->>Dev: GET_DESCRIPTOR (config, full wTotalLength)
Hub->>CCGP: Stage 4 -- composite split (if bDeviceClass=0x00 or IAD present)
CCGP->>PnP: Per-interface PDOs
PnP->>PnP: Stage 5 -- synthesize hardware + compatible IDs
PnP->>PnP: Stage 6 -- INF database search with rank scoring
PnP->>IO: Stage 7 -- KMCS check on chosen function driver
IO->>Cls: Stage 8 -- attach class driver to device node
IO->>IO: Stage 9 -- IOMMU policy (KDP, if armed) The sources for each stage are cited inline in the prose that follows. We will walk all nine.
Stage 1: Physical detection (usbxhci.sys)
The xHCI host controller's hardware raises a port-status-change interrupt when a downstream port detects electrical attach. The host-controller driver -- usbxhci.sys on Windows 8 and newer -- handles the interrupt, drives the port through a reset, and detects the device's negotiated speed: Low (1.5 Mbps), Full (12 Mbps), High (480 Mbps), Super (5 Gbps), or Super+ Speed (10 Gbps and beyond) [11]. Microsoft's architecture documentation names this verbatim: "The xHCI driver is the USB 3.0 host controller driver" and pairs with the framework-derived host-controller extension Ucx01000.sys [2]. The device, at this point, has no identity. It has a port number and a speed. It does not yet have a USB bus address; it lives at the default address (zero) until the hub assigns one.
Stage 2: Initial device-descriptor fetch (usbhub3.sys)
The hub driver, usbhub3.sys, issues the first control transfer. The request is bmRequestType=0x80, bRequest=GET_DESCRIPTOR, wValue=0x0100, wLength=8 -- "give me the first eight bytes of the device descriptor at default address zero." The first eight bytes carry the bMaxPacketSize0 field, which tells the host how to size subsequent control transfers. SET_ADDRESS assigns a real bus address. A second GET_DESCRIPTOR then retrieves the full eighteen-byte USB_DEVICE_DESCRIPTOR.
This is the descriptor parser's first contact with attacker-controlled bytes -- the surface Andy Davis demonstrated as exploitable at Black Hat 2011 [19]. The binary doing the parsing is usbhub3.sys, the same hub driver §4 Generation 4 names verbatim from the architecture reference [2]. The hub driver runs in ring zero. The bytes it parses originate in the peripheral's firmware. The trust contract is one-way.
Stage 3: Configuration-descriptor fetch
The hub driver issues a third GET_DESCRIPTOR for the first nine bytes of USB_CONFIGURATION_DESCRIPTOR to learn the wTotalLength field; a fourth fetch retrieves the full configuration, which includes one or more USB_INTERFACE_DESCRIPTORs, each followed by its USB_ENDPOINT_DESCRIPTORs and any class-specific descriptors (HID report descriptors, mass-storage CSW formats, audio control units). The two-fetch pattern -- read nine bytes to learn the size, then re-read the full block -- is a perfectly sensible engineering optimization. It also doubles the number of attacker-controlled parser entries the hub driver executes per insertion. The pragmatic optimization and the widened attack surface are the same line of code. All of this is parsed in usbhub3.sys [2]. This stage is the bulk of the kernel's adversarial-input surface for USB.
A composite USB device is a single physical peripheral that declares multiple independent interfaces. A common pattern is a wireless-keyboard-and-mouse receiver that presents one USB interface for the keyboard and a second for the mouse. The host treats each interface as a separate logical device and binds a class driver to each. Composite-device handling is the structural primitive that makes the BadUSB "mass storage device that also presents a HID keyboard interface" attack possible inside an unmodified USB peripheral.
Stage 4: Composite-device split (usbccgp.sys)
If the device descriptor's bDeviceClass is 0x00 (deferred to interface), or its bDeviceClass / bDeviceSubClass / bDeviceProtocol triple is 0xEF / 0x02 / 0x01 (the Multi-Interface Function class signalled by Interface Association Descriptors), and the device has more than one interface and a single configuration, the hub bus driver synthesizes an additional compatible ID of USB\COMPOSITE. The PnP manager's INF search then matches that compatible ID against Usb.inf and loads the generic parent driver. Microsoft Learn states the architecture verbatim: "the USB generic parent driver (Usbccgp.sys) ... the generic parent driver enumerates each of these interfaces as a separate device" [41]; the USB 3.0 architecture page is verbatim about which layer does the synthesis: "The hub driver enumerates and loads the parent composite driver if deviceClass is 0 or 0xef and numInterfaces is greater than 1 in the device descriptor" [2]. usbccgp.sys then creates one child physical device object (PDO) per interface and lets the PnP manager bind a class driver to each independently. This is the moment a single physical thumb drive can become a thumb drive and a HID keyboard. Nothing in this stage cross-checks whether the combination is a plausible product; the device has declared it, and the host honors the declaration.
Stage 5: Hardware-ID and compatible-ID synthesis
The PnP manager builds two ordered lists from the descriptor fields it just parsed:
- Hardware IDs (most specific):
USB\VID_xxxx&PID_xxxx&REV_xxxx,USB\VID_xxxx&PID_xxxx, and for composite devicesUSB\VID_xxxx&PID_xxxx&MI_xx(interface number) [42]. - Compatible IDs (fallback):
USB\Class_xx&SubClass_xx&Prot_xx, thenUSB\Class_xx&SubClass_xx, thenUSB\Class_xx[43].
A hardware ID is the most specific identifier the Plug-and-Play manager uses to bind a driver to a device. For USB, the canonical hardware ID is USB\VID_xxxx&PID_xxxx&REV_xxxx, derived directly from the device descriptor's idVendor, idProduct, and bcdDevice fields. A driver INF that names a hardware ID exactly will outrank any compatible-ID match in the rank-scored search; vendors use this to ship a vendor-specific function driver for their own hardware.
A compatible ID is a generic identifier the Plug-and-Play manager falls back to when no driver INF names the device's hardware ID. For USB, compatible IDs are class-coded: USB\Class_03&SubClass_01&Prot_01 is a boot-protocol keyboard, USB\Class_08&SubClass_06&Prot_50 is a SCSI-transparent mass-storage device. The inbox Microsoft class drivers (hidusb.sys, usbstor.sys, and so on) are registered against compatible IDs, which is why an unbranded thumb drive with no vendor INF still gets a working class driver on Windows.
Stage 6: INF database search with rank scoring
The PnP manager hands the two lists to the driver-store INF search. The algorithm is documented under "How Setup Selects Drivers" [3] and is rank-arithmetic: each candidate INF is assigned a 32-bit rank, lowest wins. Roughly speaking, the rank is composed from three terms: an ID-match term (hardware-ID hit beats compatible-ID hit, and a higher hardware-ID in the list beats a lower one), a signer-trust term (a Microsoft-signed driver outranks a third-party-signed driver of equal ID specificity), and an OS-version term. The chosen INF's [Models] section names the function driver [44]. The two-phase driver-package model from Windows 10 1607 first installs the best driver-store match for fast operation, then queries Windows Update separately for a potentially better match [3].
Worked example. A USB Mass Storage device exposes hardware ID USB\VID_0951&PID_1666 (a Kingston DataTraveler) and compatible ID USB\Class_08&SubClass_06&Prot_50 (SCSI-transparent bulk-only). The driver store contains the Microsoft inbox INF (usbstor.inf) registered against the compatible ID and signed by Microsoft, and a third-party INF registered against the hardware ID and signed by a paid-up OEM. The rank arithmetic decides which one wins.
Diagram source
flowchart TD
Dev["Device exposes:
HWID=USB\VID_0951&PID_1666
CompatID=USB\Class_08&SubClass_06&Prot_50"]
Dev --> Store["Driver store search"]
Store --> A["Candidate A: usbstor.inf
Match on CompatID
Signer: Microsoft (rank 0x00)"]
Store --> B["Candidate B: vendor.inf
Match on HWID
Signer: OEM (rank 0x01)"]
A --> ARank["A.rank = HWID_RANK_BASE + CompatID_term + 0x00
= 0x0000 + 0x1003 + 0x00
= 0x1003"]
B --> BRank["B.rank = HWID_term + Signer_term
= 0x0000 + 0x01
= 0x0001"]
ARank --> D{"Compare ranks (lowest wins)"}
BRank --> D
D --> Win["B wins: vendor.inf binds to USB\VID_0951&PID_1666"] The exact numeric constants are policy-controlled and vary by Windows version; the structural ordering is documented [3] [42] [43] [44]. The takeaway is that a USB device with no hardware-ID-specific INF in the driver store always falls back to the Microsoft inbox class driver matched on compatible ID, which is why an arbitrary thumb drive declaring bInterfaceClass=0x08 always finds usbstor.sys ready to load.
// Simplified model of the documented rank-scoring algorithm.
// Lower numeric rank wins; the exact constants are version-policy controlled.
const HWID_BASE = 0x0000;
const COMPATID_BASE = 0x1000;
const POSITION_STEP = 0x0001;
const SIGNER = { MICROSOFT: 0x00, OEM: 0x01, THIRD_PARTY: 0x02, UNSIGNED: 0x80 };
function rank(match) {
const idTerm = match.kind === "HWID" ? HWID_BASE : COMPATID_BASE;
const positionTerm = match.position * POSITION_STEP;
return idTerm + positionTerm + SIGNER[match.signer];
}
const candidates = [
{ name: "usbstor.inf (Microsoft inbox)",
kind: "COMPATID", position: 3, signer: "MICROSOFT" },
{ name: "vendor.inf (Kingston OEM)",
kind: "HWID", position: 0, signer: "OEM" },
];
const ranked = candidates
.map(c => ({ ...c, rank: rank(c).toString(16).padStart(4, "0") }))
.sort((a, b) => parseInt(a.rank, 16) - parseInt(b.rank, 16));
for (const c of ranked) console.log(`rank=0x${c.rank} ${c.name}`);
console.log("Winner:", ranked[0].name); Press Run to execute.
Stage 7: KMCS verification of the chosen driver
The function driver named in the winning INF is loaded. Before the I/O manager attaches it, the loader checks its signature against the Kernel-Mode Code Signing policy: signature must chain to a Microsoft-trusted root, use SHA-256, and -- if Hypervisor-Enforced Code Integrity is enabled -- pass HVCI's per-page integrity check. The driver block list and the vulnerable-driver block list are consulted. The full signing-by-version matrix is documented on Microsoft Learn [4] [20].
This is the canonical aha moment of the article. Kernel-Mode Code Signing certifies the driver. It does not certify what the driver consumes.
Stage 8: Class-driver attachment
With the rank scoring decided and the function driver KMCS-verified, the I/O manager attaches the driver to the new device node and the class driver begins serving I/O. The function driver is drawn from the inbox class-driver roster catalogued in §6 -- hidclass.sys and hidusb.sys for HID; usbstor.sys for mass storage; winusb.sys for vendor-specific generic access via the Microsoft OS Descriptor mechanism [45]; the UcmCx.sys family for Type-C connector management [36]; and the rest of the inbox roster in §6 [2]. This is the moment a USB device transitions from a parsed PDO to a binding that exposes per-class I/O semantics to user-mode -- the IRQL boundary at which descriptor-trust becomes operational rather than merely synthesised.
Stage 9: IOMMU enforcement (Kernel DMA Protection)
If Kernel DMA Protection is armed and the device is externally connected via a PCIe-tunneling fabric (Thunderbolt 3, Thunderbolt 4, USB4), the platform IOMMU places the device behind a device-specific translation domain. Pre-login DMA is blocked. Post-login DMA is allowed only into the device's own sandboxed memory if the driver opted in with DmaRemappingCompatible=1 in its INF [35]. KDP performs the IOMMU-mediated peripheral confinement quoted verbatim in §4 Generation 8 [34]. The deeper architectural treatment of Windows's hypervisor-enforced isolation primitives lives in the sibling article on the secure kernel and Virtualization-Based Security.
An IOMMU is a hardware unit that sits between peripherals and main memory, translating peripheral-issued DMA addresses through a per-device page table the operating system controls. Intel's implementation is called VT-d; AMD's is AMD-Vi; ARM platforms expose a System Memory Management Unit (SMMU). With an IOMMU enabled and configured by the OS, a peripheral that issues a DMA read to an address outside its sandboxed memory region gets a translation fault instead of a successful read. Without an IOMMU -- or with the IOMMU not enforcing policy on a given device -- peripheral DMA is unrestricted physical-address access to the kernel.
A USB 2.0 thumb drive performs no DMA. KDP is silent on it.
Diagram source
flowchart TD
subgraph HC["Host controller layer"]
XHCI["usbxhci.sys
USB 3.0 host controller driver"]
UCX["Ucx01000.sys
USB host controller extension (KMDF)"]
end
subgraph Hub["Hub layer"]
H["usbhub3.sys
USB 3.0 hub and enumeration"]
end
subgraph Comp["Composite split"]
CCGP["usbccgp.sys
generic parent: one PDO per interface"]
end
subgraph Class["Class-driver layer"]
HID["hidclass.sys + hidusb.sys
HID class"]
STOR["usbstor.sys
Mass Storage Class"]
AUDIO["usbaudio2.sys
Audio Class 2.0"]
VIDEO["usbvideo.sys
USB Video Class (UVC)"]
SER["usbser.sys
CDC Serial"]
WIN["winusb.sys
Generic vendor access"]
UCM["UcmCx / UcmUcsiCx / UcmTcpciCx
USB Type-C connector"]
end
XHCI --> UCX
UCX --> H
H --> CCGP
CCGP --> HID
CCGP --> STOR
CCGP --> AUDIO
CCGP --> VIDEO
CCGP --> SER
CCGP --> WIN
CCGP --> UCM Sources for the architecture diagram, layer by layer: [2] for the host-controller and hub layers (usbxhci.sys, Ucx01000.sys, usbhub3.sys); [41] for the composite parent driver usbccgp.sys; [45] for winusb.sys; [36] for the UCM class-extension family.
Of the nine stages Windows executes between physical insertion and a class-driver attach, only two -- Stages 7 and 9 -- consult anything Windows holds as cryptographic truth. The other seven trust whatever the peripheral says, the moment the peripheral says it. KMCS certifies the driver, not the device. KDP certifies the bus, not the descriptor. The descriptor-trust gap is structural to USB; it lives in Stages 2 through 6, and no Windows-side defense has ever proposed to close it.
Nine stages. Two of them are the security model the article's reader thought was the security model. The other seven are descriptor parsing, ID synthesis, and INF search -- and they trust whatever the peripheral declares.
6. What Ships in Windows 11 24H2 / 25H2
Section 5 was the pipeline. This section is the roster: every Windows-11-shipping mechanism that defends the USB attack surface, what it actually does, and -- in the table at the end of this section -- what it does not.
The inbox class-driver roster. The class drivers that bind to a USB device after Stage 6 are mostly Microsoft-authored and ship in every Windows 11 SKU. They include hidclass.sys and hidusb.sys for keyboards, mice, joysticks, and HID-over-USB; usbstor.sys for the Mass Storage Class; usbprint.sys for the Printer Class; usbaudio2.sys for USB Audio Class 2.0; usbvideo.sys for the USB Video Class (webcams); usbser.sys for the CDC Serial class; winusb.sys for vendor-specific generic-access scenarios; the UcmCx.sys family for Type-C connector management; Hidi2c.sys for HID-over-I2C; and wpdusb.sys for MTP / PTP Windows Portable Devices [2] [36] [45]. Every class driver in that list is signed under the Kernel-Mode Code Signing policy [4]. Every class driver in that list trusts the descriptor that selected it. Hidi2c.sys is the sleeper attack surface on most laptops. Internal precision touchpads, fingerprint readers, and increasingly proximity sensors are HID-over-I2C devices wired to the chipset, not the external USB bus. They are not subject to USB-side Device Control policy because they are not USB devices; they are HID devices that happen to talk a different transport. The HID class definition is the same as it is on USB.
Kernel DMA Protection policy surface. KDP exposes three Group Policy values on DMAGuard\DeviceEnumerationPolicy: Block (the default; conservative posture), Allow with audit, and Allow all. The Microsoft Learn reference is verbatim about the default behavior: "By default, peripherals with DMA Remapping incompatible drivers are blocked from starting and performing DMA until an authorized user signs into the system or unlocks the screen" [34]. KDP's silicon and firmware prerequisites (IOMMU support, UEFI DMAR / IVRS publication) are non-trivial; on many post-2019 OEM platforms the toggle is shipping in BIOS but turned off until an administrator changes the firmware setting.
The ASR + Device Control + GPO triangle. The three deployable layers of enterprise USB policy on Windows 11 are an Attack Surface Reduction rule, the Microsoft Defender for Endpoint Device Control framework, and the older Group Policy Device Installation Restrictions family.
Attack Surface Reduction is a set of policy-defined kernel-and-userland rules in Microsoft Defender for Endpoint that block specific abusable behaviors. Each rule is identified by a GUID and toggled per-rule by Group Policy, Intune, or PowerShell. ASR rules sit in front of common execution sinks (Office child processes, script-from-email runs, USB-borne executables) and refuse the operation when the rule is in Block mode. They are a policy layer on top of the Windows execution model, not a re-design of it.
The ASR rule that targets USB-borne malware is "Block untrusted and unsigned processes that run from USB", GUID b2b3f03d-6a65-4f7b-a9c7-1c7ef74a9ba4 on Microsoft's ASR-rule-to-GUID matrix [37]. (Several published guides cite the unrelated GUID d4f940ab-401b-4efc-aadc-ad5f3c50688a for the same rule; per the matrix that GUID is actually "Block all Office applications from creating child processes". The corrected USB GUID is the one to deploy.) Microsoft Defender for Endpoint Device Control is the granular layer: groups, rules, and settings let an administrator allow read-only-for-corporate-encrypted-USB, deny-write-for-personal-USB, allow corporate HID by VID/PID/serial, and a dozen other primitive combinations per-user [38]. The older Group Policy Device Installation Restrictions framework has eight policies (AllowedDeviceClasses, DenyDeviceClasses, AllowedDeviceIDs, DenyDeviceIDs, and so on) and uses Setup Class GUIDs such as GUID_DEVCLASS_USB ({36FC9E60-C465-11CF-8056-444553540000}) and GUID_DEVCLASS_HIDCLASS ({745A17A0-74D3-11D0-B6FE-00A0C90F57DA}) for class-wide rules [39] [40].
BitLocker To Go. The full-volume-encryption story for removable media on Windows has been BitLocker To Go since Windows 7. On Windows 11 the default cipher is XTS-AES-128 (administrators can promote to XTS-AES-256 via the Group Policy "Choose drive encryption method and cipher strength" under Removable Data Drives), and the Group Policy "Deny write access to removable drives not protected by BitLocker" is the enterprise opt-in to force the contract [46]. BitLocker To Go protects the data on a USB stick if it is lost or stolen. It does not protect the host from a malicious peripheral, because the malicious peripheral does not present itself as a BitLocker-managed volume; it presents itself as whatever it pleases at Stage 5.
USB-IF Authentication Specification Revision 1.0. Published in the form of an ECN and errata dated January 7, 2019 [47], this specification defines cryptographic peripheral identity using ECDSA P-256, X.509 certificate chains, and SHA-256 hashing -- the same primitives Windows already uses for KMCS and BitLocker. The standard exists. Windows ships no in-box consumer. No major host operating system in 2026 consumes it. The 2019 promise of cryptographic device identity has been seven years away for seven years.
The SOTA roster, in a comparison table:
| Mechanism | What it gates | Attack class addressed | Does NOT address |
|---|---|---|---|
| KMCS [4] | Loading of unsigned .sys files into ring zero | Arbitrary kernel-mode driver loads | Descriptors a signed driver consumes |
| Kernel DMA Protection [34] | Pre-login + post-login DMA from Thunderbolt / USB4 PCIe endpoints | Thunderclap-class DMA attacks | USB 2.0/3.x storage and HID; pre-DMAR firmware platforms |
ASR USB rule b2b3f03d-... [37] | Unsigned and untrusted process launch from USB-mounted volume | AutoRun-like execution; mass-storage-borne executables | HID-injection (no process is launched); descriptor-parser bugs |
| MDE Device Control [38] | Per-VID/PID/serial allow-deny on read, write, execute, file-walk | Any policy-named USB device class | Devices the policy explicitly allows |
| GPO Device Installation Restrictions [39] [40] | Setup-class-wide allow-deny by Device Setup Class GUID | Whole-class blocks (e.g. all USB Storage) | Devices the policy allow-lists |
| BitLocker To Go [46] | Encryption of data at rest on removable USB volumes | Lost / stolen thumb drive | Malicious peripheral; host compromise |
| AutoRun-disable (KB971029 era) [18] [9] | autorun.inf-driven AutoPlay launch on insert | Conficker-class AutoRun worms | HID injection; descriptor parser bugs |
| Driver Block List / Vulnerable Driver Block List [4] | Loading of named known-bad signed .sys files | Bring-Your-Own-Vulnerable-Driver | New (unlisted) malicious-but-signed driver |
| USB-IF Authentication 1.0 [47] | Cryptographic peripheral identity at enumeration | Descriptor-trust impossibility result (BadUSB) | (Standard exists; Windows does not consume it) |
// Emulates the PowerShell check:
// $p = Get-MpPreference
// $p.AttackSurfaceReductionRules_Ids
// $p.AttackSurfaceReductionRules_Actions
// In a real Windows 11 enterprise rollout, run the PowerShell as administrator.
const USB_RULE_GUID = "b2b3f03d-6a65-4f7b-a9c7-1c7ef74a9ba4"; // "Block untrusted and unsigned processes from USB"
const ACTION = { DISABLED: 0, BLOCK: 1, AUDIT: 2, WARN: 6 };
// Sample output that a healthy enterprise endpoint should produce.
const sample = {
ids: [USB_RULE_GUID, "d4f940ab-401b-4efc-aadc-ad5f3c50688a", "75668c1f-73b5-4cf0-bb93-3ecf5cb7cc84"],
actions: [ACTION.BLOCK, ACTION.BLOCK, ACTION.BLOCK],
};
const i = sample.ids.indexOf(USB_RULE_GUID);
if (i < 0) {
console.log("ASR USB rule not present in policy.");
} else if (sample.actions[i] === ACTION.BLOCK) {
console.log("ASR USB rule is ENABLED in BLOCK mode.");
} else if (sample.actions[i] === ACTION.AUDIT) {
console.log("ASR USB rule is in AUDIT mode (events logged, nothing blocked).");
} else {
console.log("ASR USB rule is DISABLED (action=" + sample.actions[i] + ").");
} Press Run to execute.
Eight Windows-shipping mechanisms, one missing implementation. The implementation gap is structural: the only complete defense in the roster is the one Windows does not ship.
7. USB Security on Non-Windows Platforms
Windows is not the only OS that inherits USB's descriptor-trust premise. Every host operating system since 1996 has inherited the same contract; each has staked out a different position on how to live with it. The contrast clarifies what Windows chose.
macOS on Apple Silicon (Ventura 2022, extended Sequoia 2024). Apple Support is verbatim on the prompt: "When you use a new or unknown USB accessory, Thunderbolt accessory, or SD card with your Mac laptop with Apple silicon, you get an alert that asks you to allow the accessory to connect" [48]. The same page documents the four user-selectable modes -- Always ask, Ask for new accessories, Automatically allow when unlocked, Always allow -- and the lockout window: "If your Mac has been locked for 3 or more days, you might need to unlock it to use a previously allowed accessory again" [48]. Apple is the only major host OS that ships a user-facing prompt as the default posture. Apple Silicon Macs enforce the accessory-prompt at the hardware level through the Secure Enclave Processor, not purely in software. This is architectural inference from Apple's general SEP-policy documentation; Apple Support pages describe the user-visible behavior, not the SEP-side enforcement chain. The architectural distinction matters because the prompt is not a kernel-side policy a privileged process can bypass.
iOS USB Restricted Mode (iOS 11.4.1, 2018; USB-C version, iOS 17+). Apple Support carries the iOS variant verbatim: "By default, you need to first unlock your iPhone or iPad to connect to an accessory or computer" [49]. Modern USB-C iPhones and iPads expose the same four-mode setting as the Mac: Always Ask, Ask for New Accessories, Automatically Allow When Unlocked, Always Allow [49]. iOS came first; macOS adopted the same UX pattern four years later.
Linux usbguard. The open-source usbguard daemon implements per-user, per-device USB authorization on top of the kernel's sysfs authorized flag [50]. The architectural cousin of Windows's Defender for Endpoint Device Control, usbguard ships a mature policy language (usbguard list-devices, usbguard allow-device, declarative rules.conf) and integrates cleanly with PolicyKit. The catch is that no major Linux distribution enables usbguard by default; it is opt-in software a sysadmin installs. Linux's kernel has had the authorized sysfs flag since 2007; what it has not had is a default-deny posture out of the box.
OpenBSD umass(4) / FreeBSD opt-in USB policy. The BSD family of operating systems ships conservative defaults: separated drivers per class, no autorun.inf-equivalent in the file manager, and a documented user-mode authorization story. Deployment scale is small; the design is included here only to illustrate that a default-deny posture is technically possible inside an inherited USB protocol contract.
The cross-platform comparison:
| Platform | Default posture | Model | Pre-login HID injection | DMA isolation |
|---|---|---|---|---|
| Windows 11 25H2 | Allow on insert | Policy frameworks layered over descriptor trust [37] [38] [39] | Mitigated only by ASR USB rule + Device Control allow-list (enterprise opt-in) | Kernel DMA Protection on capable platforms [34] |
| macOS (Apple Silicon) | Prompt user | User-facing approval dialog, 3-day re-prompt window [48] | Mitigated by default prompt (consumer + enterprise) | Apple-managed IOMMU + SEP policy |
| iOS (USB-C) | Locked-until-unlock | User-facing approval dialog [49] | Mitigated by default prompt | Apple-managed IOMMU + SEP policy |
| ChromeOS (managed) | Default deny after suspend | Sign-in-state-gated authorization | Mitigated by default deny (managed devices) | Platform-IOMMU policy |
| Linux + usbguard | Default deny if installed | User-space daemon over kernel authorized flag [50] | Mitigated if usbguard installed (opt-in) | Distribution-dependent |
| Stock Linux | Allow on insert | Kernel authorized flag exists, default is allowed | Not mitigated | Distribution-dependent |
| OpenBSD / FreeBSD | Conservative by default | Per-class driver opt-in | Not the default attack surface (low deployment) | Limited |
Two platforms (Apple's, both of them) prompt the user as the default posture. One (Linux) ships an opt-in user-space daemon. Windows is the only major platform that combines a kernel-mode device-control framework with cross-platform telemetry inside Microsoft Defender for Endpoint -- and the only one still relying entirely on enterprise opt-in for the HID-injection mitigation. The consumer default on Windows 11 25H2 is allow-on-insert.
8. What Windows Cannot Defend Against
We have walked the modern pipeline and seen the roster of defenses. We owe the reader a clean accounting of where the model is structural -- where no plausible Windows version closes the gap without breaking USB compatibility. There are five named limits, and none of them are bugs.
Limit 1: The descriptor-trust impossibility result. USB has, by specification, no out-of-band identity. A peripheral that declares itself to be a keyboard is a keyboard for purposes of the bus-enumeration handshake. The Wikipedia reference is explicit about the device-class architecture in which the peripheral, not the host, owns the declaration [11]. Until USB-IF Authentication (cryptographic device identity) is universal at the silicon level, this gap is structural to the protocol. Closing it on the host side -- by, say, refusing to bind a class driver until the device signs a challenge -- would break every existing USB device on the market.
Limit 2: HID-class trust is structural, not technical. A USB HID keyboard issues input events to the focused window. Windows has no way to know whether the user is the source of those events or whether a reprogrammed thumb drive is. The SR Labs disclosure is verbatim about why the host cannot tell the difference: the same Phison or Cypress controller chip that ships in a thumb drive can be reprogrammed to enumerate as a HID device with a vendor-controlled report descriptor [23] [24]. Microsoft Defender for Endpoint Device Control supports granular HID rules, but they are opt-in, enterprise-only, and inherently break every external keyboard the policy does not allow. The structural cost of fixing this is breaking USB.
Limit 3: Firmware reprogrammability of commodity USB controllers. Phison, Cypress, Genesys, Realtek, and the rest of the commodity USB-controller market ship field-flashable firmware. The Psychson toolchain demonstrated the Phison PS2251-03 reflash end-to-end and made it reproducible in a researcher's afternoon: "firmware patches have only been tested against PS2251-03 firmware version 1.03.53 ... DriveCom ... EmbedPayload ... Injector" [25]. The O.MG Cable productionized the technique inside a USB-A-to-Lightning cable form factor, proving the attack is now commercial-supply-chain-implantable [29]. The host operating system has no view into the controller's firmware, no way to attest it, and no way to reject a peripheral that exposes a different identity post-flash than it did pre-flash.
Limit 4: Kernel DMA Protection is opt-in at three layers. Silicon (the platform must have an IOMMU), firmware (the UEFI must publish DMAR / IVRS tables), and driver (the driver must declare DmaRemappingCompatible=1 in its INF) [34] [35]. Many post-2019 OEM platforms ship with the firmware toggle off in BIOS. Worse, the Thunderclap research demonstrated that even on IOMMU-enabled systems, shared IOMMU contexts between a peripheral and a kernel driver are a viable attack vector [31]. KDP also has no view at all of USB 2.0/3.x mass storage or HID, which do not perform DMA.
"Windows only uses the IOMMU in limited cases and remains vulnerable." -- Markettos, Rothwell, Gutstein, Pearce, Neumann, Moore, and Watson, Thunderclap, NDSS 2019 [31]
Limit 5: The descriptor parser is C code in the kernel. usbhub3.sys and usbccgp.sys are partially undocumented, are closed-source, and parse adversarial input in a memory-unsafe language. Microsoft has not published the source for usbhub3.sys or usbccgp.sys; the architectural descriptions on Microsoft Learn describe the externally visible behavior of these drivers, not their internal parsing routines or memory-safety properties. Any claim about their specific implementation must be hedged accordingly. The conclusion that they parse adversarial input in C is inferred from the Windows-kernel codebase's language conventions and from the public record of descriptor-parser CVEs over the last fifteen years. Andy Davis named the surface in 2011 [19], and Google's syzkaller-USB program -- a public-record proxy for the wider community's descriptor-parser fuzzing effort -- has been producing kernel-side descriptor-parser bugs across host operating systems since 2017 [51]. Until the parser is rewritten in a memory-safe language, this is finite-but-non-zero kernel-mode attack surface. Linux's usbcore has ongoing Rust experiments under the upstream Rust-for-Linux project [52]; Windows has not publicly committed to a similar rewrite.
The USB attack surface on Windows is the price Windows pays for being USB-compatible. Five named gaps. Zero of them are bugs. Each is a structural cost of inheriting a 1996 protocol contract written when peripheral firmware was not field-flashable and the descriptor-trust assumption was at least defensible. In 2026 the assumption is indefensible and the contract is everywhere. The defense Windows ships is the best layered mitigation anyone has built around the gap; it does not close the gap.
9. Open Problems
If the limits are structural, the open problems are sociological: who adopts the standard that already exists, who funds the rewrite that nobody has shipped, who builds the heuristic that no production OS has.
USB-IF Authentication 2.0 / 3.0 uptake. The standard exists as a January 2019 ECN [47]. Device-vendor uptake is near zero outside specialized industries (automotive, medical). Windows has no in-box consumer. The blocker is not cryptographic feasibility -- ECDSA P-256 over SHA-256 with X.509 chains is everyday code -- it is two-sided market adoption: peripheral vendors will not ship the silicon until host operating systems consume it; host operating systems will not consume it until enough peripherals ship it. Someone in the duopoly of major host-OS shipping has to commit first. As of mid-2026 no one has. Current best partial result: the same ECDSA-plus-X.509 attestation pattern has been deployed at scale in adjacent ecosystems -- Apple's Find My accessory-attestation network and the automotive / medical USB-Authentication-mandatory tiers -- demonstrating that the cryptographic primitive itself is silicon-shippable; what remains is OS-side consumption.
HID re-enumeration detection. A thumb drive that mounts as Mass Storage, presents a benign-looking volume for a few seconds, and then re-enumerates as a composite device that adds a HID keyboard interface is the BadUSB signature [23]. No production host operating system detects this generically. A reasonable heuristic -- that a freshly enumerated device which changes its declared composition in the first fifteen seconds is suspicious -- is not in any Microsoft Defender for Endpoint hunting query as a shipped detection, only as a custom Defender XDR query an enterprise can compose itself. The heuristic is this article's own proposal, not a published primary source. Current best partial result: mature Microsoft Defender Experts customers are already deploying custom Defender XDR hunting queries that key on the post-attach composition-change pattern (typically joined against the BadUSB 200 ms keystroke-burst signature in §10.4); the detection exists in mature managed-detection-and-response practices but has not landed as a default rule in any shipping product.
USB-C Alternate Mode trust. DisplayPort Alt Mode, Thunderbolt Alt Mode, and USB4-tunneled PCIe each cross OS / firmware / silicon boundaries inside a single physical connector. The display-side firmware attack surface, the Power Delivery contract negotiation, and the "fast charge negotiation opens a data path" primitive that has emerged in commodity fast-charging hardware are all under-explored. Microsoft's Type-C UCM stack [36] documents the connector-manager class extensions but does not (and cannot) verify the firmware behind the alt-mode peer. Current best partial result: the UCM UcmCx / UcmUcsiCx / UcmTcpciCx class-extension family ships in every Windows 11 SKU and gives the OS a uniform connector-state view it did not have before 2016 -- the partial mitigation is the architectural plumbing, not yet a firmware-attestation policy on top of it.
Supply-chain attacks on USB controller chips. The O.MG Cable shows that BadUSB is now manufacturing-implantable [29]; the FBI's 2020 and 2022 FIN7 advisories show organized cybercriminal actors mailing the same primitive [30]. Hardware bill-of-materials attestation, Microsoft Defender for IoT inventory, and supply-chain risk-management frameworks (NIST SP 800-161 in the United States [53]) are nascent on the consumer side and uneven on the enterprise side. Nothing on the consumer Windows endpoint defends the user from a cable that looks like a real cable. Current best partial result: the deployable enterprise stack is USB-IF Authentication 1.0 in the small set of authentication-capable peripherals [47], plus Microsoft Defender for IoT device-inventory telemetry, plus per-organisation bring-your-own-cable allow-list policy primitives in Defender for Endpoint Device Control [38] -- a layered stack rather than a single defence.
Open-source memory-safe descriptor parser. Linux's usbcore has ongoing Rust experiments under the upstream Rust-for-Linux project [52]; Microsoft has not committed to a similar rewrite. The bug-volume reduction from rewriting usbhub3.sys and usbccgp.sys in a memory-safe language would, on the basis of the public CVE record, dwarf any single mitigation in the article. The blocker is engineering scope, not technical feasibility. Current best partial result: the syzkaller-USB program has produced a continuously growing tally of kernel-side descriptor-parser bugs across host operating systems since 2017 [51], proving the attack surface is empirically large; the upstream Rust-for-Linux USB driver experiments are the only public evidence that a memory-safe rewrite of a production USB stack is practical at scale.
The shortest path to closing the descriptor-trust gap runs through silicon (USB-IF Authentication), not through Windows. Until then, every defense in this article is layered around the gap, not on top of it.
10. A 2026 USB-Security Playbook for Windows IT
We have done the structural accounting. The reader who got this far is either a Windows internals engineer who wants the exact stack picture or an IT operator who needs to deploy something on Monday. The next four sub-sections are for that operator.
For end users
Do not plug in cables you did not buy. Do not use public USB charging stations. Brian Krebs reported the original juice-jacking demonstration verbatim in August 2011: "In the three and a half days of this year's DefCon, at least 360 attendees plugged their smartphones into the charging kiosk built by the same guys who run the infamous Wall of Sheep ... Brian Markus, president of Aires Security, said he and fellow researchers Joseph Mlodzianowski and Robert Rowley built the charging kiosk to educate attendees about the potential perils of juicing up at random power stations" [54]. CISA's 2023 juice-jacking advisory and the FBI Denver Field Office's April 6, 2023 X.com warning trace their evidence base to the Aires Security demonstration and its lineage [55]. If you must charge in public, use a USB data-blocker dongle (a passive accessory that breaks the data pins and passes only power).
For IT admins on Windows 11 Enterprise
What if Kernel DMA Protection shows 'Not capable' in msinfo32?
Not capable means one of three things: the platform lacks an IOMMU (Intel VT-d or AMD-Vi disabled in firmware), the UEFI is not publishing the DMAR / IVRS ACPI tables, or no DMA-Remapping-compatible driver is loaded for at least one externally exposed peripheral. First check Intel VT-d or AMD IOMMU in the BIOS setup screen and enable them. If they are already on, confirm in msinfo32 that DMA Protection: ACPI is On (the firmware-tables check). If the firmware is on and KDP still says Not capable, the per-driver opt-in path is the gap: open Device Manager and look at the Hardware ID tab of each Thunderbolt or USB4 peripheral; a driver without the DmaRemappingCompatible=1 directive in its INF will not be IOMMU-isolated and downgrades the system-wide posture. The Microsoft Learn reference walks through the per-driver opt-in [35].
For driver developers
Declare DmaRemappingCompatible=1 in your INF if your hardware tolerates IOMMU isolation; this is a one-line directive change with a system-wide security posture improvement [35]. Prefer the WDF USB Lower / Upper filter pattern over legacy WDM; the framework's lifecycle and PnP plumbing are correct by construction in ways that legacy WDM code is not [2]. Validate every descriptor byte in user-mode tooling before relying on usbhub3.sys to do so; if your device cannot survive its own validator, the descriptor parser surface is wider than it needs to be. If you are writing a vendor-specific function driver, prefer winusb.sys over a custom KMDF function driver where possible [45]; less kernel-mode code is unambiguously better.
For red team and blue team
The reproducible test devices are USB Rubber Ducky II + DuckyScript 3.0 [28] [27] and the O.MG Cable [29]. For inspection, usbview.exe from the Windows SDK reads live descriptor trees out of usbhub3.sys and is the closest thing Windows has to a USB-side lsusb -v. For trace evidence, the ETW providers Microsoft-Windows-USB-USBHUB3 and Microsoft-Windows-USB-USBPORT (older stack) carry enumeration sequences with per-stage timing, documented end-to-end in Microsoft's USB Event Tracing for Windows reference [56]; wireshark + USBPcap reads the raw descriptor bytes if the kernel-side capture is permitted. For blue-team detection, the BadUSB signature is "first observed time-since-attach to first keystroke event is less than 200 ms"; legitimate human-driven keyboards do not type at that rate.
The playbook is layered defense. None of these controls closes the descriptor-trust gap; together they raise the cost enough that the BadUSB-class attacks the article opens with become attacker-uneconomical in a corporate context. The structural problem is still open.
11. Frequently Asked Questions
The reader has the model. These are the seven misconceptions the model corrects.
Frequently asked questions
Does BitLocker To Go protect me from a malicious USB stick?
No. BitLocker To Go protects the data on the stick if you lose it. A reprogrammed thumb drive that re-enumerates as a HID keyboard is unaffected because BitLocker never sees it as a managed volume in the first place [46]. BitLocker is a confidentiality control for data at rest on a removable volume; the malicious-peripheral problem is a problem of peripheral authentication, which BitLocker is not in the threat model of.
Doesn't Kernel DMA Protection block malicious USB devices?
No. KDP blocks pre-login DMA from PCIe-class peripherals tunneled over Thunderbolt 3, Thunderbolt 4, or USB4 [34]. A USB 2.0 thumb drive performs no DMA at all, so KDP is not in its defense chain. KDP is a defense against a different attack class than BadUSB. They are complementary, not substitutable.
Doesn't driver signing mean USB drivers are safe?
No. Driver signing certifies that Microsoft (or a paid-up OEM signed under Microsoft's signing infrastructure) approved the driver code [4] [20]. It does not certify the descriptors the driver consumes at runtime. The signed hidclass.sys will load happily and inject keystrokes for any HID-class device whose descriptor declares it to be a keyboard, including a reprogrammed thumb drive. KMCS is a defense of the kernel against malicious drivers, not a defense of the kernel against malicious peripherals presenting valid descriptors to honest drivers. The Aside in Section 5 walks this point in detail.
Didn't disabling AutoRun make USB safe?
No, it closed one vector. The 2011 KB971029-equivalent rollout disabled autorun.inf-driven AutoPlay execution by default [18] [9]. That vector was the load-bearing one for the Conficker era. It did not affect HID injection (which Hak5 had already commercialized in 2010), it did not affect descriptor-parser bugs (which Andy Davis named at Black Hat 2011 [19]), and it did not affect the LNK-icon attack class (which the same Patch Tuesday addressed separately [16]). Each closed vector was a single-bug closure that left adjacent vectors intact.
Is the O.MG Cable a movie trope or a real threat?
Real. The cable is commercially available; the firmware is technically documented in the product's own materials [29]; the same primitive (a USB cable with a WiFi-enabled implant) is now in the FBI's threat reporting on FIN7 mailed-USB campaigns [30]. On a stock Windows 11 25H2 endpoint, the O.MG Cable's HID-injection primitive works exactly as advertised unless explicit Microsoft Defender for Endpoint Device Control policy blocks the HID class for that VID/PID/serial [38]. It is not a movie trope.
Will USB-IF Authentication fix all of this?
Not yet, and not by itself. The USB-IF Authentication Specification Revision 1.0 ECN dates from January 7, 2019 [47]. The standard defines ECDSA P-256 over SHA-256 with X.509 chains -- everyday cryptography. The structural problem is two-sided market adoption: no host operating system (Windows, macOS, Linux, ChromeOS) consumes the standard in-box in 2026, and no major device-certification tier requires it. Until that loop closes, the standard's existence is necessary but not sufficient.
If I disable USB ports in BIOS, am I safe?
Mostly, with significant cost. Disabling USB controllers at firmware time blocks every USB attack class because no descriptors are ever parsed. It also blocks every keyboard, every mouse, every security token, every licensed peripheral, every biometric reader, every printer that does not speak network protocols, and every legitimate file transfer onto and off of the endpoint. The cost is usually higher than the threat for general-purpose business endpoints, but the trade-off is a legitimate one for tightly scoped roles like air-gapped industrial-control workstations.
Plugging in a USB device is the single most-trusted action a user routinely performs on a Windows machine. Windows has done forty years of work to walk that trust back -- bit by bit, single-bug closure by single-bug closure, generation by generation. Some of that work is silicon-level (Kernel DMA Protection over IOMMU). Some of it is kernel-level (Kernel-Mode Code Signing chained to a Microsoft-trusted root). Some of it is application-level (Attack Surface Reduction, Device Control, AutoRun disablement, BitLocker To Go). None of it -- not one of the ten generations the article walks -- has touched the descriptor-trust premise itself. A peripheral's self-declared identity is still its identity at enumeration time, in 2026 as in 1996.
The next breakthrough on this stack will not come from Windows. It will come from USB-IF Authentication finally shipping in commodity peripheral silicon, and a host operating system committing to consume it in-box. That shipment has now been seven years away for seven years. When it arrives -- if it arrives -- the descriptor-trust gap closes, the BadUSB primitive becomes detectable in the bus enumeration handshake, and the eleven kernel-mode operations that begin at 10:42:17 each morning finally consult something the peripheral cannot fake. Until then, the gap is the gap, and the layered mitigations Windows ships are what stand between a Phison microcontroller and your domain administrator credentials.
Study guide
Key terms
- USB descriptor
- A small structured block of bytes a USB peripheral returns on request; the device descriptor names vendor ID, product ID, device class, and packet size. The host has no out-of-band channel to verify any of these fields.
- Vendor ID / Product ID (VID/PID)
- A pair of 16-bit numbers the USB-IF sells (VID) and the manufacturer assigns (PID). The pair forms Windows's most-specific USB hardware ID. The USB-IF charges $6,000/year for a VID.
- Hardware ID
- The most specific identifier the PnP manager uses to bind a driver to a USB device. Canonical form: USB\VID_xxxx&PID_xxxx&REV_xxxx, synthesized from the device descriptor.
- Compatible ID
- A class-based identifier the PnP manager falls back to when no hardware-ID-specific driver INF matches. Canonical form: USB\Class_xx&SubClass_xx&Prot_xx, synthesized from the interface descriptor.
- Composite USB device
- A physical USB peripheral that declares multiple independent interfaces. usbccgp.sys splits the device into per-interface PDOs; a class driver binds to each independently. This is the structural primitive that lets a thumb drive also present a HID keyboard.
- Kernel-Mode Code Signing (KMCS)
- Mandatory-since-Vista-x64 policy requiring every .sys file Windows loads into ring zero to carry a Microsoft-trusted signature using SHA-256. KMCS protects against malicious drivers loading; it does not authenticate the data those drivers consume.
- Kernel DMA Protection (KDP)
- Windows 10 1803+ defense that uses the platform IOMMU to confine externally-connected PCIe-class peripherals (Thunderbolt 3/4, USB4) to per-device translation domains. Pre-login DMA is blocked; per-driver opt-in via DmaRemappingCompatible=1 is required for post-login allow.
- IOMMU
- Input/Output Memory Management Unit; hardware between peripherals and main memory that translates DMA addresses through OS-controlled per-device page tables. Intel VT-d, AMD-Vi, ARM SMMU.
- HID class
- USB device class with bInterfaceClass=0x03, originally for keyboards/mice/joysticks. A device that declares HID is allowed to inject keyboard and pointer events into the active session. There is no protocol provision for the host to authenticate that the device is actually a keyboard.
- Attack Surface Reduction (ASR)
- Microsoft Defender for Endpoint policy framework of GUID-identified rules that block specific abusable behaviors. The USB rule (b2b3f03d-6a65-4f7b-a9c7-1c7ef74a9ba4) blocks untrusted and unsigned process execution from USB-mounted volumes.
- BadUSB
- The 2014 SR Labs disclosure (Nohl + Krißler + Lell, Black Hat USA) that USB peripheral firmware is field-reprogrammable, allowing a thumb drive to re-enumerate as a HID keyboard and inject keystrokes. Demonstrated to be unpatchable at the protocol level by Karsten Nohl.
- USB-IF Authentication 1.0
- January 2019 ECN to the USB specification defining cryptographic peripheral identity via ECDSA P-256, X.509 chains, and SHA-256. Exists as a published standard; no major host OS consumes it as of 2026.
Comprehension questions
In what order does Windows execute the eleven kernel-mode operations between physical insertion of a USB device and class-driver attachment?
Port-status-change interrupt; port reset; speed detection; default-address GET_DESCRIPTOR for the first 8 bytes; SET_ADDRESS; full 18-byte device descriptor fetch; configuration descriptor fetch; composite-device split if applicable; hardware-ID and compatible-ID synthesis; INF database rank-scored search and KMCS verification of the chosen driver; class-driver attachment.
Why does Kernel-Mode Code Signing not stop a BadUSB attack?
KMCS verifies the cryptographic signature of the driver binary Windows loads. It does not verify the descriptors the driver consumes at runtime. The signed hidclass.sys loads correctly and injects keystrokes for any HID-class peripheral that declares itself a keyboard; the malicious peripheral never needed to be signed because it is not the loaded binary.
Why is a thumb drive that re-enumerates as a HID keyboard a protocol-level attack, not a bug?
The USB specification, by design, lets a peripheral declare its own class via the bInterfaceClass field. The HID class definition allows any HID device to send input events to the active session. There is no out-of-band channel for the host to authenticate that the device is actually a keyboard. The attack is the contract working as written.
What attack class does Kernel DMA Protection mitigate, and what does it NOT mitigate?
KDP mitigates DMA-based attacks from externally-connected PCIe-class peripherals tunneled over Thunderbolt 3/4 or USB4. It does NOT mitigate USB 2.0/3.x mass storage attacks, HID injection, descriptor parser bugs, or anything else that does not involve raw DMA. A USB 2.0 thumb drive performs no DMA at all.
Why has USB-IF Authentication 1.0 not been adopted by any major host OS as of 2026?
The standard has existed since January 2019. The blocker is two-sided market adoption: peripheral vendors will not ship Authentication-capable silicon until host operating systems consume it, and host operating systems will not consume it until enough peripherals ship it. The cryptography (ECDSA P-256, X.509, SHA-256) is everyday code; the gap is institutional, not technical.
References
- (2000). Universal Serial Bus Specification, Revision 2.0 (Section 7.1.7.3 Connect and Disconnect Signaling defines T_ATTDB attach-debounce interval). USB-IF. https://www.usb.org/document-library/usb-20-specification ↩
- USB 3.0 Driver Stack Architecture. Microsoft Learn. https://learn.microsoft.com/en-us/windows-hardware/drivers/usbcon/usb-3-0-driver-stack-architecture ↩
- How Setup Selects Drivers. Microsoft Learn. https://learn.microsoft.com/en-us/windows-hardware/drivers/install/how-setup-selects-drivers ↩
- Kernel-Mode Code Signing Policy (Windows Vista and Later). Microsoft Learn. https://learn.microsoft.com/en-us/windows-hardware/drivers/install/kernel-mode-code-signing-policy--windows-vista-and-later- ↩
- Brain (computer virus). Wikipedia. https://en.wikipedia.org/wiki/Brain_(computer_virus) ↩
- Stoned (computer virus). Wikipedia. https://en.wikipedia.org/wiki/Stoned_(computer_virus) ↩
- Michelangelo (computer virus). Wikipedia. https://en.wikipedia.org/wiki/Michelangelo_(computer_virus) ↩
- Boot sector. Wikipedia. https://en.wikipedia.org/wiki/Boot_sector ↩
- AutoRun. Wikipedia. https://en.wikipedia.org/wiki/AutoRun ↩
- USB Implementers Forum. Wikipedia. https://en.wikipedia.org/wiki/USB_Implementers_Forum ↩
- USB. Wikipedia. https://en.wikipedia.org/wiki/USB ↩
- (1999). Universal Serial Bus Mass Storage Class -- Bulk-Only Transport, Revision 1.0. USB-IF. https://www.usb.org/sites/default/files/usbmassbulk_10.pdf ↩
- Conficker. Wikipedia. https://en.wikipedia.org/wiki/Conficker ↩
- CVE-2008-4250 Detail (Server Service path-canonicalization overflow exploited by Gimmiv.A). NIST National Vulnerability Database. https://nvd.nist.gov/vuln/detail/CVE-2008-4250 ↩
- Stuxnet. Wikipedia. https://en.wikipedia.org/wiki/Stuxnet ↩
- CVE-2010-2568 Detail. NIST National Vulnerability Database. https://nvd.nist.gov/vuln/detail/CVE-2010-2568 ↩
- Microsoft Security Bulletin MS10-046: Vulnerability in Windows Shell Could Allow Remote Code Execution (2286198). Microsoft Security Response Center. https://learn.microsoft.com/en-us/security-updates/securitybulletins/2010/ms10-046 ↩
- (2011). Adobe, Microsoft, WordPress Issue Security Fixes. KrebsOnSecurity. https://krebsonsecurity.com/2011/02/adobe-microsoft-wordpress-issue-security-fixes/ ↩
- (2011). USB -- Undermining Security Barriers (Further Adventures with USB). NCC Group / Black Hat USA 2011. https://www.nccgroup.com/research/usb-undermining-security-barriersfurther-adventures-with-usb/ ↩
- Driver Signing. Microsoft Learn. https://learn.microsoft.com/en-us/windows-hardware/drivers/install/driver-signing ↩
- Who Is This Code? The Quiet 33-Year Reinvention of App Identity in Windows. paragmali.com. https://paragmali.com/blog/who-is-this-code----the-quiet-33-year-reinvention-of-app-ide/ ↩
- Karsten Nohl. Wikipedia. https://en.wikipedia.org/wiki/Karsten_Nohl ↩
- (2014). BadUSB -- On Accessories That Turn Evil. SR Labs / Black Hat USA 2014. https://radetskiy.files.wordpress.com/2014/08/srlabs-badusb-blackhat-v1.pdf ↩
- BadUSB. Wikipedia. https://en.wikipedia.org/wiki/BadUSB ↩
- (2014). Psychson: USB Device Research (Phison 2251-03). GitHub. https://github.com/adamcaudill/Psychson ↩
- (2014). Code Published for Unfixable USB Attack. Wired. https://www.wired.com/2014/10/code-published-for-unfixable-usb-attack/ ↩
- USB Rubber Ducky by Hak5 -- Documentation. Hak5 Docs. https://docs.hak5.org/hak5-usb-rubber-ducky/usb-rubber-ducky-by-hak5/ ↩
- USB Rubber Ducky (Mark II). Hak5 Shop. https://shop.hak5.org/products/usb-rubber-ducky ↩
- O.MG Cable (Mischief Gadgets). o.mg.lol. https://o.mg.lol/ ↩
- (2022). FBI: Hackers sending malicious USB drives and teddy bears via USPS. BleepingComputer. https://www.bleepingcomputer.com/news/security/fbi-hackers-sending-malicious-usb-drives-and-teddy-bears-via-usps/ ↩
- (2019). Thunderclap: Exploring Vulnerabilities in Operating System IOMMU Protection via DMA from Untrustworthy Peripherals. NDSS 2019. https://www.ndss-symposium.org/ndss-paper/thunderclap-exploring-vulnerabilities-in-operating-system-iommu-protection-via-dma-from-untrustworthy-peripherals/ ↩
- (2020). Thunderspy: When Lightning Strikes Thrice. thunderspy.io. https://thunderspy.io/ ↩
- Thunderclap (security vulnerability). Wikipedia. https://en.wikipedia.org/wiki/Thunderclap_(security_vulnerability) ↩
- Kernel DMA Protection. Microsoft Learn. https://learn.microsoft.com/en-us/windows/security/hardware-security/kernel-dma-protection-for-thunderbolt ↩
- Enabling DMA Remapping for Device Drivers. Microsoft Learn. https://learn.microsoft.com/en-us/windows-hardware/drivers/pci/enabling-dma-remapping-for-device-drivers ↩
- Bring up a USB Type-C Connector on a Windows System. Microsoft Learn. https://learn.microsoft.com/en-us/windows-hardware/drivers/usbcon/bring-up-a-usb-type-c-connector-on-a-windows-system ↩
- Attack Surface Reduction Rules Reference. Microsoft Learn. https://learn.microsoft.com/en-us/defender-endpoint/attack-surface-reduction-rules-reference ↩
- Microsoft Defender for Endpoint Device Control Overview. Microsoft Learn. https://learn.microsoft.com/en-us/defender-endpoint/device-control-overview ↩
- Manage Device Installation with Group Policy. Microsoft Learn. https://learn.microsoft.com/en-us/windows/client-management/client-tools/manage-device-installation-with-group-policy ↩
- System-Defined Device Setup Classes. Microsoft Learn. https://learn.microsoft.com/en-us/windows-hardware/drivers/install/device-setup-classes ↩
- USB Common Class Generic Parent Driver. Microsoft Learn. https://learn.microsoft.com/en-us/windows-hardware/drivers/usbcon/usb-common-class-generic-parent-driver ↩
- Hardware IDs. Microsoft Learn. https://learn.microsoft.com/en-us/windows-hardware/drivers/install/hardware-ids ↩
- Compatible IDs. Microsoft Learn. https://learn.microsoft.com/en-us/windows-hardware/drivers/install/compatible-ids ↩
- INF Files. Microsoft Learn. https://learn.microsoft.com/en-us/windows-hardware/drivers/install/inf-files ↩
- WinUSB Installation. Microsoft Learn. https://learn.microsoft.com/en-us/windows-hardware/drivers/usbcon/winusb-installation ↩
- BitLocker Overview. Microsoft Learn. https://learn.microsoft.com/en-us/windows/security/operating-system-security/data-protection/bitlocker/ ↩
- (2019). USB Authentication Specification Rev 1.0 ECN and errata through January 7, 2019. USB-IF. https://www.usb.org/document-library/usb-authentication-specification-rev-10-ecn-and-errata-through-january-7-2019 ↩
- About the "Allow accessories to connect" security setting on a Mac laptop with Apple silicon. Apple Support. https://support.apple.com/en-us/102282 ↩
- About the wired accessory security feature on iPhone and iPad. Apple Support. https://support.apple.com/en-us/HT208857 ↩
- USBGuard. usbguard.github.io. https://usbguard.github.io/ ↩
- syzkaller external USB fuzzing documentation. Google / GitHub. https://github.com/google/syzkaller/blob/master/docs/linux/external_fuzzing_usb.md ↩
- Rust for Linux. Rust-for-Linux Project. https://rust-for-linux.com/ ↩
- (2022). NIST Special Publication 800-161 Revision 1: Cybersecurity Supply Chain Risk Management Practices for Systems and Organizations. NIST Computer Security Resource Center. https://csrc.nist.gov/pubs/sp/800/161/r1/upd1/final ↩
- (2011). Beware of Juice-Jacking. KrebsOnSecurity. https://krebsonsecurity.com/2011/08/beware-of-juice-jacking/ ↩
- Juice jacking. Wikipedia. https://en.wikipedia.org/wiki/Juice_jacking ↩
- USB Event Tracing for Windows. Microsoft Learn. https://learn.microsoft.com/en-us/windows-hardware/drivers/usbcon/usb-event-tracing-for-windows ↩