VU.LS
vu.ls blog
vu.ls blog

BYOVD Protection Is A Lie

Overview

For some reason, there’s a collective hallucination that Bring Your Own Vulnerable Driver (BYOVD) protection is a thing that’s achievable, and something that you should do. Let’s look into how this happened…

Patient zero: Microsoft

In 2020, Microsoft advertised Secured-core PCs, and included a curious statement:

Defending against these types of threats—whether those that live off the land by using what’s already on the machine or those that bring in vulnerable drivers as part of their attack chain—requires a fresh approach to security, one that combines threat defense on multiple levels: silicon, operating system, and cloud.

Secured-core PCs enable the full set of HVCI-provided exploit mitigations, but let’vs look at the specifically troublesome part of that statement:

those that bring in vulnerable drivers

The message being conveyed is: If you buy a Secured-core PC, you can protect against attackers that bring their own vulnerable drivers. Let’s see if this statement is grounded in reality.

Why drivers?

Why do attackers use drivers? There are several things that a driver can accomplish that an attacker might want, including (list courtesy Rapid7):

In some cases, drivers that allow these things to happen may already be present on a system that is being attacked. If the driver is vulnerable, these actions may not even require admin privileges to pull off.

Bringing vulnerable drivers?

A vulnerable driver being present on a system can make an attacker’s life easier. But what about this “BYOVD” thing that I keep hearing about? Attackers are doing this in the wild, so it’s something we should worry about, right? Let’s look at some facts about the Windows driver world and how it affects attackers:

  1. In order to bring a driver, an attacker must have admin privileges.

  2. Administrator-to-kernel is not a security boundary.

    Administrator to Kernel
Administrative processes and users are considered part of the Trusted Computing Base (TCB) for Windows and are therefore not strong isolated from the kernel boundary. Administrators are in control of the security of a device and can disable security features, uninstall security updates, and perform other actions that make kernel isolation ineffective. This includes actions which require Administrator permissions like registry tampering with HKEY_LOCAL_MACHINE and any attack where the attacker has Local or Domain Administrator access.

To clarify “Administrator-to-kernel is not a security boundary”, imagine that you have two drivers:

Driver A would be considered vulnerable because it allows non-administrator users to modify kernel memory. On the other hand Driver B is not considered vulnerable because it requires a user with admin privileges to take action. Because “Administrator to Kernel” is not a security boundary, abuse of the driver would not cross any security boundary, and therefore there is no vulnerability at play.

Attackers are indeed bringing vulnerable drivers in attacks occurring in the wild. Now, think about whether the “vulnerable” part of that statement matters. Remember to avoid logical fallacies in the process.

  1. A vulnerable driver allows non-admin users to do dangerous things.

  2. An attacker bringing their own driver already has admin privileges.

Given this, what does an attacker get out of bringing a vulnerable driver to their game? If I were an attacker, I’d probably choose a driver that was not vulnerable, just to stay under the radar a touch more, as opposed to setting off alarm bells by using a driver that is known to be vulnerable.

Ways to accomplish goals without using a vulnerable driver.

For certain activities, an admin-privileged attacker can simply bring a non-vulnerable driver to achieve their goal.

Simple actions

If the goal is to kill a protected EDR process, an attacker can simply use a driver that exposes ZwTerminateProcess to admin users. If the driver only exposes ZwTerminateProcess to admin users, then it would not be considered a vulnerable driver. However, it’s allowing an admin-privileged attacker to do something that might be useful to them.

Loading unsigned or uncertified drivers

An example ZwTerminateProcess driver that isn’t vulnerable is interesting, but the holy grail of proving that BYOVD protection is a lie would be to show that an admin-privileged attacker can load an unsigned or invalid-signed driver, or failing that, showing that an attacker can load a driver that has a valid signature but has not been approved by Microsoft. This would open up the attack to be able to universally leverage anything that a driver can do.

KDU

The KDU exploit is a universal driver exploit that can leverage a driver that has a kernel memory read/write primitive to achieve a number of useful goals. Including the ability to disable Windows Driver Signature Enforcement (DSE). While the drivers that KDU comes with are generally considered “vulnerable” in that non-admin users can leverage their functionality, it’s important to realize that a non-vulnerable driver with the same read-write privileges can be used to achieve the same goal. And because KDU requires admin privileges to run, the use of a vulnerable driver is even less relevant.

For example, here we see KDU using rtcore64.sys to set the CiVariableAddress value using a read/write primitive, which disables the driver signature-checking enforcement in Windows.

Screenshot of a driver without a valid signature being loaded, yet "Microsoft Vulnerable Driver Blocklist" is enabled

KDU and HVCI’s KDP

If you attempt to disable DSE on an HVCI-enabled Windows system, you’ll get a different, unpleasant result:

BSOD: ATTEMPTED WRITE TO READONLY MEMORY. What failed: Cl.dll

Why is this? It’s not actually HVCI itself that provides this protection (ATTEMPTED WRITE TO READONLY MEMORY), but rather it’s Kernel Data Protection (KDP) that provides the protection. A naive attempt to write to a protected kernel memory location will fail. And sometimes catastrophically (in a BSOD). Does this mean that an HVCI-enabled system will prevent an attacker from disabling the driver signature check?

KDP bypassing

The Microsoft article that introduces KDP makes a statement that is a clue to how its protections might be able to be bypassed:

KDP does not enforce how the virtual address range mapping a protected region is translated.

What this means is that while the original memory location might benefit from read-only memory permissions, an attacker can remap the memory by modifying the page table, which will result in the memory having read-write privileges. From Intel VT-rp - Part 1. remapping attack and HLAT:

Diagrem of how an attacker can perform remapping or page swapping to modify protcted data

Just like over time exploits were modified to take advantage of ROP to bypass the NX protection introduced by AMD, we can expect exploits like KDU to be eventually modified to take advantage of memory remapping to bypass protections added by KDP.

So that’s it? We’ve proved that BYOVD protection is a lie, right?

Timestamp forging

Cisco Talos published a blog post: https://blog.talosintelligence.com/old-certificate-new-signature/ , which describes a technique that is being used in the wild to skip the requirement that Windows drivers are approved by the Microsoft Developer Portal.

Developer Portal requirements

Microsoft states: Starting with Windows 10, version 1607, Windows will not load any new kernel-mode drivers which are not signed by the Dev Portal.

Note
Starting with Windows 10, version 1607, Windows will not load any new kernel-mode drivers which are not signed by the Dev Portal. To get your driver signed, first Register for the Windows Hardware Dev Center program. Note that an EV code signing certificate is required to establish a dashboard account.

The presumed goal here is to give a certain amount of control to Microsoft over Windows drivers. Drivers that are blatantly malicious or vulnerable might not get the approval from Microsoft, resulting in a driver that Windows will refuse to load by default.

But as the Talos blog post explains, the above policy seems to be an intended goal as opposed to a fact. Why? By playing games with modifying a cross-signing certificate’s date, Windows will treat the driver with the pre-1607 policy, which is to not require the Developer Portal signature.

This means that an attacker can load a malicious driver in Windows, as long as it has a valid signature, which can be accomplished by simply purchasing one, or by using a signing key that has been leaked, stolen, or otherwise made available to the attacker.

So there’s no need for a vulnerable driver when we can just use a malicious driver. That’s the final nail in the BYOVD protection coffin, right?

Changing Windows to use pre-1607 driver signing behavior

Sure, an attacker might play certificate games as outlined by the Talos blog post to get past the Developer Portal signing requirement. But since we’re talking about cases where the attacker is an admin (since they’re bringing a driver), even this is over-thinking things. Why? An admin user can simply tell Windows to use the pre-1607 behavior.

As outlined in https://www.geoffchappell.com/notes/security/whqlsettings/index.htm, Windows can be reverted to a configuration where it does not require drivers to be signed by the Microsoft Developer Portal by setting the UpgradedSystem and BootUpgradedSystem registry values.

How many nails does this BYOVD protection coffin need?

Protecting against BYOD

So you want to protect against BYOD? This is a laudable (yet achievable) goal. However, as with just about anything security-related, achieving this improvement comes at a cost of increased maintenance.

WDAC policies

Windows Defender Application Control (WDAC) can be used to control what applications and drivers Windows will allow to run. For example, the Microsoft recommended driver block rules policy that recent versions of Windows use to block vulnerable drivers is implemented as a WDAC policy.

Windows 11 screenshot of "Core isolation". "Microsoft Vulnerable Driver Blocklist" is circled.

This is a useful feature to prevent the presence of a vulnerable driver on a system before an attacker arrives. Note that this feature will not block an attacker that is in a position to attempt a BYOVD attack, though. Such an attacker already has admin privileges by nature of bringing their own driver, and an admin user of a Windows system can simply modify or disable WDAC settings to their liking.

Signed WDAC policies

WDAC settings can be made tamper resistant by using signed policies. Part of the deployment for signed WDAC policies is to deploy the signed policy into the system’s EFI partition. This type of WDAC deployment is tamper resistant by way of two behaviors:

  1. If the WDAC policy file in the Windows filesystem is modified or removed, Windows will simply use the copy of the policy in the EFI partition.

  2. If the WDAC policy file in the EFI partition is modified or removed, SecureBoot will fail to boot Windows.

If a Windows system is to be protected against BYOD attacks, a WDAC policy must be created that only allows the set of drivers that have been approved for use on a system. That is, the WDAC policy must provide as specific “allow list” of drivers that may be loaded. Note that the Microsoft recommended driver block rules list includes an “Allow All” rule, so therefore this list by itself is not sufficient to protect against BYOD attacks. From the Microsoft recommended driver block rules list page:

Important
The policy listed below contains Allow All rules. If your version of Windows supports WDAC multiple policies, we recommend deploying this policy alongside any existing WDAC policies. If you do plan to merge this policy with another policy, you may need to remove the Allow All rules before merging it if the other policy applies an explicit allow list. For more information, see Create a WDAC Deny Policy.

The WDAC policy to specify what drivers are allowed to be loaded must also be signed before deployment to both Windows and the EFI partition. Once this signed WDAC deployment is complete, Windows should prevent an attacker from being able to bring their own driver.

Conclusion

Years ago, Microsoft mentioned that their Secured-core PCs will protect against BYOVD attacks. And as time has passed, this hallucination has propagated to the masses. It’s simply not currently a viable goal to aim to block BYOVD attacks, however. Preventing attackers from loading arbitrary drivers is a reasonable goal, which can be accomplished with the combination of SecureBoot and a signed WDAC policy. Without this combination of protections, it should be assumed that an admin-privileged attacker can load whatever drivers they want.

Advertising BYOVD protection is disingenuous, as any attacker that’s bringing a driver already has admin privileges, and as such they don’t need to bother with using a vulnerable driver.

Secured-core PCs are a good idea from a security perspective, with their HVCI and associated KDP features. However even Secured-core PCs cannot truthfully advertise BYOD (note the lack of “V”) protection. BYOD protection can be accomplished by way of a signed WDAC policy that is maintained and deployed to systems that are to be protected. Such protection is not deployed to the masses by way of them using a Secured-core PC that comes with standard Windows 11.