WDACSimulation/Get-NestedSignerSignature.psm1
Function Get-NestedSignerSignature { <# .SYNOPSIS Helps to get the 2nd aka nested signer/signature of the dual signed files .NOTES This function is used in a very minimum capacity by the WDACConfig module and it's been modified to meet the WDACConfig's requirements .PARAMETER FilePath The path of the file to get the nested signature of .INPUTS System.IO.FileInfo .OUTPUTS System.Management.Automation.Signature #> [CmdletBinding()] [OutputType([System.Management.Automation.Signature])] param( [Parameter(Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)] [System.IO.FileInfo]$FilePath ) begin { # Detecting if Verbose switch is used $PSBoundParameters.Verbose.IsPresent ? ([System.Boolean]$Verbose = $true) : ([System.Boolean]$Verbose = $false) | Out-Null # Importing the $PSDefaultParameterValues to the current session, prior to everything else . "$ModuleRootPath\CoreExt\PSDefaultParameterValues.ps1" # Load the System.Security assembly to use the SignedCms class Add-Type -AssemblyName 'System.Security' -ErrorAction SilentlyContinue # Add the Crypt32.dll library functions as a type if they don't exist if (-NOT ('WDACConfig.Crypt32DLL' -as [System.Type]) ) { Add-Type -Path "$ModuleRootPath\C#\Crypt32dll.cs" } # Define some constants for the CryptQueryObject function parameters [System.Int16]$CERT_QUERY_OBJECT_FILE = 0x1 [System.Int32]$CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED_EMBED = 0x400 [System.Int16]$CERT_QUERY_FORMAT_FLAG_BINARY = 0x2 function Get-TimeStamps { <# .SYNOPSIS Helper function to get the timestamps of the CounterSigner .INPUTS System.Security.Cryptography.Pkcs.SignerInfo .OUTPUTS System.Object[] #> param ( [System.Security.Cryptography.Pkcs.SignerInfo]$SignerInfo ) # Initialize an array to store the custom objects with CounterSigner info [System.Object[]]$RetValue = @() foreach ($CounterSignerInfos in $Infos.CounterSignerInfos) { # Get the signing time attribute from the CounterSigner info object $STime = ($CounterSignerInfos.SignedAttributes | Where-Object -FilterScript { $_.Oid.Value -eq '1.2.840.113549.1.9.5' }).Values | Where-Object -FilterScript { $null -ne $_.SigningTime } # Create a custom object with the CounterSigner certificate and signing time properties $TsObject = New-Object 'psobject' -Property @{ Certificate = $CounterSignerInfos.Certificate SigningTime = $STime.SigningTime.ToLocalTime() } # Add the custom object to the return value array $RetValue += $TsObject } # Return the array of custom objects with CounterSigner info Return $RetValue } } process { # For each file path, get the authenticode signature using the built-in cmdlet foreach ($Output in Get-AuthenticodeSignature -LiteralPath $FilePath) { # Initialize some variables to store the output parameters of the CryptQueryObject function [System.Int64]$PdwMsgAndCertEncodingType = 0 [System.Int64]$PdwContentType = 0 [System.Int64]$PdwFormatType = 0 [System.IntPtr]$PhCertStore = [System.IntPtr]::Zero [System.IntPtr]$PhMsg = [System.IntPtr]::Zero [System.IntPtr]$PpvContext = [System.IntPtr]::Zero # Call the CryptQueryObject function to get the handle of the PKCS #7 message from the file path $Return = [WDACConfig.Crypt32DLL]::CryptQueryObject( $CERT_QUERY_OBJECT_FILE, $Output.Path, $CERT_QUERY_CONTENT_FLAG_PKCS7_SIGNED_EMBED, $CERT_QUERY_FORMAT_FLAG_BINARY, 0, [ref]$pdwMsgAndCertEncodingType, [ref]$pdwContentType, [ref]$pdwFormatType, [ref]$phCertStore, [ref]$phMsg, [ref]$ppvContext ) # If the function fails, return nothing if (!$Return) { return } # Initialize a variable to store the size of the PKCS #7 message data [System.Int64]$PcbData = 0 # Call the CryptMsgGetParam function to get the size of the PKCS #7 message data $Return = [WDACConfig.Crypt32DLL]::CryptMsgGetParam($phMsg, 29, 0, $null, [ref]$PcbData) # If the function fails, return nothing if (!$Return) { return } # Create a byte array to store the PKCS #7 message data [System.Byte[]]$PvData = New-Object -TypeName 'System.Byte[]' -ArgumentList $PcbData # Call the CryptMsgGetParam function again to get the PKCS #7 message data $Return = [WDACConfig.Crypt32DLL]::CryptMsgGetParam($PhMsg, 29, 0, $PvData, [System.Management.Automation.PSReference]$PcbData) # Create a SignedCms object to decode the PKCS #7 message data [System.Security.Cryptography.Pkcs.SignedCms]$SignedCms = New-Object -TypeName 'Security.Cryptography.Pkcs.SignedCms' # Decode the PKCS #7 message data and populate the SignedCms object properties $SignedCms.Decode($PvData) # Get the first signer info object from the SignedCms object $Infos = $SignedCms.SignerInfos[0] # Add some properties to the output object, such as TimeStamps, DigestAlgorithm and NestedSignature $Output | Add-Member -MemberType NoteProperty -Name TimeStamps -Value $null $Output | Add-Member -MemberType NoteProperty -Name DigestAlgorithm -Value $Infos.DigestAlgorithm.FriendlyName # Call the helper function to get the timestamps of the CounterSigner and assign it to the TimeStamps property $Output.TimeStamps = Get-TimeStamps -SignerInfo $Infos # Check if there is a nested signature attribute in the signer info object by looking for the OID 1.3.6.1.4.1.311.2.4.1 $Second = $Infos.UnsignedAttributes | Where-Object -FilterScript { $_.Oid.Value -eq '1.3.6.1.4.1.311.2.4.1' } if ($Second) { # If there is a nested signature attribute # Get the value of the nested signature attribute as a raw data byte array $Value = $Second.Values | Where-Object -FilterScript { $_.Oid.Value -eq '1.3.6.1.4.1.311.2.4.1' } # Create another SignedCms object to decode the nested signature data [System.Security.Cryptography.Pkcs.SignedCms]$SignedCms2 = New-Object -TypeName 'Security.Cryptography.Pkcs.SignedCms' # Decode the nested signature data and populate the SignedCms object properties $SignedCms2.Decode($Value.RawData) $Output | Add-Member -MemberType NoteProperty -Name NestedSignature -Value $null # Get the first signer info object from the nested signature SignedCms object $Infos = $SignedCms2.SignerInfos[0] # Create a custom object with some properties of the nested signature, such as signer certificate, digest algorithm and timestamps $Nested = New-Object -TypeName 'psobject' -Property @{ SignerCertificate = $Infos.Certificate DigestAlgorithm = $Infos.DigestAlgorithm.FriendlyName TimeStamps = Get-TimeStamps -SignerInfo $Infos } # Assign the custom object to the NestedSignature property of the output object $Output.NestedSignature = $Nested } # Close the handles of the PKCS #7 message and the certificate store [System.Void][WDACConfig.Crypt32DLL]::CryptMsgClose($PhMsg) [System.Void][WDACConfig.Crypt32DLL]::CertCloseStore($PhCertStore, 0) } } End { # Return the output object with the added properties Return $Output } } Export-ModuleMember -Function 'Get-NestedSignerSignature' # SIG # Begin signature block # MIILkgYJKoZIhvcNAQcCoIILgzCCC38CAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCCwG/qIkwoxGi1v # AY70GdZI8htbl9J1IpskXi4hnc4fGaCCB9AwggfMMIIFtKADAgECAhMeAAAABI80 # LDQz/68TAAAAAAAEMA0GCSqGSIb3DQEBDQUAME8xEzARBgoJkiaJk/IsZAEZFgNj # b20xIjAgBgoJkiaJk/IsZAEZFhJIT1RDQUtFWC1DQS1Eb21haW4xFDASBgNVBAMT # C0hPVENBS0VYLUNBMCAXDTIzMTIyNzExMjkyOVoYDzIyMDgxMTEyMTEyOTI5WjB5 # MQswCQYDVQQGEwJVSzEeMBwGA1UEAxMVSG90Q2FrZVggQ29kZSBTaWduaW5nMSMw # IQYJKoZIhvcNAQkBFhRob3RjYWtleEBvdXRsb29rLmNvbTElMCMGCSqGSIb3DQEJ # ARYWU3B5bmV0Z2lybEBvdXRsb29rLmNvbTCCAiIwDQYJKoZIhvcNAQEBBQADggIP # ADCCAgoCggIBAKb1BJzTrpu1ERiwr7ivp0UuJ1GmNmmZ65eckLpGSF+2r22+7Tgm # pEifj9NhPw0X60F9HhdSM+2XeuikmaNMvq8XRDUFoenv9P1ZU1wli5WTKHJ5ayDW # k2NP22G9IPRnIpizkHkQnCwctx0AFJx1qvvd+EFlG6ihM0fKGG+DwMaFqsKCGh+M # rb1bKKtY7UEnEVAsVi7KYGkkH+ukhyFUAdUbh/3ZjO0xWPYpkf/1ldvGes6pjK6P # US2PHbe6ukiupqYYG3I5Ad0e20uQfZbz9vMSTiwslLhmsST0XAesEvi+SJYz2xAQ # x2O4n/PxMRxZ3m5Q0WQxLTGFGjB2Bl+B+QPBzbpwb9JC77zgA8J2ncP2biEguSRJ # e56Ezx6YpSoRv4d1jS3tpRL+ZFm8yv6We+hodE++0tLsfpUq42Guy3MrGQ2kTIRo # 7TGLOLpayR8tYmnF0XEHaBiVl7u/Szr7kmOe/CfRG8IZl6UX+/66OqZeyJ12Q3m2 # fe7ZWnpWT5sVp2sJmiuGb3atFXBWKcwNumNuy4JecjQE+7NF8rfIv94NxbBV/WSM # pKf6Yv9OgzkjY1nRdIS1FBHa88RR55+7Ikh4FIGPBTAibiCEJMc79+b8cdsQGOo4 # ymgbKjGeoRNjtegZ7XE/3TUywBBFMf8NfcjF8REs/HIl7u2RHwRaUTJdAgMBAAGj # ggJzMIICbzA8BgkrBgEEAYI3FQcELzAtBiUrBgEEAYI3FQiG7sUghM++I4HxhQSF # hqV1htyhDXuG5sF2wOlDAgFkAgEIMBMGA1UdJQQMMAoGCCsGAQUFBwMDMA4GA1Ud # DwEB/wQEAwIHgDAMBgNVHRMBAf8EAjAAMBsGCSsGAQQBgjcVCgQOMAwwCgYIKwYB # BQUHAwMwHQYDVR0OBBYEFOlnnQDHNUpYoPqECFP6JAqGDFM6MB8GA1UdIwQYMBaA # FICT0Mhz5MfqMIi7Xax90DRKYJLSMIHUBgNVHR8EgcwwgckwgcaggcOggcCGgb1s # ZGFwOi8vL0NOPUhPVENBS0VYLUNBLENOPUhvdENha2VYLENOPUNEUCxDTj1QdWJs # aWMlMjBLZXklMjBTZXJ2aWNlcyxDTj1TZXJ2aWNlcyxDTj1Db25maWd1cmF0aW9u # LERDPU5vbkV4aXN0ZW50RG9tYWluLERDPWNvbT9jZXJ0aWZpY2F0ZVJldm9jYXRp # b25MaXN0P2Jhc2U/b2JqZWN0Q2xhc3M9Y1JMRGlzdHJpYnV0aW9uUG9pbnQwgccG # CCsGAQUFBwEBBIG6MIG3MIG0BggrBgEFBQcwAoaBp2xkYXA6Ly8vQ049SE9UQ0FL # RVgtQ0EsQ049QUlBLENOPVB1YmxpYyUyMEtleSUyMFNlcnZpY2VzLENOPVNlcnZp # Y2VzLENOPUNvbmZpZ3VyYXRpb24sREM9Tm9uRXhpc3RlbnREb21haW4sREM9Y29t # P2NBQ2VydGlmaWNhdGU/YmFzZT9vYmplY3RDbGFzcz1jZXJ0aWZpY2F0aW9uQXV0 # aG9yaXR5MA0GCSqGSIb3DQEBDQUAA4ICAQA7JI76Ixy113wNjiJmJmPKfnn7brVI # IyA3ZudXCheqWTYPyYnwzhCSzKJLejGNAsMlXwoYgXQBBmMiSI4Zv4UhTNc4Umqx # pZSpqV+3FRFQHOG/X6NMHuFa2z7T2pdj+QJuH5TgPayKAJc+Kbg4C7edL6YoePRu # HoEhoRffiabEP/yDtZWMa6WFqBsfgiLMlo7DfuhRJ0eRqvJ6+czOVU2bxvESMQVo # bvFTNDlEcUzBM7QxbnsDyGpoJZTx6M3cUkEazuliPAw3IW1vJn8SR1jFBukKcjWn # aau+/BE9w77GFz1RbIfH3hJ/CUA0wCavxWcbAHz1YoPTAz6EKjIc5PcHpDO+n8Fh # t3ULwVjWPMoZzU589IXi+2Ol0IUWAdoQJr/Llhub3SNKZ3LlMUPNt+tXAs/vcUl0 # 7+Dp5FpUARE2gMYA/XxfU9T6Q3pX3/NRP/ojO9m0JrKv/KMc9sCGmV9sDygCOosU # 5yGS4Ze/DJw6QR7xT9lMiWsfgL96Qcw4lfu1+5iLr0dnDFsGowGTKPGI0EvzK7H+ # DuFRg+Fyhn40dOUl8fVDqYHuZJRoWJxCsyobVkrX4rA6xUTswl7xYPYWz88WZDoY # gI8AwuRkzJyUEA07IYtsbFCYrcUzIHME4uf8jsJhCmb0va1G2WrWuyasv3K/G8Nn # f60MsDbDH1mLtzGCAxgwggMUAgEBMGYwTzETMBEGCgmSJomT8ixkARkWA2NvbTEi # MCAGCgmSJomT8ixkARkWEkhPVENBS0VYLUNBLURvbWFpbjEUMBIGA1UEAxMLSE9U # Q0FLRVgtQ0ECEx4AAAAEjzQsNDP/rxMAAAAAAAQwDQYJYIZIAWUDBAIBBQCggYQw # GAYKKwYBBAGCNwIBDDEKMAigAoAAoQKAADAZBgkqhkiG9w0BCQMxDAYKKwYBBAGC # NwIBBDAcBgorBgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAvBgkqhkiG9w0BCQQx # IgQgPti7rGaGdt/b735AkAeA4QVEZ1NsB+bPFaKweh9IHDswDQYJKoZIhvcNAQEB # BQAEggIAghWhefd87gkodrLMsrt115GIZpa5U/9AbgM3JnKO/fqGJoIudAIFQjeW # qSfKc9MFIa/qadgAKGhEC5GmOo1mrKiK3/CV+8SFVmEgyH4yolKZeX1rrSyzdTA0 # pCdOgjpm04h7SC/a/OTYr1GiQ/u/jgy7LZgpvJEhHtoRrlOwXRxNRBRz13MqS0U+ # 61Ykgiflu7kTdXbsCMIwIk1jSspBdgZFPhQs9svBG1wsxxWS5Tb1lBDn7xASEkzJ # rAYLGGM2RTM6IzD/CC2KIVHHeU606doTUeXg0YDuxKv4nbJF41YfNlli0zt4iJ8N # UOzYxJeTBLHeTDWgWdbYsiAmxdveLbgyUeL+lylkxoeI5I3CWWm1hwrgHTgtBM90 # +Vext6URSgpeYZkQ0hxU2VGWprKiS3SpT+/iFplYLp13cqeBwUnuTOjnL5GfFziU # Z0f07f8HwF2RvrHrsQrkSz40c32AOSHNaXzhqiz/cCfdhy3Dx28U69ilPPM4Selx # irr4u5wB4cMSW56ZwMsQwI2jx7aR37wT1/rcVkUtM9izGPGycpSiRKDLrIYrYqRO # VQMsy4H7Nh7mdZPPrw6iRgOp1eWfe4THfpohfUBuaAZF/O4Lw4fTl4V1T+mN1UaJ # RLaWpOV8NiLNSnmgiaydH2s/Nsk6VTwHH9fAZ1uQ2K8Ypo13v8A= # SIG # End signature block |