Skip to content

Instantly share code, notes, and snippets.

@mattifestation
Last active July 27, 2022 09:37
Show Gist options
  • Save mattifestation/7027c1ff29d699d69b87ad564d0ea6d5 to your computer and use it in GitHub Desktop.
Save mattifestation/7027c1ff29d699d69b87ad564d0ea6d5 to your computer and use it in GitHub Desktop.
ELAM driver approved anti-malware signer parser
function Get-ElamCertInfo {
<#
.SYNOPSIS
Extract early launch anti-malware certificate information from an ELAM driver.
Author: Matthew Graeber (@mattifestation)
License: BSD 3-Clause
.DESCRIPTION
Get-ElamCertInfo parses out the MICROSOFTELAMCERTIFICATEINFO resource of an ELAM driver. The information contained in this structure contains a list of approved anti-malware product signers.
.PARAMETER Path
Specifies the path to the target ELAM driver.
.EXAMPLE
Get-CimInstance Win32_LoadOrderGroup -Filter 'Name = "Early-launch"' | Get-CimAssociatedInstance -Association Win32_LoadOrderGroupServiceMembers | Get-ElamCertInfo
Description
-----------
Parse approved ELAM anti-malware signer information from any currently installed ELAM drivers.
.EXAMPLE
Get-ChildItem -Path download | Get-ElamCertInfo
Description
-----------
Parse approved ELAM anti-malware signer information from a directory containing ELAM drivers.
.LINK
https://msdn.microsoft.com/en-us/library/windows/desktop/dn313124
http://www.alex-ionescu.com/?p=146
#>
param (
[Parameter(Position = 0, Mandatory = $True, ValueFromPipelineByPropertyName = $True)]
[ValidateScript({ Test-Path -Path $_ })]
[Alias('PathName')]
[Alias('FullName')]
[String[]]
$Path
)
BEGIN {
# Dnlib.dll should be loaded in the same directory as this script.
$DnlibPath = Join-Path -Path $PSScriptRoot -ChildPath 'dnlib.dll'
# Import dnlib for Win32Resource parsing support
Add-Type -Path $DnlibPath -ErrorAction Stop
$HashAlgorithmTable = @{
[UInt16] 32771 = 'MD5'
[UInt16] 32772 = 'SHA1'
[UInt16] 32780 = 'SHA256'
[UInt16] 32781 = 'SHA384'
[UInt16] 32782 = 'SHA512'
}
}
PROCESS {
foreach ($FilePath in $Path) {
$FullPath = Resolve-Path $FilePath
$PEImage = New-Object -TypeName dnlib.PE.PEImage -ArgumentList $FullPath
if ($PEImage) {
$FileInfo = Get-Item -Path $FullPath
$FileHash = Get-FileHash -Path $FullPath -Algorithm SHA256
$ObjectProperties = [Ordered] @{
CompanyName = $FileInfo.VersionInfo.CompanyName
OriginalFilename = $FileInfo.VersionInfo.OriginalFilename
InternalName = $FileInfo.VersionInfo.InternalName
FileVersion = $FileInfo.VersionInfo.FileVersion
FileDescription = $FileInfo.VersionInfo.FileDescription
FileHash = $FileHash.Hash
ApprovedAntiMalwareSigners = $null
}
$ELAMCertInfo = $PEImage.Win32Resources.Root.Directories | Where-Object { $_.Name -eq 'MSELAMCERTINFOID' }
if ($ELAMCertInfo) {
$MSElamCertInfo = $ELAMCertInfo.Directories | Where-Object { $_.Name -eq 'MICROSOFTELAMCERTIFICATEINFO' }
if ($MSElamCertInfo) {
$ResourceData = $MSElamCertInfo.Data[0].Data
if ($ResourceData) {
$ELAMCertInfoBytes = $ResourceData.ReadBytes($ResourceData.Length)
$AntiMalwareSignerRuleCount = [BitConverter]::ToUInt16($ELAMCertInfoBytes, 0)
$CurrentIndex = 0
$AntiMalwareSignerRules = New-Object -TypeName PSObject[]($AntiMalwareSignerRuleCount)
for ($i = 0; $i -lt $AntiMalwareSignerRuleCount; $i++) {
$CurrentIndex += 2
# Obtain the index of the end of the first string
$TBSHashIndex = $CurrentIndex
while ([BitConverter]::ToUInt16($ELAMCertInfoBytes, $CurrentIndex) -ne 0) { $CurrentIndex += 2 }
$CertTBSHash = [Text.Encoding]::Unicode.GetString($ELAMCertInfoBytes[$TBSHashIndex..($CurrentIndex - 1)])
$CurrentIndex += 2
$HashAlgorithm = $HashAlgorithmTable[[BitConverter]::ToUInt16($ELAMCertInfoBytes, $CurrentIndex)]
$CurrentIndex += 2
$EKUListIndex = $CurrentIndex
while ([BitConverter]::ToUInt16($ELAMCertInfoBytes, $CurrentIndex) -ne 0) { $CurrentIndex += 2 }
$EKUList = $null
if ($CurrentIndex - $EKUListIndex) {
$EKUList = [Text.Encoding]::Unicode.GetString($ELAMCertInfoBytes[$EKUListIndex..($CurrentIndex - 1)])
}
$AntiMalwareSignerRules[$i] = [PSCustomObject] @{
AntiMalwareServiceSignerHash = $CertTBSHash
AntiMalwareServiceSignerHashAlgorithm = $HashAlgorithm
AntiMalwareServiceSignerEKUs = $EKUList
}
}
$ObjectProperties['ApprovedAntiMalwareSigners'] = $AntiMalwareSignerRules
New-Object -TypeName PSObject -Property $ObjectProperties
}
}
}
}
}
}
}
This file has been truncated, but you can view the full file.
View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment