如何通过PowerShell获取文件正确的SignerInfos信息?
问题:读取文件签名者信息时仅获取到反签名者,无法获取目标签名者
我正在编写PowerShell脚本读取文件的所有证书和SignerInfos。当前代码能获取所有证书,但只返回第一个签名者(这个是反签名者,不是我需要的)。目标文件CbDisk.sys在Windows资源管理器中显示有2个签名者,且每个签名者都带有CounterSignature,我需要获取签名者“Carbon Black Inc.”的信息,但脚本只显示“Microsoft Windows Third Party Component CA 2012”作为唯一签名者。我尝试用CryptMsgGetParam()结合CMSG_SIGNER_COUNT_PARAM参数读取签名者数量,结果还是显示只有1个签名者。
以下是当前代码:
# reference links: # embedded C# code template: https://www.sysadmins.lv/blog-en/reading-multiple-signatures-from-signed-file-with-powershell.aspx # MS sample: https://learn.microsoft.com/en-gb/previous-versions/troubleshoot/windows/win32/get-information-authenticode-signed-executables # wincrypt header definitions: https://github.com/dwimperl/perl-5.14.2.1-32bit-windows/blob/master/c/i686-w64-mingw32/include/wincrypt.h cls Remove-Variable * -ea 0 $errorActionPreference = 'stop' $FilePath = "C:\WINDOWS\system32\DRIVERS\CbDisk.sys" Add-Type -TypeDefinition @" using System; using System.Security.Cryptography.Pkcs; using System.Runtime.InteropServices; public static class Crypt32 { [DllImport("crypt32.dll", CharSet = CharSet.Auto, SetLastError = true)] public static extern bool CryptQueryObject( int dwObjectType, [MarshalAs(UnmanagedType.LPWStr)] string pvObject, int dwExpectedContentTypeFlags, int dwExpectedFormatTypeFlags, int dwFlags, ref int pdwMsgAndCertEncodingType, ref int pdwContentType, ref int pdwFormatType, ref IntPtr phCertStore, ref IntPtr phMsg, ref IntPtr ppvContext ); [DllImport("crypt32.dll", CharSet = CharSet.Auto, SetLastError = true)] public static extern bool CryptMsgGetParam( IntPtr hCryptMsg, int dwParamType, int dwIndex, byte[] pvData, ref int pcbData ); [DllImport("crypt32.dll", CharSet = CharSet.Auto, SetLastError = true)] public static extern bool CryptMsgClose(IntPtr hCryptMsg); [DllImport("crypt32.dll", CharSet = CharSet.Auto, SetLastError = true)] public static extern bool CertCloseStore(IntPtr hCertStore, int dwFlags); public static SignedCms GetSignedCmsFromFile(string filePath) { int pdwMsgAndCertEncodingType = 0; int pdwContentType = 0; int pdwFormatType = 0; IntPtr phCertStore = IntPtr.Zero; IntPtr phMsg = IntPtr.Zero; IntPtr ppvContext = IntPtr.Zero; if (!CryptQueryObject( 1, filePath, 0x400, 2, 0, ref pdwMsgAndCertEncodingType, ref pdwContentType, ref pdwFormatType, ref phCertStore, ref phMsg, ref ppvContext )) {return new SignedCms();} int pcbData = 0; CryptMsgGetParam(phMsg, 29, 0, null, ref pcbData); byte[] pvData = new byte[pcbData]; CryptMsgGetParam(phMsg, 29, 0, pvData, ref pcbData); CryptMsgClose(phMsg); SignedCms signedCms = new SignedCms(); signedCms.Decode(pvData); return signedCms; } } "@ -ReferencedAssemblies System.Security # this gets all certs: $cms = [Crypt32]::GetSignedCmsFromFile($FilePath) $certs = $cms.Certificates $certs | ft -AutoSize # this gives me only 1 signer, but not all of them. # also the CounterSignerInfos are always empty here: $signers = $cms.SignerInfos
资源管理器中该文件的签名显示:
内容的提问来源于stack exchange,提问作者Carsten
相关产品推荐
相关产品推荐

