Skip to content

Instantly share code, notes, and snippets.

Created November 21, 2023 02:44
Show Gist options
  • Save MHaggis/8d6de45b883b338e47de08b3cb4c9819 to your computer and use it in GitHub Desktop.
Save MHaggis/8d6de45b883b338e47de08b3cb4c9819 to your computer and use it in GitHub Desktop.
Based on Trail of Bits HVCI LOLDrivers Check script - just outputs to csv
Compares the HVCI block list on the current system against the list of
vulnerable and malicious drivers from
Company: Trail of Bits
Author: Michael Lin
Contributors: Yarden Shafir
License: Apache 2
check_allowed_drivers.ps1 reports the drivers from which are allowed
by the current HVCI block list on the system.
Note: drivers which are allowed by the HVCI block list might still not load
on a system due to other reasons such as architecture incompatibility,
incorrect signature or EDR software.
Outputs a list of drivers not blocked by the HVCI policy in CSV format.
$loldrivers = Invoke-WebRequest -Uri | ConvertFrom-Json -AsHashTable
$cipolicypath = $env:TEMP + '\CIPolicyParser.ps1'
$recovered_policy_path = $env:TEMP + '\recovered_policy.xml'
Invoke-WebRequest -Uri -OutFile $cipolicypath
# CIPolicyParser is imcompatible with .NET Core so must be run in old powershell through Invoke-Command.
# save result of Invoke-Command into variable so it won't write output to console
$v = Invoke-Command -ScriptBlock { powershell {Import-Module ($env:TEMP + '\CIPolicyParser.ps1'); ConvertTo-CIPolicy -BinaryFilePath C:\Windows\System32\CodeIntegrity\driversipolicy.p7b -XmlFilePath ($env:TEMP + '\recovered_policy.xml')} }
[xml]$policy = Get-Content $recovered_policy_path
Remove-Item -Path $recovered_policy_path
Remove-Item -Path $cipolicypath
$file_rules = $policy.SiPolicy.FileRules
$signers = $policy.SiPolicy.Signers.Signer
$allowed = New-Object System.Collections.ArrayList
$not_allowed = New-Object System.Collections.ArrayList
function hasBlockedHash($driver){
foreach($hash in $file_rules.Deny.Hash){
if(($hash) -and (
($hash -eq $driver.Authentihash.SHA256) -or
($hash -eq $driver.Authentihash.SHA1) -or
($hash -eq $driver.Authentihash.MD5) -or
($hash -eq $driver.SHA256) -or
($hash -eq $driver.SHA1) -or
($hash -eq $driver.MD5)))
return $true
return $false
function hasBlockedSigner($driver){
$file_attrib = $file_rules.FileAttrib | Where-Object {$_.FileName -eq $driver.OriginalFilename}
foreach($signer in $signers){
$tbs = $signer.CertRoot.Value.ToLower()
if(($driver.Signatures.Certificates.TBS.MD5 -contains $tbs) -or
($driver.Signatures.Certificates.TBS.SHA1 -contains $tbs) -or
($driver.Signatures.Certificates.TBS.SHA256 -contains $tbs) -or
($driver.Signatures.Certificates.TBS.SHA384 -contains $tbs)){
$blocked_files = $signer.FileAttribRef
if(!$blocked_files -or ($blocked_files.RuleID -contains $file_attrib.ID)){
return $true
return $false
foreach ($driver in $loldrivers.KnownVulnerableSamples) {
$driverInfo = New-Object PSObject -Property @{
MD5 = $driver.MD5
SHA1 = $driver.SHA1
SHA256 = $driver.SHA256
Status = ""
if(hasBlockedHash $driver){
$driverInfo.Status = "Blocked"
$not_allowed.Add($driverInfo) | Out-Null
$file_max_version = ($file_rules.Deny | Where-Object {$_.FileName -eq $driver.OriginalFilename}).MaximumFileVersion
$version = (-split ($driver.FileVersion -replace ',\s*', '.'))[0]
if($file_max_version -and $version -and ([version]$version -le $file_max_version)){
$driverInfo.Status = "Blocked"
$not_allowed.Add($driverInfo) | Out-Null
if(hasBlockedSigner $driver){
$driverInfo.Status = "Blocked"
$not_allowed.Add($driverInfo) | Out-Null
$driverInfo.Status = "Allowed"
$allowed.Add($driverInfo) | Out-Null
$csvPath = ".\hvci_drivers.csv"
$allDrivers = $allowed + $not_allowed
$allDrivers | Export-Csv -Path $csvPath -NoTypeInformation
Write-Output ("Number of blocked drivers: {0}" -f $not_allowed.Count)
Write-Output ("Number of allowed drivers: {0}`n" -f $allowed.Count)
Write-Output "CSV file created at $csvPath"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment