rufus/res/scripts/SspToBar.ps1

209 lines
6.9 KiB
PowerShell

#
# SspToBar.ps1 - SkuSiPolicy.p7b revoked PE256 hashes to C byte array converter
# Copyright © 2023 Pete Batard <pete@akeo.ie>
# Heavily derived from https://gist.github.com/mattifestation/92e545bf1ee5b68eeb71d254cec2f78e
# Copyright © 2016-2019 Matthew Graeber with contributions by James Forshaw
#
# License: BSD 3-Clause
#
# This script is generates the pe256ssp[] byte array from Rufus' db.h
#region Parameters
[cmdletbinding()]
param(
# (Optional) The path to the .p7b to process
[string]$BinaryFilePath = "SkuSiPolicy.p7b",
# (Optional) Output the straight values
[switch]$Raw = $false
)
#endregion
Add-Type -AssemblyName 'System.Security'
$BinPath = Resolve-Path $BinaryFilePath
$GuidLength = 0x10
$Pe256HashLength = 0x20
$HeaderLengthMax = 0x44
# Helper function to read strings from the binary
function Get-BinaryString {
[OutputType('String')]
param (
[Parameter(Mandatory)]
[IO.BinaryReader]
[ValidateNotNullOrEmpty()]
$BinaryReader
)
$StringLength = $BinaryReader.ReadUInt32()
if ($StringLength) {
$PaddingBytes = 4 - $StringLength % 4 -band 3
$StringBytes = $BinaryReader.ReadBytes($StringLength)
$null = $BinaryReader.ReadBytes($PaddingBytes)
[Text.Encoding]::Unicode.GetString($StringBytes)
}
$null = $BinaryReader.ReadInt32()
}
try {
$CIPolicyBytes = [IO.File]::ReadAllBytes($BinPath.Path)
try {
$ContentType = $null
try {
$ContentType = [Security.Cryptography.Pkcs.ContentInfo]::GetContentType($CIPolicyBytes)
} catch { }
# Check for PKCS#7 ASN.1 SignedData type
if ($ContentType -and $ContentType.Value -eq '1.2.840.113549.1.7.2') {
$Cms = New-Object System.Security.Cryptography.Pkcs.SignedCms
$Cms.Decode($CIPolicyBytes)
$CIPolicyBytes = $Cms.ContentInfo.Content
if ($CIPolicyBytes[0] -eq 4) {
$PolicySize = $CIPolicyBytes[1]
$BaseIndex = 2
if (($PolicySize -band 0x80) -eq 0x80) {
$SizeCount = $PolicySize -band 0x7F
$BaseIndex += $SizeCount
$PolicySize = 0
for ($i = 0; $i -lt $SizeCount; $i++) {
$PolicySize = $PolicySize -shl 8
$PolicySize = $PolicySize -bor $CIPolicyBytes[2 + $i]
}
}
$CIPolicyBytes = $CIPolicyBytes[$BaseIndex..($BaseIndex + $PolicySize - 1)]
}
}
} catch {
Write-Output $_
}
$MemoryStream = New-Object -TypeName IO.MemoryStream -ArgumentList @(,$CIPolicyBytes)
$BinaryReader = New-Object -TypeName System.IO.BinaryReader -ArgumentList $MemoryStream, ([Text.Encoding]::Unicode)
} catch {
throw $_
return
}
try {
$CIPolicyFormatVersion = $BinaryReader.ReadInt32()
Write-Verbose "Detected CI Policy Format Version $CIPolicyFormatVersion"
if ($CIPolicyFormatVersion -gt 7) {
Write-Warning "CI Policy Format may be unsupported..."
}
$PolicyTypeID = [Guid][Byte[]] $BinaryReader.ReadBytes($GuidLength)
switch ($PolicyTypeID.Guid) {
'a244370e-44c9-4c06-b551-f6016e563076' { Write-Verbose "Policy Type {$PolicyTypeID} => Enterprise Code Integrity Policy (SiPolicy.p7b or UpdateSiPolicy.p7b)" }
'2a5a0136-f09f-498e-99cc-51099011157c' { Write-Verbose "Policy Type {$PolicyTypeID} => Windows Revoke Code Integrity Policy (RvkSiPolicy.p7b or UpdateRvkSiPolicy.p7b)" }
'976d12c8-cb9f-4730-be52-54600843238e' { Write-Verbose "Policy Type {$PolicyTypeID} => SKU Code Integrity Policy (SkuSiPolicy.p7b or UpdateSkuSiPolicy.p7b)" }
'5951a96a-e0b5-4d3d-8fb8-3e5b61030784' { Write-Verbose "Policy Type {$PolicyTypeID} => Windows Lockdown Code Integrity Policy (WinSiPolicy.p7b or UpdateWinSiPolicy.p7b)" }
'4e61c68c-97f6-430b-9cd7-9b1004706770' { Write-Verbose "Policy Type {$PolicyTypeID} => Advanced Threat Protection Code Integrity Policy (ATPSiPolicy.p7b or UpdateATPSiPolicy.p7b)" }
'd2bda982-ccf6-4344-ac5b-0b44427b6816' { Write-Verbose "Policy Type {$PolicyTypeID} => Driver Code Integrity Policy (DriverSiPolicy.p7b or UpdateDriverSiPolicy.p7b)" }
default { Write-Warning "Policy Type {$PolicyTypeID} => Unknown Policy Type" }
}
[Byte[]] $PlatformIDBytes = $BinaryReader.ReadBytes($GuidLength)
$PlatformID = [Guid] $PlatformIDBytes
Write-Verbose "PlatformID: {$PlatformID}"
$OptionFlags = $BinaryReader.ReadInt32()
Write-Verbose "Policy Option Flags: 0x$($OptionFlags.ToString('X8'))"
if ($OptionFlags -band ([Int32]::MinValue) -ne [Int32]::MinValue) {
throw "Invalid Policy Option Flags"
return
}
if (($OptionFlags -band 0x40000000) -eq 0x40000000) {
Write-Warning 'Policy Option Flags indicate that the CI Policy was built from supplemental policies.'
}
$EKURuleEntryCount = $BinaryReader.ReadInt32()
Write-Verbose "$EKURuleEntryCount EKU Rule(s)"
$FileRuleEntryCount = $BinaryReader.ReadInt32()
Write-Verbose "$FileRuleEntryCount File Rule(s)"
$SignerRuleEntryCount = $BinaryReader.ReadInt32()
Write-Verbose "$SignerRuleEntryCount Signer Rule(s)"
$SignerScenarioEntryCount = $BinaryReader.ReadInt32()
Write-Verbose "$SignerScenarioEntryCount Signer Scenario(s)"
$Revis = $BinaryReader.ReadUInt16()
$Build = $BinaryReader.ReadUInt16()
$Minor = $BinaryReader.ReadUInt16()
$Major = $BinaryReader.ReadUInt16()
Write-Verbose "Version: $Major.$Minor.$Build.$Revis"
$HeaderLength = $BinaryReader.ReadInt32()
if ($HeaderLength -ne ($HeaderLengthMax - 4)) {
Write-Warning "$BinPath has an invalid header footer: 0x$($HeaderLength.ToString('x8'))"
}
if ($EKURuleEntryCount) {
Write-Verbose "Skipping EKU Rules..."
for ($i = 0; $i -lt $EKURuleEntryCount; $i++) {
$EkuValueLen = $BinaryReader.ReadUInt32()
$PaddingBytes = 4 - $EkuValueLen % 4 -band 3
$null = $BinaryReader.ReadBytes($EkuValueLen)
$null = $BinaryReader.ReadBytes($PaddingBytes)
}
}
if ($FileRuleEntryCount) {
Write-Verbose "Processing File Rules..."
$HashArray = New-Object System.Collections.ArrayList
for ($i = 0; $i -lt $FileRuleEntryCount; $i++) {
$FileRuleTypeValue = $BinaryReader.ReadInt32()
$FileName = Get-BinaryString -BinaryReader $BinaryReader
$Revis = $BinaryReader.ReadUInt16()
$Build = $BinaryReader.ReadUInt16()
$Minor = $BinaryReader.ReadUInt16()
$Major = $BinaryReader.ReadUInt16()
$HashLen = $BinaryReader.ReadUInt32()
if ($HashLen) {
$PaddingBytes = 4 - $HashLen % 4 -band 3
$HashBytes = $BinaryReader.ReadBytes($HashLen)
# We are only interested in the 'DENY' type (0) for PE256 hashes
if (($FileRuleTypeValue -eq 0) -and ($HashLen -eq $Pe256HashLength)) {
$HashString = ($HashBytes | ForEach-Object ToString x2) -join ''
$HashArray.Add($HashString) | Out-Null
}
$null = $BinaryReader.ReadBytes($PaddingBytes)
}
}
# Sort the array and remove duplicates
$HashArray.Sort()
$HashArray = $HashArray | Select-Object -Unique
foreach ($HashStr in $HashArray) {
if ($Raw) {
Write-Output $HashStr
} else {
$HashChars = $HashStr.ToCharArray()
$Line = "`t"
for ($i = 0; $i -lt $Pe256HashLength; $i++) {
$Line += "0x" + $HashChars[2 * $i] + $HashChars[2 * $i + 1] + ", "
}
Write-Output $Line
}
}
}
} catch {
$BinaryReader.Close()
$MemoryStream.Close()
throw $_
return
}