microsoft / CSS-Exchange

Exchange Server support tools and scripts
MIT License
1.21k stars 332 forks source link

[Issue] - Health Checker - Credential Guard Check Still Not Functioning As Expected #2069

Closed MilkyCGS closed 2 months ago

MilkyCGS commented 2 months ago

This was previously reported as issue 1867 and subsequently a fix was put in place. However, the script is still not detecting Credential Guard correctly.

The current script checks the SecurityServicesRunning array within "Get-CimInstance -ClassName Win32_DeviceGuard -Namespace root\Microsoft\Windows\DeviceGuard" to check that it is not equal to 0. This is not correct as the array can contain the numbers 0-4 depending on what security services are configured.

Credential Guard is enabled when a value of one exists in the array (whether alone or with other values) and so therefore the logic needs to be updated to search for that value and output as necessary.

dpaulson45 commented 2 months ago

@MilkyCGS do you have a way to configure Credential Guard this way?

MilkyCGS commented 2 months ago

In my tests so far, changing:

  if (-not ($credGuardUnknown)) {
        # CredentialGuardCimInstance is an array type and not sure if we can have multiple here, so just going to loop thru and handle it this way.
        $credGuardRunning = $null -ne ($osInformation.CredentialGuardCimInstance | Where-Object { $_ -ne 0 })
    }

    $displayValue = $credentialGuardValue = $osInformation.RegistryValues.CredentialGuard -ne 0 -or $credGuardRunning
    $displayWriteType = "Grey"

To:

  if (-not ($credGuardUnknown)) {
        # CredentialGuardCimInstance is an array type and not sure if we can have multiple here, so just going to loop thru and handle it this way.
        $credGuardRunning = $null -ne ($osInformation.CredentialGuardCimInstance | Where-Object { $_ -eq 1 })
    }

    $displayValue = $credentialGuardValue = $osInformation.RegistryValues.CredentialGuard -eq 1 -or $credGuardRunning
    $displayWriteType = "Grey"

Appears to work, but someone much better than me in PowerShell would need to confirm!

dpaulson45 commented 2 months ago

I believe that should work. Do you have the documentation that supports that CredentialGuard is only enabled with the value of 1?

MilkyCGS commented 2 months ago

Yes, it looks like there is a conflict in the MS documentation. The below link appears to be what the current script is based on:

https://learn.microsoft.com/en-us/windows/security/identity-protection/credential-guard/configure?tabs=gpo#powershell

This is incorrect, as the array can contain any numbers from 0-4. This is documented in the wider virtualisation security document here:

https://learn.microsoft.com/en-us/windows/security/hardware-security/enable-virtualization-based-protection-of-code-integrity#securityservicesrunning

dpaulson45 commented 2 months ago

Okay, so this explains the value from the WMI command that I can change that. However, the registry key still looks like a value of 2 still has Credential Guard enabled without lock. So, I think we still need to keep $osInformation.RegistryValues.CredentialGuard -ne 0

https://learn.microsoft.com/en-us/windows/security/identity-protection/credential-guard/configure?tabs=reg#enable-credential-guard

image

MilkyCGS commented 2 months ago

Yes, I had overlooked that the registry check used different values. That should stay as not equal to 0. So the only change necessary is to the WMI check. I've just ran through this in testing and the results from both WMI and registry support it.

dpaulson45 commented 2 months ago

Created the PR, once approved it will be in the next release of CSS Exchange.