Skip to content

Instantly share code, notes, and snippets.

@andrewgalbraith
Forked from out0xb2/Check-Dbx.ps1
Created June 8, 2022 17:08
Show Gist options
  • Select an option

  • Save andrewgalbraith/19c1cb398f6f8500b24f173634c01c50 to your computer and use it in GitHub Desktop.

Select an option

Save andrewgalbraith/19c1cb398f6f8500b24f173634c01c50 to your computer and use it in GitHub Desktop.

Revisions

  1. Jeremiah Cox revised this gist Jul 19, 2021. 1 changed file with 3 additions and 1 deletion.
    4 changes: 3 additions & 1 deletion Check-Dbx.ps1
    Original file line number Diff line number Diff line change
    @@ -24,7 +24,8 @@ if (-NOT ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdent
    $biosinfo = $bios.Manufacturer , $bios.Name , $bios.SMBIOSBIOSVersion , $bios.Version -join ", "
    "BIOS: " + $biosinfo + "`n"

    $DbxFound = Get-SecureBootUEFI dbx | Get-UEFIDatabaseSignatures
    $DbxRaw = Get-SecureBootUEFI dbx
    $DbxFound = $DbxRaw | Get-UEFIDatabaseSignatures

    $DbxBytesRequired = [IO.File]::ReadAllBytes($patchfile)
    $DbxRequired = Get-UEFIDatabaseSignatures -BytesIn $DbxBytesRequired
    @@ -66,6 +67,7 @@ if (-NOT ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdent

    if ($failures -ne 0) {
    Write-Error "!!! FAIL: $failures failures detected!"
    # $DbxRaw.Bytes | sc -encoding Byte dbx_found.bin
    } elseif ($successes -ne $RequiredArray.Count) {
    Write-Error "!!! Unexpected: $successes != $requiredCount expected successes!"
    } elseif ($successes -eq 0) {
  2. Jeremiah Cox revised this gist Jul 19, 2021. 1 changed file with 9 additions and 1 deletion.
    10 changes: 9 additions & 1 deletion Check-Dbx.ps1
    Original file line number Diff line number Diff line change
    @@ -16,6 +16,14 @@ if (-NOT ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdent

    Import-Module -Force .\Get-UEFIDatabaseSignatures.ps1

    # Print computer info
    $computer = gwmi Win32_ComputerSystem
    $bios = gwmi Win32_BIOS
    "Manufacturer: " + $computer.Manufacturer
    "Model: " + $computer.Model
    $biosinfo = $bios.Manufacturer , $bios.Name , $bios.SMBIOSBIOSVersion , $bios.Version -join ", "
    "BIOS: " + $biosinfo + "`n"

    $DbxFound = Get-SecureBootUEFI dbx | Get-UEFIDatabaseSignatures

    $DbxBytesRequired = [IO.File]::ReadAllBytes($patchfile)
    @@ -30,7 +38,7 @@ if (-NOT ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdent
    }
    }
    Write-Information "Required `n" $RequiredArray

    # Flatten into an array of EfiSignatureData data objects (read from dbx)
    $FoundArray = foreach ($EfiSignatureList in $DbxFound) {
    Write-Verbose $EfiSignatureList
  3. [email protected] revised this gist May 27, 2021. 1 changed file with 9 additions and 0 deletions.
    9 changes: 9 additions & 0 deletions Check-Dbx.ps1
    Original file line number Diff line number Diff line change
    @@ -1,9 +1,18 @@
    Write-Host "Checking for Administrator permission..."
    if (-NOT ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) {
    Write-Warning "Insufficient permissions to run this script. Open the PowerShell console as administrator and run this script again."
    Break
    } else {
    Write-Host "Running as administrator — continuing execution..." -ForegroundColor Green
    }

    $patchfile = $args[0]

    if ($patchfile -eq $null) {
    $patchfile = ".\dbx-2021-April.bin"
    Write-Host "Patchfile not specified, using latest $patchfile`n"
    }
    $patchfile = (gci $patchfile).FullName

    Import-Module -Force .\Get-UEFIDatabaseSignatures.ps1

  4. Jeremiah Cox revised this gist May 21, 2021. 4 changed files with 11 additions and 2 deletions.
    13 changes: 11 additions & 2 deletions Check-Dbx.ps1
    Original file line number Diff line number Diff line change
    @@ -1,8 +1,15 @@
    $patchfile = $args[0]

    if ($patchfile -eq $null) {
    $patchfile = ".\dbx-2021-April.bin"
    Write-Host "Patchfile not specified, using latest $patchfile`n"
    }

    Import-Module -Force .\Get-UEFIDatabaseSignatures.ps1

    $DbxFound = Get-SecureBootUEFI dbx | Get-UEFIDatabaseSignatures

    $DbxBytesRequired = [IO.File]::ReadAllBytes((pwd).Path+'\dbx-August.bin')
    $DbxBytesRequired = [IO.File]::ReadAllBytes($patchfile)
    $DbxRequired = Get-UEFIDatabaseSignatures -BytesIn $DbxBytesRequired

    # Flatten into an array of required EfiSignatureData data objects
    @@ -44,6 +51,8 @@
    Write-Error "!!! FAIL: $failures failures detected!"
    } elseif ($successes -ne $RequiredArray.Count) {
    Write-Error "!!! Unexpected: $successes != $requiredCount expected successes!"
    } elseif ($successes -eq 0) {
    Write-Error "!!! Unexpected failure: no successes detected, check command-line usage."
    } else {
    Write-Host "SUCCESS: dbx.bin patch appears to be successfully applied"
    }
    }
    File renamed without changes.
    File renamed without changes.
    Binary file added dbx-2021-April.bin
    Binary file not shown.
  5. @out0xb2 out0xb2 revised this gist Dec 8, 2020. 4 changed files with 180 additions and 106 deletions.
    49 changes: 49 additions & 0 deletions Check-Dbx.ps1
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,49 @@
    Import-Module -Force .\Get-UEFIDatabaseSignatures.ps1

    $DbxFound = Get-SecureBootUEFI dbx | Get-UEFIDatabaseSignatures

    $DbxBytesRequired = [IO.File]::ReadAllBytes((pwd).Path+'\dbx-August.bin')
    $DbxRequired = Get-UEFIDatabaseSignatures -BytesIn $DbxBytesRequired

    # Flatten into an array of required EfiSignatureData data objects
    $RequiredArray = foreach ($EfiSignatureList in $DbxRequired) {
    Write-Verbose $EfiSignatureList
    foreach ($RequiredSignatureData in $EfiSignatureList.SignatureList) {
    Write-Verbose $RequiredSignatureData
    $RequiredSignatureData.SignatureData
    }
    }
    Write-Information "Required `n" $RequiredArray

    # Flatten into an array of EfiSignatureData data objects (read from dbx)
    $FoundArray = foreach ($EfiSignatureList in $DbxFound) {
    Write-Verbose $EfiSignatureList
    foreach ($FoundSignatureData in $EfiSignatureList.SignatureList) {
    Write-Verbose $FoundSignatureData
    $FoundSignatureData.SignatureData
    }
    }
    Write-Information "Found `n" $FoundArray

    $successes = 0
    $failures = 0
    $requiredCount = $RequiredArray.Count
    foreach ($RequiredSig in $RequiredArray) {
    if ($FoundArray -contains $RequiredSig) {
    Write-Information "FOUND: $RequiredSig"
    $successes++
    } else {
    Write-Error "!!! NOT FOUND`n$RequiredSig`n!!!`n"
    $failures++
    }
    $i = $successes + $failures
    Write-Progress -Activity 'Checking if all patches applied' -Status "Checking element $i of $requiredCount" -PercentComplete ($i/$requiredCount *100)
    }

    if ($failures -ne 0) {
    Write-Error "!!! FAIL: $failures failures detected!"
    } elseif ($successes -ne $RequiredArray.Count) {
    Write-Error "!!! Unexpected: $successes != $requiredCount expected successes!"
    } else {
    Write-Host "SUCCESS: dbx.bin patch appears to be successfully applied"
    }
    237 changes: 131 additions & 106 deletions Get-UEFIDatabaseSignatures.ps1
    Original file line number Diff line number Diff line change
    @@ -1,106 +1,131 @@
    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, an instance of which is returned by calling the Get-SecureBootUEFI cmdlet. Only 'db' and 'dbx' are supported.
    .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-UEFIDatabaseSigner
    .INPUTS
    Microsoft.SecureBoot.Commands.UEFIEnvironmentVariable
    Accepts the output of Get-SecureBootUEFI over the pipeline.
    .OUTPUTS
    UEFIDBXHash
    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.
    #>

    [CmdletBinding()]
    param (
    [Parameter(Mandatory, ValueFromPipeline)]
    [ValidateScript({ ($_.GetType().Fullname -eq 'Microsoft.SecureBoot.Commands.UEFIEnvironmentVariable') -and (($_.Name -eq 'kek') -or ($_.Name -eq 'pk') -or ($_.Name -eq 'db') -or ($_.Name -eq 'dbx')) })]
    $Variable
    )

    $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
    }

    try {
    $MemoryStream = New-Object -TypeName IO.MemoryStream -ArgumentList @(,$Variable.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] @{
    PSTypeName = 'EFI.SignatureData'
    SignatureOwner = $SignatureOwner
    SignatureData = $SignatureData
    }
    }

    [PSCustomObject] @{
    PSTypeName = 'EFI.SignatureList'
    SignatureType = $SignatureType
    Signature = $Signature
    }
    }
    }
    function Get-UefiDatabaseSignatures {
    <#
    .SYNOPSIS
    Parses UEFI Signature Databases into logical Powershell objects
    .DESCRIPTION
    Original Author: Matthew Graeber (@mattifestation)
    Modified By: Jeremiah Cox (@int0x6)
    Additional Source: https://gist.github.com/mattifestation/991a0bea355ec1dc19402cef1b0e3b6f
    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-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 -eq 'kek') -or ($_.Name -eq 'pk') -or ($_.Name -eq 'db') -or ($_.Name -eq 'dbx')) })]
    $Variable,

    [Parameter(Mandatory, ParameterSetName = 'ByteArray')]
    [Byte[]]
    [ValidateNotNullOrEmpty()]
    $BytesIn
    )

    $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 ($Variable) {
    $Bytes = $Variable.Bytes
    } else {
    $Bytes = $BytesIn
    }

    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
    }
    }
    }
    Binary file added dbx-August.bin
    Binary file not shown.
    Binary file added dbx-July.bin
    Binary file not shown.
  6. @out0xb2 out0xb2 renamed this gist Dec 8, 2020. 1 changed file with 0 additions and 0 deletions.
  7. @mattifestation mattifestation revised this gist Jun 13, 2018. 1 changed file with 9 additions and 1 deletion.
    10 changes: 9 additions & 1 deletion UEFISecDatabaseParser.ps1
    Original file line number Diff line number Diff line change
    @@ -21,6 +21,14 @@ Get-SecureBootUEFI -Name db | Get-UEFIDatabaseSigner
    Get-SecureBootUEFI -Name dbx | Get-UEFIDatabaseSigner
    .EXAMPLE
    Get-SecureBootUEFI -Name pk | Get-UEFIDatabaseSigner
    .EXAMPLE
    Get-SecureBootUEFI -Name kek | Get-UEFIDatabaseSigner
    .INPUTS
    Microsoft.SecureBoot.Commands.UEFIEnvironmentVariable
    @@ -37,7 +45,7 @@ Outputs a custom object consisting of banned SHA256 hashes and the respective "o
    [CmdletBinding()]
    param (
    [Parameter(Mandatory, ValueFromPipeline)]
    [ValidateScript({ ($_.GetType().Fullname -eq 'Microsoft.SecureBoot.Commands.UEFIEnvironmentVariable') -and (($_.Name -eq 'db') -or ($_.Name -eq 'dbx')) })]
    [ValidateScript({ ($_.GetType().Fullname -eq 'Microsoft.SecureBoot.Commands.UEFIEnvironmentVariable') -and (($_.Name -eq 'kek') -or ($_.Name -eq 'pk') -or ($_.Name -eq 'db') -or ($_.Name -eq 'dbx')) })]
    $Variable
    )

  8. @mattifestation mattifestation created this gist May 8, 2018.
    98 changes: 98 additions & 0 deletions UEFISecDatabaseParser.ps1
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,98 @@
    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, an instance of which is returned by calling the Get-SecureBootUEFI cmdlet. Only 'db' and 'dbx' are supported.
    .EXAMPLE
    Get-SecureBootUEFI -Name db | Get-UEFIDatabaseSigner
    .EXAMPLE
    Get-SecureBootUEFI -Name dbx | Get-UEFIDatabaseSigner
    .INPUTS
    Microsoft.SecureBoot.Commands.UEFIEnvironmentVariable
    Accepts the output of Get-SecureBootUEFI over the pipeline.
    .OUTPUTS
    UEFIDBXHash
    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.
    #>

    [CmdletBinding()]
    param (
    [Parameter(Mandatory, ValueFromPipeline)]
    [ValidateScript({ ($_.GetType().Fullname -eq 'Microsoft.SecureBoot.Commands.UEFIEnvironmentVariable') -and (($_.Name -eq 'db') -or ($_.Name -eq 'dbx')) })]
    $Variable
    )

    $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
    }

    try {
    $MemoryStream = New-Object -TypeName IO.MemoryStream -ArgumentList @(,$Variable.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] @{
    PSTypeName = 'EFI.SignatureData'
    SignatureOwner = $SignatureOwner
    SignatureData = $SignatureData
    }
    }

    [PSCustomObject] @{
    PSTypeName = 'EFI.SignatureList'
    SignatureType = $SignatureType
    Signature = $Signature
    }
    }
    }