-
-
Save nafai/e014e2b9600e1f7dc93d0999df4ff720 to your computer and use it in GitHub Desktop.
Parses signature data from the pk, kek, db, and dbx UEFI variables.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[CmdletBinding()]Param( | |
[Parameter(ParameterSetName = 'Filename')] | |
[string]$Filename, | |
[Parameter(ParameterSetName = 'Base64')] | |
[string]$Base64 | |
) | |
if (-NOT ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) | |
{ | |
Write-Error "Insufficient permissions to run this script. Open the PowerShell console as administrator and run this script again." -ErrorAction Stop | |
} | |
if ((Get-Command Get-UefiDatabaseSignatures -ErrorAction SilentlyContinue).count -eq 0) | |
{ | |
Write-Error "Please import function Get-UefiDatabaseSignatures." -ErrorAction Stop | |
} | |
# Fail early if Secure Boot isn't enabled on the local system. | |
Get-SecureBootPolicy -ErrorAction Stop | Out-Null | |
$LocalDbx = Get-SecureBootUEFI dbx | Get-UEFIDatabaseSignatures | |
if ($PSCmdlet.ParameterSetName -eq "Base64") | |
{ | |
$DecodedBytes = [System.Convert]::FromBase64String($Base64) | |
$Filename = "$env:temp\dbxupdate.bin" | |
Set-Content -Encoding Byte -Path $Filename -Value $DecodedBytes -Force | |
} | |
Try | |
{ | |
$Filename = (Resolve-Path $Filename -ErrorAction Stop).Path | |
Write-Verbose ("Using file: $Filename") | |
$DbxFileSigs = Get-UEFIDatabaseSignatures -Filename $Filename | |
} | |
Catch | |
{ | |
Write-Error "Failure while parsing $Filename." -ErrorAction Stop | |
} | |
$LocalSigs = @($LocalDbx).ForEach({if ($_.SignatureType -eq "EFI_CERT_SHA256_GUID") { $_.SignatureList.SignatureData } elseif ($_.SignatureType -eq "EFI_CERT_X509_GUID") { $_.SignatureList.SignatureData.Thumbprint }}) | Sort-Object | |
$FileSigs = @($DbxFileSigs).ForEach({if ($_.SignatureType -eq "EFI_CERT_SHA256_GUID") { $_.SignatureList.SignatureData } elseif ($_.SignatureType -eq "EFI_CERT_X509_GUID") { $_.SignatureList.SignatureData.Thumbprint }}) | Sort-Object | |
$ExtraSigs = (Compare-Object $LocalSigs $FileSigs).Where({$_.SideIndicator -eq "<="}).InputObject | |
$MissingSigs = (Compare-Object $LocalSigs $FileSigs).Where({$_.SideIndicator -eq "=>"}).InputObject | |
$result = [pscustomobject]@{ | |
"Filename"=$Filename; | |
"LocalSigCount"=$LocalSigs.Count; | |
"FileSigCount"=$FileSigs.Count; | |
"MissingSigCount"=$MissingSigs.Count; | |
"ExtraSigCount"=$ExtraSigs.Count; | |
} | |
Write-Verbose ("{0} signatures in local database, {1} signatures in database file. {2} are present in the file and not on this system, {3} are present on this system and not in the update file." -f $result.LocalSigCount,$result.FileSigCount,$result.MissingSigCount,$result.ExtraSigCount) | |
Return $result |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function Get-UefiDatabaseSignatures { | |
<# | |
.SYNOPSIS | |
Parses UEFI Signature Databases into logical Powershell objects | |
.DESCRIPTION | |
Original Author: Matthew Graeber (@mattifestation) | |
Modified By: Jeremiah Cox (@int0x6) | |
Modified By: Joel Roth (@nafai) | |
Additional Source: https://gist.github.com/mattifestation/991a0bea355ec1dc19402cef1b0e3b6f | |
Additional Source: https://www.powershellgallery.com/packages/SplitDbxContent/1.0 | |
License: BSD 3-Clause | |
.PARAMETER Variable | |
Specifies a UEFI variable, an instance of which is returned by calling the Get-SecureBootUEFI cmdlet. Only 'db' and 'dbx' are supported. | |
.PARAMETER BytesIn | |
Specifies a byte array consisting of the PK, KEK, db, or dbx UEFI vairable contents. | |
.EXAMPLE | |
$DbxBytes = [IO.File]::ReadAllBytes('.\dbx.bin') | |
Get-UEFIDatabaseSignatures -BytesIn $DbxBytes | |
.EXAMPLE | |
Get-UEFIDatabaseSignatures -Filename ".\DBXUpdate-20230314.x64.bin" | |
.EXAMPLE | |
Get-SecureBootUEFI -Name db | Get-UEFIDatabaseSignatures | |
.EXAMPLE | |
Get-SecureBootUEFI -Name dbx | Get-UEFIDatabaseSignatures | |
.EXAMPLE | |
Get-SecureBootUEFI -Name pk | Get-UEFIDatabaseSignatures | |
.EXAMPLE | |
Get-SecureBootUEFI -Name kek | Get-UEFIDatabaseSignatures | |
.INPUTS | |
Microsoft.SecureBoot.Commands.UEFIEnvironmentVariable | |
Accepts the output of Get-SecureBootUEFI over the pipeline. | |
.OUTPUTS | |
UefiSignatureDatabase | |
Outputs an array of custom powershell objects describing a UEFI Signature Database. "77fa9abd-0359-4d32-bd60-28f4e78f784b" refers to Microsoft as the owner. | |
#> | |
[CmdletBinding()] | |
param ( | |
[Parameter(Mandatory, ValueFromPipeline, ParameterSetName = 'UEFIVariable')] | |
[ValidateScript({ ($_.GetType().Fullname -eq 'Microsoft.SecureBoot.Commands.UEFIEnvironmentVariable') -and ($_.Name -in "kek","pk","db","dbx") })] | |
$Variable, | |
[Parameter(Mandatory, ParameterSetName = 'ByteArray')] | |
[Byte[]] | |
[ValidateNotNullOrEmpty()] | |
$BytesIn, | |
[Parameter(Mandatory, ParameterSetName = 'File')] | |
[string] | |
[ValidateScript({ (Resolve-Path "$_").where({Test-Path $_}).Path })] | |
$Filename | |
) | |
$SignatureTypeMapping = @{ | |
'C1C41626-504C-4092-ACA9-41F936934328' = 'EFI_CERT_SHA256_GUID' # Most often used for dbx | |
'A5C059A1-94E4-4AA7-87B5-AB155C2BF072' = 'EFI_CERT_X509_GUID' # Most often used for db | |
} | |
$Bytes = $null | |
if ($Filename) | |
{ | |
$Bytes = Get-Content -Encoding Byte $Filename -ErrorAction Stop | |
} | |
elseif ($Variable) | |
{ | |
$Bytes = $Variable.Bytes | |
} | |
else | |
{ | |
$Bytes = $BytesIn | |
} | |
# Modified from Split-Dbx | |
if (($Bytes[40] -eq 0x30) -and ($Bytes[41] -eq 0x82 )) | |
{ | |
Write-Debug "Removing signature." | |
# Signature is known to be ASN size plus header of 4 bytes | |
$sig_length = $Bytes[42] * 256 + $Bytes[43] + 4 | |
if ($sig_length -gt ($Bytes.Length + 40)) { | |
Write-Error "Signature longer than file size!" -ErrorAction Stop | |
} | |
## Unsigned db store | |
[System.Byte[]]$Bytes = @($Bytes[($sig_length+40)..($Bytes.Length - 1)].Clone()) | |
} | |
else | |
{ | |
Write-Debug "Signature not found. Assuming it's already split." | |
} | |
try | |
{ | |
$MemoryStream = New-Object -TypeName IO.MemoryStream -ArgumentList @(,$Bytes) | |
$BinaryReader = New-Object -TypeName IO.BinaryReader -ArgumentList $MemoryStream, ([Text.Encoding]::Unicode) | |
} | |
catch | |
{ | |
throw $_ | |
return | |
} | |
# What follows will be an array of EFI_SIGNATURE_LIST structs | |
while ($BinaryReader.PeekChar() -ne -1) { | |
$SignatureType = $SignatureTypeMapping[([Guid][Byte[]] $BinaryReader.ReadBytes(16)).Guid] | |
$SignatureListSize = $BinaryReader.ReadUInt32() | |
$SignatureHeaderSize = $BinaryReader.ReadUInt32() | |
$SignatureSize = $BinaryReader.ReadUInt32() | |
$SignatureHeader = $BinaryReader.ReadBytes($SignatureHeaderSize) | |
# 0x1C is the size of the EFI_SIGNATURE_LIST header | |
$SignatureCount = ($SignatureListSize - 0x1C) / $SignatureSize | |
$SignatureList = 1..$SignatureCount | ForEach-Object { | |
$SignatureDataBytes = $BinaryReader.ReadBytes($SignatureSize) | |
$SignatureOwner = [Guid][Byte[]] $SignatureDataBytes[0..15] | |
switch ($SignatureType) { | |
'EFI_CERT_SHA256_GUID' { | |
$SignatureData = ([Byte[]] $SignatureDataBytes[0x10..0x2F] | ForEach-Object { $_.ToString('X2') }) -join '' | |
} | |
'EFI_CERT_X509_GUID' { | |
$SignatureData = New-Object Security.Cryptography.X509Certificates.X509Certificate2 -ArgumentList @(,([Byte[]] $SignatureDataBytes[16..($SignatureDataBytes.Count - 1)])) | |
} | |
} | |
[PSCustomObject] @{ | |
PSTypeName = 'EFI.SignatureData' | |
SignatureOwner = $SignatureOwner | |
SignatureData = $SignatureData | |
} | |
} | |
[PSCustomObject] @{ | |
PSTypeName = 'EFI.SignatureList' | |
SignatureType = $SignatureType | |
SignatureList = $SignatureList | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
In case it helps anyone else, https://github.com/fwupd/dbx-firmware has been a more convenient source than uefi.org for the historical/archived files.