Threat Analysis Unit

Bring Your Own Backdoor: How Vulnerable Drivers Let Hackers In

Bring Your Own Vulnerable Driver (BYOVD) techniques are not new; they can be traced back at least as far as 2012 and the Shamoon wiper that targeted Saudi Aramco. The attack used RawDisk driver, which could manipulate hard drives from user space without any special permissions. This access enabled the malicious actor to erase data at such a large scale, the company was forced to replace practically all hard drives on its network. The Shamoon/RawDisk driver attack did not use a vulnerability in the driver, it used the driver for the purpose intended, but by a person or group with unscrupulous objectives. In the case of Shamoon, the driver itself could be considered a vulnerability, and in some ways, this is the case with almost all vulnerabilities. The misuse of well-intended segments of code necessary for functionality results in calamity.  

This paper provides an overview of common driver vulnerabilities for currently supported versions of Windows running on x86-64 architecture. Some driver principles and concepts can be applied across operating systems, but for brevity the scope is limited. It is intended as a high-level overview introduction to the topic of driver vulnerabilities in Windows.  

What is a driver? 

At an exceedingly high level, drivers are software that allows the operating system to interact with all the different physical parts of a computer. Each physical component of a computer is commonly referred to as a device, which is why drivers are commonly referred to as device drivers. This differentiates them from purely software drivers which are low-level programs that act as filters or perform some other low-level function. It is normal for each device on the computer to have at least one driver. For example, in high-performance computing, it is common to have a separate card or piece of hardware for processing video (video card). In general, the manufacturer of the video card will write a driver or multiple drivers, at least one for each supported operating system. These drivers facilitate communication between the physical device and the operating system and enable full use of the specialized hardware. Since device drivers act as a bridge between the operating system and physical hardware, it follows that they require intimate access to the guarded components of the operating system that not all applications are allowed to use. For this reason, they are an attractive option for dishonest cyber actors whose goal is to implant undetectable, difficult-to-remove malicious code on a system. 

Admittedly, this is an oversimplification but provides a baseline for understanding the techniques that follow. For a more complete explanation of Windows drivers see Microsoft’s, “What is a driver?”   

What makes a driver vulnerable? 

Since drivers are software, they are susceptible to all the vulnerabilities of software in general, but the below provides a high-level overview of the most common vulnerabilities specific to drivers. In most cases, some combination or variation of these techniques is used for driver exploitation. Like in other instances of software exploitation, many of these constructs which are manipulated are also required for normal use in the operation of a system, and when abused, these same constructs can result in behaviors not intended by the original authors. 

Function Calls from Model Specific Registers (MSRs) 

Model-specific registers (MSRs) are a set of special-purpose data holding places on most computer processors that are available to drivers that are used for debugging, performance monitoring, and enabling/disabling CPU/GPU features. One common use of these registers is to collect environmental measurements related to the driver’s hardware, for example, temperature or voltage. These data points can be essential for the device to function properly.  

A closer look at how MSRs operate reveals the problem. Within the set of MSRs one register is of particular interest, IA32_LSTAR (IA-32e Mode System Call Target Address R/W), commonly referred to as the shortened LSTAR. This register allows drivers to make system calls. Normal operation dictates that the driver places the address of the system call it wants to make in the LSTAR register, and then signals for it to be called. A system call is a function or action that triggers something to happen in the operating system itself; these types of operations are considered privileged and only trusted software is allowed to use them. Since drivers are trusted, this is not a problem. However, in the case of a basic MSR attack the address of the system call in LSTAR is replaced with the address of the non-trusted code. Now when the driver triggers what it thinks is a system call, the imposter code is executed as if it were a trusted part of the operating system.  

Techniques that involve overwriting the LSTAR register are no longer quite as straightforward as presented. Microsoft has implemented security measures to make abuse more complicated, but the basics of the technique remain the same. The difference is that it now requires multiple exploits to place the untrusted code in memory, change LSTAR, and subsequently trigger the system call. 

Microsoft’s Mitigations 
Supervisory Mode Execution Prevention (SMEP) – Prevents the kernel from executing code in user pages.
Virtualization-Based Security (VBS) – Restricts access to MSRs and reviews MSR events (successor of PatchGuard) 

Notable Example:  WannaCrypt 

Unprotected IOCTL Requests 

IOCTL Requests are a property and feature of drivers that purposefully allow untrusted or user-mode programs to interact directly with the underlying trusted parts of a driver’s code and subsequently the operating system. For example, when installing a new peripheral device like a video card, there are usually multiple components. One will be a driver for the video card itself and another will be a user interface for tuning how video is processed and displayed. The driver is trusted, and the user interface application is not. Out of necessity, there are predetermined user interactions within the video card user application that can trigger events that run code in the trusted driver. Vulnerabilities occur when the communication between the untrusted and trusted is taken advantage of by a third party.  

Drivers that contain this type of vulnerability share a commonality, accessible IOCTL codes or commands. IOCTL commands are 32-bit values, represented in hex (example: 0x12345678), which can be called from untrusted parts of the operating system to execute code in the trusted part. These commands are defined by the author of the driver and can execute the most protected operating system calls. For example, a video card application can send hardware configuration changes to increase how quickly data is processed. To accomplish this the untrusted user application must be able to communicate with the video card itself. This is possible because the driver contains a predefined IOCTL Request that the user application can issue to it. The order of events is, the OS video card application connects to the device driver, sometimes authenticates itself, and sends the command along with any compulsory data (the new settings). Vulnerabilities arise when access to these IOCTL operations is not adequately restricted. 

One example of this type of vulnerability is when an unsecured IOCTL Request can perform arbitrary memory writes. For example, there are IOCTL Requests that result in calls to MmMapIOSpace, which maps physical to virtual addresses. Two examples of this are CVE-2020-15368 and CVE-2020-15481, in both cases unprotected IOCTL commands result in the ability to run untrusted code by writing it directly to arbitrary physical memory. 

The scope of IOCTL Request vulnerabilities is much larger and goes beyond writing to arbitrary memory and extends to almost any operation available in the operating system. What bad actors can accomplish with this type of vulnerability is completely dependent on what the driver has defined in IOCTLs, and how security is implemented to prevent unintended use. For this reason, this type of vulnerability is particularly troubling and difficult to defend against, and in an unscientific randomized sampling of vulnerable drivers, it was also the most common.  

Microsoft’s Mitigations
Security Recommendations for I/O Control Codes
Applying Security Descriptors on the Device Object 

Notable Examples
Lazarus Group’s Rootkit
InvisiMole
Slingshot
BlackByte 

Plug-and-Play Driver Vulnerabilities 

It is great when things “just work,” which is probably why Windows introduced Plugin and Play (PnP) device drivers. This feature of Windows allows the operating system to seamlessly adjust to hardware changes with minimal user interaction. A common example where this comes into play is when a peripheral device like a keyboard is plugged into a computer while Windows is already running. Windows recognizes the new hardware and, in most cases, makes it available for use very quickly. This ease of use can lead to a false sense of security. PnP drivers are still drivers and susceptible to all the vulnerabilities discussed and unfortunately more.  

The convenience that PnP offers is delivered by additional software layers in both trusted and untrusted parts of the operating system. These allow Windows to recognize hardware changes, allocate memory on behalf of a device, load a driver, and provide some basic components needed by most drivers. To seamlessly install a PnP device, the OS must grant some level of trust to it at some point during the installation, and this is where most PnP vulnerabilities arise and lead to privilege escalation. 

From an attacker’s perspective, PnP drivers are beneficial because they can be loaded and unloaded from untrusted user mode with no user interaction. Additionally, you may think this type of vulnerability requires physical access, but this is not the case. Physical access is not required. Generally, vulnerabilities in PnP device drivers provide privilege escalation, which opens the door for other attacks. 

Note: PnP Drivers should not be confused with UPnP (Universal Plug and Play), which is a protocol for dynamic network device discovery. 

Possible Mitigation 
DisableCoInstallers Registry Key 

Notable Example 

PnP Mouse Privilege Escalation
CVE-2020-1048 – Print Spooler
CVE-2021-1675, CVE-2021-34527 – Print Nightmare 

Firmware Update Vulnerabilities 

The introduction provided a definition of a driver and explained the difference between a device driver, which provides hardware-OS communication, and a software driver, which acts more like a filter for the device drivers. There is another type of driver called a firmware driver. Like a device driver it is for a single device, but instead of residing in and facilitating communication with the operating system; it provides instructions to be stored on the hardware itself. This includes all the definitions and the logic necessary for the hardware to operate. Firmware drivers are used to load code onto a specialized chip located on the hardware itself.  This code is usually placed there by the manufacturer, and for the most part, is not meant to be changed. For this reason, it is good security practice for the firmware to be write-protected, however, sometimes a situation arises where an update is required. This could be a logic error or other oversight that leaves firmware vulnerable to malicious actors. 

Firmware update vulnerabilities do not usually occur in the firmware driver itself but in the lack of access control dictating its use. In malicious firmware updates the firmware driver replaces the manufacturer-approved code for performing logic on the actual hardware with nontrusted code, and once complete is close to undetectable. While this type of vulnerability is certainly found on Windows devices, most notably printers. It is far more prevalent on IoT (Internet of Things) devices. IoT devices consist of non-traditional end-user systems that are connected to the internet, for example, cameras, lightbulbs, thermostats, kitchen appliances, and more. 

Microsoft Mitigation
Firmware Attack Surface Reduction (FASR)
Update device firmware using Windows Update 

Notable example
CVE-2022-21134
FutureSmart Printer Firmware 

UEFI and Boot Loader Vulnerabilities 

UEFI (Unified Extensible Firmware Interface) is the modern version of BIOS (Basic Input/Output System), both of which enable a computer’s hardware to boot the operating system. One benefit of UEFI over BIOS is that it provides the option for secure boot, which introduced a security feature that ensures the integrity of code before it executes. UEFI secure boot should only allow code with valid credentials to run by enforcing authenticity through PKI (Public Key Infrastructure) and Certificates. For this reason, the UEFI class of driver vulnerability usually involves disabling or bypassing secure boot to run unendorsed code.  

UEFI attacks are possible even when the firmware is not left unprotected. VMware Carbon Black’s own Takahiro Haruyama has done extensive research into this type of attack, see his blog post, “Detecting UEFI Bookits in the Wild.” 

Microsoft Mitigation 

Secure the Windows boot process 

Notable Example
From ESET –  When “secure” isn’t secure at all: Highimpact UEFI vulnerabilities discovered in Lenovo consumer laptops 

Conclusion 

This has been an introduction to driver vulnerabilities and is not meant to be all-encompassing of all possible driver vulnerabilities. For example, there are additional MSR manipulation vulnerabilities, which could have been covered but were left out. These involve manipulating MSR register values, however, the depth of understanding of MSR registers needed to make a section like that easily comprehensible went beyond the scope of this brief introduction. Additionally, Microsoft’s virtualization-based security has made MSR attacks far less prevalent.  

Network security professionals everywhere spend an untold number of hours working to patch vulnerabilities in their networks as they are discovered. This is a monumental task considering the amount of hardware and software on modern systems. It is no wonder, given all the hours of demanding work devoted to this when an actor brings their own vulnerable driver into a fully patched network, security professionals cringe. Not to mention that many of these so-called vulnerable drivers are signed; why are they not safe? This overview of driver vulnerabilities has attempted to provide some insight into this question and provide additional resources to further enrich one’s own knowledge of the topic.  

Protections 

Carbon Black offers multiple out-of-the-box protections against Bring Your Own Vulnerable Driver attacks. The simplest method of protection provided is alerting on or prohibiting known abused drivers in a network. As soon as a vulnerable driver is disclosed, it is added to a known malware list independent of the validity of the file signature. Secondly, a universal requirement of BYOVD attacks is that the vulnerable driver must be installed in the operating system. In the case of BYOVD attacks, the steps required to move the vulnerable driver to the targeted system and then install it are very similar to well-known cyber-attack chains. 

One strength of the Carbon Black line of products is the unparalleled ability to identify, alert, and block cyber-attack chains. Additionally, it’s endpoint software tracks applications that load data or code into memory, which includes drivers, so any driver loaded into memory will result in an alert or potential block depending on the policy. Finally, Carbon Black products have the capacity to alert on or block the installation of drivers by unknown applications, which stops BYOVD attacks before they progress. All of these individual protections work together to provide a comprehensive defensive strategy that guards against malware even when it uses signed drivers.