Enumerating Endpoint Mitigations

Modern versions of Windows include a number of security features that aim to make the operating system more resistant to attack. This article is looking at how we can determine which of these features are enabled.


Security Technologies

Virtualization-Based Security (VBS) uses the Microsoft Hyper-V hypervisor to create an isolated execution environment known as Virtual Trust Level 1 (VTL1). This environment is separated from the normal Windows operating system, which runs in VTL0, allowing security-sensitive code and data to be protected from compromise even if the OS kernel is attacked.

Windows Device Guard builds on VBS to provide several platform security features, including:

Credential Guard
Protects credential material by isolating the Local Security Authority Subsystem Service (LSASS) in a VTL1 process called LSA Isolated (LSAISO). This prevents direct access to credential memory from the normal OS.

Hypervisor-Protected Code Integrity (HVCI), also known as Memory Integrity
Enforces kernel-mode code integrity using the hypervisor, preventing untrusted or tampered code from executing in the Windows kernel.

When HVCI is enabled, Windows blocks:

  • Unsigned kernel-mode drivers
  • Test-signed drivers
  • Cross-signed (legacy) drivers
  • Kernel code that is modified at runtime

In addition to HVCI’s code-integrity enforcement, Windows also maintains a Vulnerable Driver Blocklist, which prevents known exploitable but properly signed drivers from loading. This blocklist is enabled and managed separately from HVCI.

Together, these protections significantly reduce kernel attack surface:

  • Credential Guard prevents credential theft using traditional tools such as Mimikatz by isolating LSASS in VTL1.
  • HVCI combined with the Vulnerable Driver Blocklist provides strong defenses against Bring Your Own Vulnerable Driver (BYOVD) attacks by blocking both unsigned and known-bad signed drivers.
  • Tamper Protection ensures that these defenses remain enabled and resistant to local attempts to disable or bypass them.

Credential Guard typically relies on Secure Boot, a UEFI firmware security feature that enforces a chain of trust during system startup by allowing only cryptographically signed and trusted boot components to execute. Secure Boot ensures that the hypervisor and VBS are launched in a trusted state, strengthening all protections built on top of them.


Enumerating Security Technologies

Knowing which protection mechanisms are enabled is essential to bypassing them in the most efficient manner. The below C# code enumerates the following items using a combination of WMI and registry based checks.

  • Virtualisation Based Security status
  • Credential Guard
  • HVCI (Memory Integrity)
  • Tamper Protection
  • Vulnerable Driver Blocklist status

To compile, the code will require reference to the System.Management assembly. To add this, right click on the project > Assemblies > Framework > Enable System.Management.

using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Management;

class Program
{
    static void Main()
    {
        Console.OutputEncoding = System.Text.Encoding.Unicode;

        DeviceGuardAndHVCI();
        TamperProtectionStatus();
        VulnerableDriverBlocklistStatus();

    }

    static void DeviceGuardAndHVCI()
    {
        Console.WriteLine("\n[Device Guard]");

        using (var searcher = new ManagementObjectSearcher(
            @"ROOT\Microsoft\Windows\DeviceGuard",
            "SELECT * FROM Win32_DeviceGuard"))
        {
            foreach (ManagementObject dg in searcher.Get())
            {
                uint vbsStatus = dg["VirtualizationBasedSecurityStatus"] != null
                    ? (uint)dg["VirtualizationBasedSecurityStatus"]
                    : 0;

                Console.WriteLine("VBS Status: " + DescribeVbsStatus(vbsStatus));

                uint[] configured = dg["SecurityServicesConfigured"] as uint[] ?? Array.Empty<uint>();

                bool credGuardConfigured = configured.Contains(1u);
                bool hvciConfigured = configured.Contains(2u);


                bool lsaIsolated = IsLsaIsolated();
                bool lsaisoRunning = IsLsaisoRunning();

                bool credGuardRunning =
                    vbsStatus == 2 &&
                    credGuardConfigured &&
                    (lsaIsolated || lsaisoRunning);

                bool hvciRunning =
                    vbsStatus == 2 && hvciConfigured;

                Console.WriteLine("Credential Guard: " +
                    (credGuardRunning ? "Enabled" : "Disabled"));

                Console.WriteLine("Memory Integrity (HVCI): " +
                    (hvciRunning ? "Enabled" : "Disabled"));

                Console.WriteLine("Configured Services: " +
                    DescribeServices(configured));
            }
        }
    }


    static bool IsLsaisoRunning()
    {
        try
        {
            using (var searcher = new ManagementObjectSearcher(
                "SELECT Name FROM Win32_Process WHERE Name='lsaiso.exe'"))
            {
                return searcher.Get().Count > 0;
            }
        }
        catch
        {
            return false;
        }
    }


    static bool IsLsaIsolated()
    {
        try
        {
            using (var lsa = Registry.LocalMachine.OpenSubKey(
                @"SYSTEM\CurrentControlSet\Control\Lsa"))
            {
                int flags = Convert.ToInt32(lsa?.GetValue("LsaCfgFlags") ?? 0);
                return flags > 0;
            }
        }
        catch
        {
            return false;
        }
    }


    static string DescribeVbsStatus(uint status)
    {
        switch (status)
        {
            case 0: return "Disabled";
            case 1: return "Enabled (Not Running)";
            case 2: return "Enabled";
            default: return "Unknown (" + status + ")";
        }
    }

    static string DescribeService(uint id)
    {
        switch (id)
        {
            case 1: return "Credential Guard";
            case 2: return "HVCI (Memory Integrity)";
            case 3: return "System Guard";
            case 5: return "Kernel-mode Hardware-enforced Stack Protection";
            default: return "Unknown (" + id + ")";
        }
    }


    static string DescribeServices(object value)
    {
        uint[] arr = value as uint[];
        if (arr != null && arr.Length > 0)
        {
            List<string> names = new List<string>();
            foreach (uint id in arr)
            {
                names.Add(DescribeService(id));
            }
            return string.Join(", ", names);
        }
        return "None";
    }

    static void TamperProtectionStatus()
    {
        Console.WriteLine("\n[Tamper Protection]");

        try
        {
            using (var searcher = new ManagementObjectSearcher(
                @"ROOT\Microsoft\Windows\Defender",
                "SELECT IsTamperProtected FROM MSFT_MpComputerStatus"))
            {
                foreach (ManagementObject obj in searcher.Get())
                {
                    bool enabled = obj["IsTamperProtected"] != null &&
                                   (bool)obj["IsTamperProtected"];

                    Console.WriteLine("Tamper Protection: " +
                        (enabled ? "Enabled" : "Disabled"));
                    return;
                }
            }

            Console.WriteLine("Tamper Protection: Not available");
        }
        catch
        {
            Console.WriteLine("Tamper Protection: Unable to query (requires Defender / permissions)");
        }
    }

    static void VulnerableDriverBlocklistStatus()
    {
        Console.WriteLine("\n[Vulnerable Driver Blocklist]");

        bool enabled = false;

        try
        {
            using (var searcher = new ManagementObjectSearcher(
                @"ROOT\Microsoft\Windows\Defender",
                "SELECT VulnerableDriverBlocklistEnabled FROM MSFT_MpComputerStatus"))
            {
                foreach (ManagementObject obj in searcher.Get())
                {
                    object val = obj["VulnerableDriverBlocklistEnabled"];
                    if (val != null)
                        enabled = (bool)val;
                }
            }
        }
        catch
        {
            enabled = IsVulnerableDriverBlocklistConfigured();
        }

        Console.WriteLine("Status: " + (enabled ? "Enabled" : "Disabled"));
    }

    static bool IsVulnerableDriverBlocklistConfigured()
    {
        try
        {
            using (var key = Registry.LocalMachine.OpenSubKey(
                @"SYSTEM\CurrentControlSet\Control\CI\Config"))
            {
                if (key == null)
                    return false;

                object val = key.GetValue("VulnerableDriverBlocklistEnable");
                return val != null && Convert.ToInt32(val) == 1;
            }
        }
        catch
        {
            return false;
        }
    }

    static bool NamespaceExists(string ns)
    {
        try
        {
            using (var searcher = new ManagementObjectSearcher(@"ROOT", "SELECT * FROM __namespace"))
            {
                foreach (ManagementObject obj in searcher.Get())
                {
                    if (obj["Name"].ToString().Equals(ns, StringComparison.OrdinalIgnoreCase))
                        return true;
                }
            }
        }
        catch { }
        return false;
    }
}

Running the code, we can see credential guard & HVCI are enabled. Kernel-mode Hardware-forced Stack Protection is enabled, but the CPU I’m running this on does not support shadow stacks.

EnumMitigations.exe

[Device Guard]
VBS Status: Enabled
Credential Guard: Enabled
Memory Integrity (HVCI): Enabled
Configured Services: Credential Guard, HVCI (Memory Integrity), System Guard, Kernel-mode Hardware-enforced Stack Protection

[Tamper Protection]
Tamper Protection: Disabled

[Vulnerable Driver Blocklist]
Status: Enabled

In Conclusion

Most of the information we have programmatically determined can also be retrieved using msinfo.exe. However, our code can run without administrative privileges.