Forked from mattifestation/UEFISecDatabaseParser.ps1
Last active
September 21, 2025 17:14
-
-
Save p0w3rsh3ll/16512ce589aa6e40c6ec854f651edb26 to your computer and use it in GitHub Desktop.
Parses signature data from the pk, kek, db, and dbx UEFI variables.
This file contains hidden or 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-UEFIDatabaseSigner { | |
| <# | |
| .SYNOPSIS | |
| Dumps signature or hash information for whitelisted ('db' variable) or blacklisted ('dbx' variable) UEFI bootloaders. | |
| .DESCRIPTION | |
| Author: Matthew Graeber (@mattifestation) | |
| License: BSD 3-Clause | |
| .PARAMETER Variable | |
| Specifies a UEFI variable name or a list of variable names. | |
| The default variable name used is 'dbx'. | |
| .PARAMETER File | |
| Specifies the path to a binary file. | |
| .PARAMETER InputObject | |
| Specifies an instance or a list of instances of the Get-SecureBootUEFI cmdlet output | |
| .EXAMPLE | |
| Get-SecureBootUEFI -Name db | Get-UEFIDatabaseSigner | |
| .EXAMPLE | |
| Get-SecureBootUEFI -Name dbx | Get-UEFIDatabaseSigner | |
| .EXAMPLE | |
| Get-SecureBootUEFI -Name pk | Get-UEFIDatabaseSigner | |
| .EXAMPLE | |
| (Get-SecureBootUEFI -Name kek),(Get-SecureBootUEFI -Name db) | Get-UEFIDatabaseSigner | |
| .EXAMPLE | |
| Get-UEFIDatabaseSigner -Variable dbx | |
| .EXAMPLE | |
| Get-UEFIDatabaseSigner -Variable kek,pk,db | |
| .EXAMPLE | |
| Get-UEFIDatabaseSigner -File .\DBXUpdate.bin | |
| .INPUTS | |
| System.String | |
| Microsoft.SecureBoot.Commands.UEFIEnvironmentVariable | |
| Accepts the output of Get-SecureBootUEFI over the pipeline. | |
| .OUTPUTS | |
| Outputs a custom object consisting of banned SHA256 hashes and the respective "owner" of each hash. | |
| "77fa9abd-0359-4d32-bd60-28f4e78f784b" refers to Microsoft as the owner. | |
| .NOTES | |
| Modified by @p0w3rsh3ll | |
| Split-DbxAuthInfo is from https://www.powershellgallery.com/packages/SplitDbxContent/1.0/Content/SplitDbxContent.ps1 | |
| DBX Bin files can be found on these 2 sites: | |
| https://github.com/microsoft/secureboot_objects/releases/ | |
| https://github.com/fwupd/dbx-firmware | |
| #> | |
| [CmdletBinding(DefaultParameterSetName='Name')] | |
| Param ( | |
| [Parameter(ParameterSetName = 'Name')] | |
| [Parameter()] | |
| [ValidateSet('kek','pk','db','dbx')] | |
| [string[]]$Variable='dbx', | |
| [Parameter(ParameterSetName = 'FilePath')] | |
| [Parameter()] | |
| [ValidateScript({Test-Path -Path $_ -PathType Leaf})] | |
| [string]$File, | |
| [Parameter(ParameterSetName = 'Input')] | |
| [Parameter(ValueFromPipeline)] | |
| [ValidateScript({ ($_.GetType().Fullname -eq 'Microsoft.SecureBoot.Commands.UEFIEnvironmentVariable')})] | |
| $InputObject | |
| ) | |
| Begin { | |
| $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 | |
| } | |
| $Var = New-Object System.Collections.ArrayList | |
| Function Split-DbxAuthInfo { | |
| [CmdletBinding()] | |
| [OutputType([System.Byte[]])] | |
| Param( | |
| [Parameter(Mandatory)] | |
| [string]$FilePath | |
| ) | |
| Begin { | |
| Switch ($PSVersionTable.PSEdition) { | |
| 'Core' { $HT = @{ AsByteStream = [switch]::Present }} | |
| 'Desktop'{ $HT = @{ Encoding = 'Byte' }} | |
| } | |
| } | |
| Process { | |
| Try { | |
| $rawfile = (Get-Content -Path "$($FilePath)" @HT -ErrorAction Stop) | |
| } catch { | |
| throw $_ | |
| return | |
| } | |
| $chop = $rawfile[40..($rawfile.Length - 1)] | |
| if ($chop[0] -eq 0x30 -and $chop[1] -eq 0x82) { | |
| # Signature is known to be ASN size plus header of 4 bytes | |
| $sig_length = ($chop[2] * 256) + $chop[3] + 4 | |
| $sig = $chop[0..($sig_length - 1)] | |
| if ($sig_length -gt ($rawfile.Length + 40)) { | |
| throw 'Signature longer than file size!' | |
| return | |
| } | |
| [Byte[]]($chop[$sig_length..($chop.Length - 1)]) | |
| } else { | |
| $rawfile | |
| } | |
| } | |
| End {} | |
| } | |
| } | |
| Process { | |
| Switch ($PSCmdlet.ParameterSetName) { | |
| 'Name' { | |
| $Variable | | |
| Foreach-Object { | |
| $null = $Var.Add( | |
| [PSCustomObject]@{ | |
| Name = $_ | |
| Object = (Get-SecureBootUEFI -Name $_) | |
| } | |
| ) | |
| } | |
| break | |
| } | |
| 'FilePath' { | |
| $null = $Var.Add( | |
| [PSCustomObject]@{ | |
| Name = "$($File)" | |
| Object = [PSCustomObject]@{ | |
| Name = 'File' | |
| Bytes = (Split-DbxAuthInfo -FilePath "$($File)") | |
| Attribute = [string]::Empty | |
| } | |
| } | |
| ) | |
| break | |
| } | |
| 'Input' { | |
| $InputObject | | |
| Foreach-Object { | |
| $null = $Var.Add( | |
| [PSCustomObject]@{ | |
| Name = $_.Name | |
| Object = $_ | |
| } | |
| ) | |
| } | |
| break | |
| } | |
| default {} | |
| } | |
| $Var | | |
| Foreach-Object -Process { | |
| $n = $_.Name | |
| $v = $_.Object | |
| try { | |
| $MemoryStream = New-Object -TypeName IO.MemoryStream -ArgumentList @(,$v.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 | |
| $Signature = 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] @{ | |
| SecureBootDBName = $n | |
| PSTypeName = 'EFI.SignatureData' | |
| SignatureOwner = $SignatureOwner | |
| SignatureData = $SignatureData | |
| } | |
| } | |
| [PSCustomObject] @{ | |
| SecureBootDBName = $n | |
| PSTypeName = 'EFI.SignatureList' | |
| SignatureType = $SignatureType | |
| Signature = $Signature | |
| } | |
| } #endof while | |
| } #enof % | |
| } | |
| End {} | |
| } | |
| Export-ModuleMember -Function 'Get-UEFIDatabaseSigner' |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment