~/home/study/finding-vulnerable-drivers-windows

Finding Vulnerable Drivers on Windows Systems - A Practical Guide

Learn how to enumerate, analyze, and locate vulnerable Windows kernel drivers using built-in utilities, Sysinternals tools, and automated scripts. The guide covers metadata extraction, hash correlation with CVE sources, and defensive best practices.

Introduction

Drivers are the thin line between user-mode applications and the Windows kernel. Because they execute in kernel mode, a flaw in a driver can grant an attacker full system compromise with minimal noise. This study guide walks you through the process of discovering vulnerable drivers on a target Windows host, from basic enumeration to automated cross-referencing against public vulnerability databases.

Real-world incidents-such as the CVE-2021-34527 (PrintNightmare) and the infamous ZDI-22-1102 (Windows Kernel Driver Elevation)-demonstrate how driver weaknesses become the launchpad for ransomware, espionage, and nation-state attacks.

Prerequisites

  • A solid understanding of the Windows Kernel Architecture Overview.
  • Familiarity with Windows kernel driver concepts and their attack surface.
  • Administrator or SYSTEM level access on the target host (required for most enumeration tools).
  • Basic PowerShell, Python, and command-line proficiency.

Core Concepts

Before diving into enumeration, it helps to internalize a few fundamentals:

  1. Driver Types: Kernel-mode drivers (e.g., .sys files) versus user-mode drivers (UMDF). Vulnerability hunting typically focuses on kernel-mode drivers because they have unrestricted access to memory and hardware.
  2. Signing Status: Since Windows 10 (v1607) Microsoft enforces driver signing. Unsigned drivers are rare but remain an attractive attack vector, especially on legacy or mis-configured systems.
  3. Version & Vendor: Drivers are versioned and signed by a vendor's certificate. Older versions often contain known CVEs that attackers can leverage.
  4. Driver Hashes: The SHA-1/SHA-256 hash of a driver binary uniquely identifies its exact build. Hashes are the primary key for cross-referencing with vulnerability feeds.

Think of the driver landscape as a map: enumeration gives you the street names, metadata tells you the building numbers, and hash lookup reveals whether a particular address has a known security flaw.

Enumerating loaded drivers with built-in tools (driverquery, Get-WindowsDriver, PowerShell Get-ItemProperty)

Windows ships with several native commands that can list drivers currently loaded in memory or installed on disk.

driverquery

driverquery /v /fo csv > drivers.csv

The /v flag adds version, date, and signed status columns; /fo csv makes parsing easier. Example excerpt:

"Image Name","Module Name","Display Name","Driver Type","Link Date","Version","Manufacturer","Signed"
"ntoskrnl.exe","ntoskrnl.exe","Windows NT Operating System","Kernel","2023-03-14","10.0.22621.755","Microsoft","Yes"
"C:\Windows\System32\drivers\acpi.sys","acpi.sys","Microsoft ACPI Driver","Kernel","2022-12-08","10.0.22621.755","Microsoft","Yes"

Get-WindowsDriver (DISM)

DISM can enumerate drivers that are installed (not necessarily loaded):

dism /online /get-drivers /format:table

To capture the output for later processing:

dism /online /get-drivers /format:table | Out-File C:\Temp\installed_drivers.txt

PowerShell Get-ItemProperty

Driver objects are exposed under the registry key HKLM:\SYSTEM\CurrentControlSet\Services. You can pull detailed properties with a one-liner:

Get-ChildItem HKLM:\SYSTEM\CurrentControlSet\Services | Where-Object { $_.GetValue('Type') -band 0x1 } | ForEach-Object { $path = $_.GetValue('ImagePath') $full = (Resolve-Path $path).Path $sig = (Get-AuthenticodeSignature $full).SignerCertificate.Subject [pscustomobject]@{ Name = $_.PSChildName Path = $full Version = (Get-Item $full).VersionInfo.FileVersion Signed = $sig } } | Format-Table -AutoSize

This approach gives you driver file location, version, and signing subject in a single table-perfect for feeding into a later hash-lookup step.

Using Sysinternals Autoruns and Process Explorer for driver discovery

Microsoft Sysinternals provides two GUI tools that make driver hunting visual and fast.

Autoruns

  • Run Autoruns.exe with admin rights.
  • Navigate to the Drivers tab. You will see every driver that loads at boot, along with the full path, description, and publisher.
  • Right-click → Save to export a CSV for offline analysis.

Autoruns also highlights unsigned entries in red, offering an immediate view of potentially exploitable drivers.

Process Explorer

  • Launch procexp.exe as SYSTEM (use psexec -i -s procexp.exe).
  • Open View → Lower Pane View → DLLs while selecting the System process. The lower pane lists all loaded kernel modules (drivers).
  • Columns can be added for Version, Company Name, and Signed. Right-click → Properties gives you the digital signature details.

Both tools complement built-in enumeration: Autoruns shows drivers that are configured to load, while Process Explorer reveals those actually resident in memory.

Extracting driver metadata (version, signing status, vendor) via sigcheck and dumpbin

For bulk metadata extraction, command-line utilities are more script-friendly than GUI tools.

Sigcheck (Sysinternals)

sigcheck -q -nobanner -a C:\Windows\System32\drivers\*.sys > sigcheck_output.txt

Key columns:

  • File Name
  • Version
  • Signed (Yes/No)
  • Signing Date
  • Publisher

Dumpbin (Visual Studio)

Dumpbin can pull the export table, which sometimes reveals the driver’s internal name (e.g., DriverEntry), useful for fingerprinting.

dumpbin /headers C:\Windows\System32\drivers\acpi.sys | findstr /i "machine"

Combine both tools in a PowerShell loop to generate a master CSV:

$drivers = Get-ChildItem 'C:\Windows\System32\drivers\*.sys'
$results = foreach ($d in $drivers) { $sig = sigcheck -q -nobanner -a $d.FullName | Select-Object -First 1 $ver = (Get-Item $d.FullName).VersionInfo.FileVersion [pscustomobject]@{ Path = $d.FullName Version = $ver Signed = $sig.Split(' ')[-1] Publisher = ($sig -match 'Publisher:\s+(.*)') ? $Matches[1] : 'Unknown' SHA256 = (Get-FileHash $d.FullName -Algorithm SHA256).Hash }
}
$results | Export-Csv C:\Temp\driver_metadata.csv -NoTypeInformation

The resulting CSV contains everything you need for the next phase: hash correlation.

Cross-referencing driver hashes with public vulnerability databases (CVE, Exploit-DB, GitHub)

Hashes are the universal identifier for a binary. By comparing the SHA-256 of each driver against known vulnerable hashes, you can quickly flag risky components.

Using the NVD (National Vulnerability Database) API

Microsoft publishes CVE metadata, but not raw hashes. However, community projects like VulnDB and Metasploit maintain hash-to-CVE mappings.

import requests, csv, hashlib, json, pathlib

def get_nvd_cve(cve_id): url = f" r = requests.get(url) return r.json()

# Load pre-compiled hash-CVE CSV (example: driver_hashes.csv)
hash_map = {}
with open('driver_hashes.csv', newline='') as f: for row in csv.DictReader(f): hash_map[row['SHA256'].lower()] = row['CVE']

# Scan local drivers
for sys in pathlib.Path('C:/Windows/System32/drivers').glob('*.sys'): h = hashlib.sha256(sys.read_bytes()).hexdigest() if h in hash_map: print(f"[!] {sys.name} matches CVE {hash_map[h]}") # optional: fetch detailed description cve = get_nvd_cve(hash_map[h]) print(cve['result']['CVE_Items'][0]['cve']['description']['description_data'][0]['value']) else: print(f"[+] {sys.name} - no known vulnerability")

This script demonstrates a three-step workflow:

  1. Compute the SHA-256 of each driver.
  2. Lookup the hash in a community-maintained CSV that maps hashes to CVE IDs.
  3. Pull CVE details from NVD for reporting.

Exploit-DB & GitHub Search

Exploit-DB offers a searchable index of PoC exploits. Use the searchsploit CLI to locate driver-related exploits:

searchsploit -w "Windows driver" | grep -i "CVE"

GitHub’s advanced code search can be leveraged to find public PoCs that reference a specific driver filename or hash. Example query:

gh api -H "Accept: application/vnd.github.v3+json" "/search/code?q=acpi.sys+extension:cpp+repo:exploitdb/exploits"

Automated scanning scripts (Python/PowerShell) to locate known vulnerable drivers on a host

Below is a production-ready PowerShell module you can drop into your internal red-team toolkit.

# Module: Find-VulnerableDriver.psm1
function Get-DriverHash { param([string]$Path) $bytes = [System.IO.File]::ReadAllBytes($Path) $sha256 = [System.Security.Cryptography.SHA256]::Create() $hash = $sha256.ComputeHash($bytes) return ($hash | ForEach-Object { $_.ToString('x2') }) -join ''
}

function Find-VulnerableDrivers { param( [string]$DriverFolder = 'C:\Windows\System32\drivers', [string]$HashCsv = 'C:\Temp\driver_hashes.csv' ) $hashMap = @{} Import-Csv $HashCsv | ForEach-Object { $hashMap[$_.SHA256.ToLower()] = $_.CVE } Get-ChildItem $DriverFolder -Filter *.sys | ForEach-Object { $hash = Get-DriverHash -Path $_.FullName if ($hashMap.ContainsKey($hash)) { [pscustomobject]@{ Driver = $_.Name Path = $_.FullName SHA256 = $hash CVE = $hashMap[$hash] Signed = (Get-AuthenticodeSignature $_.FullName).Status } } }
}

Export-ModuleMember -Function Find-VulnerableDrivers

Usage:

Import-Module .\Find-VulnerableDriver.psm1
Find-VulnerableDrivers -HashCsv .\known_driver_hashes.csv | Format-Table -AutoSize

The module can be scheduled with Task Scheduler or integrated into a larger post-exploitation framework.

Identifying unsigned or outdated drivers that are prime candidates for exploitation

Even without a known CVE, unsigned or stale drivers are high-value targets.

Unsigned Driver Detection

Get-ChildItem C:\Windows\System32\drivers\*.sys | Where-Object { (Get-AuthenticodeSignature $_.FullName).Status -ne 'Valid' } | Select-Object FullName, @{N='SignatureStatus';E={(Get-AuthenticodeSignature $_.FullName).Status}}

System administrators often overlook unsigned drivers because they are required for legacy hardware. Attackers can replace a benign unsigned driver with a malicious one and avoid signature checks.

Outdated Driver Identification

Cross-reference driver version numbers against the vendor's latest release. Many vendors expose a JSON feed; for example, Intel publishes driver metadata at A quick PowerShell snippet:

$intelFeed = Invoke-RestMethod '
$installed = Get-Item 'C:\Windows\System32\drivers\*intel*.sys' | Select-Object Name, Version
foreach ($drv in $installed) { $latest = $intelFeed | Where-Object { $_.FileName -like "*$($drv.Name)*" } | Sort-Object ReleaseDate -Descending | Select-Object -First 1 if ($latest.Version -ne $drv.Version) { Write-Host "[!] $($drv.Name) is outdated. Installed: $($drv.Version) Latest: $($latest.Version)" }
}

Outdated drivers often lack patches for privilege-escalation bugs discovered years after the driver was shipped.

Practical Examples

Below we walk through a realistic red-team engagement on a Windows 10 workstation.

Scenario: Lateral movement via a vulnerable USB driver

  1. Enumerate drivers: Run driverquery /v /fo csv > C:\Temp\drivers.csv.
  2. Extract hashes: Use the PowerShell module from the previous section to produce driver_hashes.csv.
  3. Cross-reference: The script flags usbser.sys with SHA-256 abcd1234… matching CVE-2022-26923 (privilege escalation).
  4. Exploit: Deploy a known PoC (available on Exploit-DB) that overwrites a function pointer in the vulnerable driver, achieving SYSTEM.
  5. Post-exploitation: Use the SYSTEM token to dump LSASS, extract credentials, and pivot further.

This chain showcases why driver enumeration is often the first step in a kernel-mode attack.

Tools & Commands

  • driverquery - native driver list.
  • dism /online /get-drivers - installed driver catalog.
  • PowerShell Get-ItemProperty - registry based enumeration.
  • Sysinternals Autoruns - boot-time driver view.
  • Sysinternals Process Explorer - in-memory driver view.
  • Sysinternals Sigcheck - signature and version extraction.
  • Visual Studio dumpbin - binary header inspection.
  • Python requests + hashlib - automated hash lookup.
  • PowerShell module Find-VulnerableDrivers - on-host scanning.

Defense & Mitigation

Understanding the attack path enables solid defenses:

  1. Enforce Driver Signing: Deploy Secure Boot and set Device Installation Restrictions via Group Policy to block unsigned drivers.
  2. Patch Management: Use WSUS or SCCM to keep drivers up to date. Pay special attention to third-party hardware (e.g., printers, NICs).
  3. Driver Hardening: Enable Code Integrity policies that whitelist only known driver hashes (via CI.dll policies).
  4. Monitoring: Deploy Sysmon with a rule that logs DriverLoad events (Event ID 6). Alert on unknown hashes.
  5. Least-Privilege Services: Run services that interact with hardware under restricted accounts, limiting the damage if a driver is compromised.

Common Mistakes

  • Relying solely on driver name: Attackers often rename malicious drivers to mimic legitimate ones. Always verify hash and signature.
  • Ignoring unsigned drivers: Many teams focus on signed drivers only; unsigned drivers are a gold mine for privilege escalation.
  • Skipping version comparison: A driver may be signed but an older version with a known CVE. Cross-reference version numbers.
  • Forgetting 32-bit vs 64-bit paths: On 64-bit Windows, drivers can reside in C:\Windows\SysWOW64\drivers. Scan both locations.
  • Overlooking virtualized environments: Hyper-V and VMWare provide virtual drivers that may have distinct vulnerabilities.

Real-World Impact

Driver vulnerabilities have been weaponized in high-profile incidents:

  • PrintNightmare (CVE-2021-34527): Exploited a Windows Print Spooler driver loading flaw to achieve remote code execution.
  • BlueKeep (CVE-2019-0708): While not a driver, it demonstrated how a single vulnerable component can cascade into massive wormable exploits.
  • Stuxnet: Leveraged signed but vulnerable drivers to hide its presence and manipulate PLCs.

My experience in red-team engagements shows that a quick driver hash scan often reveals a “low-hanging fruit” that bypasses application-level defenses. Organizations that enforce strict driver whitelisting rarely fall victim to these attacks.

Practice Exercises

  1. On a Windows 10 VM, run driverquery /v /fo csv and export the list. Identify any driver whose Signed column says No.
  2. Using the PowerShell Find-VulnerableDrivers module, create a CSV of all drivers and manually verify one hash against cvedetails.com.
  3. Write a Python script that pulls the latest Intel driver JSON feed, compares it to installed Intel drivers, and reports outdated versions.
  4. Configure Sysmon to log driver loads. Simulate a malicious driver copy (rename a benign driver) and verify that an alert fires.
  5. Apply a Code Integrity policy that only allows drivers whose hashes are listed in a whitelist file. Test by attempting to load an unsigned test driver.

Further Reading

  • Microsoft Docs - Windows Driver Development
  • Sysinternals - Process Explorer & Autoruns
  • MITRE ATT&CK - Exploitation for Privilege Escalation (T1068)
  • Black Hat 2023 - “Kernel Driver Abuse - The New Frontier” (presentation slides)
  • Exploit-DB - Search for “Windows driver” PoCs

Summary

Finding vulnerable drivers is a systematic process that begins with enumeration (built-in tools, Sysinternals), proceeds through metadata extraction (sigcheck, dumpbin), and culminates in hash-based correlation with public vulnerability feeds. By automating these steps and integrating them into a broader detection pipeline, security teams can surface high-impact attack surfaces before adversaries do. Remember: unsigned, outdated, or poorly signed drivers are the most promising footholds-hardening them dramatically raises the bar for kernel-mode exploitation.