Developers are usually signing their code in order to provide assurance to users that their software is trusted and it has not been modified in a malicious way. This is done with the use of digital signatures.  Therefore signing code is a method to verify the authenticity and integrity of a file.

Threat hunters and blue teams usually check the digital signature of a binary in order to perform an initial check and determine whether or not it should be considered as suspicious. Microsoft defensive technologies such as AppLocker and Device Guard support the use of rules that allow only executables and PowerShell scripts that are coming from trusted publishers and are digitally signed to be executed on the system. This verification is performed through the use of certificates.

Validation of the digital signature can be performed by invoking the Get-AuthenticodeSignature via PowerShell and by using SigCheck utility from Sysinternals.

Verification of Signature
Verification of Signature

Matt Graeber in his keynote talk for DerbyCon 2017 described the process of how to execute unsigned code on a system that is lockdown by a device guard policy by performing a signature verification attack.

Digital Certificates

In modern windows operating systems code signing technology is used to assist users to recognize trusted binaries from untrusted. Native binaries are signed through the use of digital certificates which contain information about the publisher, the private key which is embedded and the public key.

The authenticode signature can be used to segregate signed PowerShell scripts and binaries from unsigned.

Authenticode Signature - PowerShell Scripts
Authenticode Signature – PowerShell Scripts

The certificate of PowerShell scripts can be hijacked easily by copying the signature block  of a digitally signed Microsoft PowerShell script and applying it into a PowerShell script that has not been signed. The following script is part of the Windows ecosystem and has already a Microsoft signature.

C:\Windows\System32\WindowsPowerShell\v1.0\Modules\ISE\ise.psm1
PowerShell Script - Microsoft Digital Signature
PowerShell Script – Microsoft Digital Signature

The CryptSIPDllGetSignedDataMsg contains a registry key which handles the default PowerShell SIP (pwrshsip.dll) and the digital signatures for native Microsoft PowerShell scripts.

HKLM\SOFTWARE\Microsoft\Cryptography\OID\EncodingType 0\CryptSIPDllGetSignedDataMsg\{603BCC1F-4B59-4E08-B724-D2C6297EF351}

The DLL and the FuncName values of this key needs to be replaced with a custom SIP and with the GetLegitMSSignature function. Matt Graeber created a custom SIP (Subject Interface Package) which can be compiled and used in order unsigned PowerShell scripts to get a legitimate Microsoft signature. A compiled version of this DLL can be found on GitHub.

DLL - C:\Users\User\MySIP.dll
FuncName - GetLegitMSSignature
PowerShell Script - Digital Microsoft Signature
PowerShell Script – Digital Microsoft Signature

The legitimate digital signature will be applied to the script and this can be verified by invoking again the Get-AuthenticodeSignature module from a PowerShell console.

Authenticode Signature - PowerShell Script with Digital Signature
Authenticode Signature – PowerShell Script with Digital Signature

However validation of the digital signature will fail as the authenticode hash will be different.

Various tools can be used in order to hijack a certificate from a trusted binary and use it to a non-legitimate binary.

SigThief:

python sigthief.py -i consent.exe -t mimikatz.exe -o signed-mimikatz.exe
Sigthief - Stealing Certificates
Sigthief – Stealing Certificates

SigPirate:

SigPirate.exe -s consent.exe -d mimikatz.exe -o katz.exe -a
SigPirate - Stealing Certificates
SigPirate – Stealing Certiificates

The consent file is an executable which is part of Windows operating system and therefore it is digitally signed by Microsoft. The binary will appear to have a digital signature of Microsoft.

Malicious Binary with Trusted Certificate
Malicious Binary with Trusted Certificate

As previously the digital signature will fail to validate.

Bypassing Signature Validation

The Authenticode is a Microsoft code signing technology that can be used by blue teams to identify the identity of a publisher through the digital certificate and to verify that the binary has not been tampered since it performs a validation of the digital signature hash.

Even if a trusted certificate has been stolen and applied to a malicious binary the digital signature will still be invalid as the authenticode hash will not match. An invalid authenticode hash is a strong indication that the binary is not legitimate. Executing the Get-AuthenticodeSignature from a PowerShell console against a binary that has a trusted certificate will produce a HashMismatch error.

Authenticode Signature - HashMismatch
Authenticode Signature – HashMismatch

The executable code is signed by a private key of the digital certificate. The public key is embedded in the certificate itself. Since the private key is not known it will always fail the hash validation process as the hash will be different.

Therefore the digital signature validation mechanism needs to be weakened through registry modifications. Matt Graeber discovered in which location in the registry the validation of the hash is performed and how. The CryptSIPDllVerifyIndirectData component handles the digital signature validation for PowerShell scripts and for portable executables.

Implementation of the hash validation of the digital signatures is performed via the following registry keys:

  • {603BCC1F-4B59-4E08-B724-D2C6297EF351} // Hash Validation for PowerShell Scripts
  • {C689AAB8-8E78-11D0-8C47-00C04FC295EE} // Hash Validation for Portable Executables

These keys exists in the following registry locations:

HKLM\SOFTWARE\Microsoft\Cryptography\OID\EncodingType 0\CryptSIPDllVerifyIndirectData\{603BCC1F-4B59-4E08-B724-D2C6297EF351}
HKLM\SOFTWARE\Microsoft\Cryptography\OID\EncodingType 0\CryptSIPDllVerifyIndirectData\{C689AAB8-8E78-11D0-8C47-00C04FC295EE}

A legitimate Microsoft DLL file needs to be used because it should be already signed with the same private key. The function name DbgUiContinue is used because it accepts two parameters like the original function that is replacing and returns TRUE if the function CryptSIPDllVerifyIndirectData succeeds.

DLL - C:\Windows\System32\ntdll.dll
FuncName - DbgUiContinue
Bypass Hash Validation - Registry Hijack
Bypass Hash Validation – Registry Hijack

Starting a new PowerShell process will complete the bypass of the hash validation. The malicious binary will appear signed and with a valid Microsoft signature.

Authenticode Signature - Hash Validation
Authenticode Signature – Hash Validation
Digital Signature Details - Valid Hash
Digital Signature Details – Valid Hash

Matt Graeber did the initially discovery of this bypass and it is explained in detail in his paper about Subverting Trust in Windows. He released also a PowerShell script which can be used to automate the signature verification attack.

The script will target the two registry keys where the hash validation of the digital signatures for PowerShell scripts and portable executables is performed.

Signature Verification Attack - Registry Keys
Signature Verification Attack – Registry Keys

The following registry values will be modified automatically with the required values in order to bypass the hash validation.

Signature Verification Attack - Registry Values
Signature Verification Attack – Registry Values

Running the PowerShell script will perform the bypass.

powershell.exe -noexit -file C:\Python34\SignatureVerificationAttack.ps1
Signature Verification Attack - PowerShell Script
Signature Verification Attack – PowerShell Script

Executing the Get-AuthenticodeSignature PowerShell module will result of a valid digital signature hash.

Authenticode Signature - Hash Validation to Malicious Binary
Authenticode Signature – Hash Validation of Malicious Binary

Metadata

Some antivirus companies are relying on the digital signatures and metadata in order to identify malicious files. Therefore antivirus detection rate against a non-legitimate binary that is using a valid certificate and metadata from a trusted entity will be decreased.

MetaTwin is a PowerShell based script that can copy metadata details from a file to another binary automatically.

PS C:\metatwin> Import-Module .\metatwin.ps1
PS C:\metatwin> Invoke-MetaTwin -Source C:\Windows\System32\netcfgx.dll -Target .\mimikatz.exe -Sign
MetaTwin
MetaTwin

On top of that it can steal the digital signature from a Microsoft file since it is using SigThief to perform this task.

MetaTwin - Digital Signature Details
MetaTwin – Digital Signature Details

The final executable will have metadata details and a digital signature from Microsoft.

MetaTwin - Metadata Details
MetaTwin – Metadata Details

This can be verified by checking the details tab from the file properties.

MetaTwin - Metada
MetaTwin – Metadata

If the system has been already modified via the registry in order to bypass the hash validation of the digital signature the malicious binary will look like it is signed from a trusted entity like Microsoft.

MetaTwin - Signed Mimikatz
MetaTwin – Signed Mimikatz

Conclusion

Hijacking a legitimate digital signature and bypassing the hash validation mechanism of Windows can be used by red teams to blend malicious binaries and PowerShell scripts with the native operating system files in order to evade detection and bypass device guard.In a summary:

  • Administrator Access is required to conduct this attack
  • Digitally signed executables will not appear in Autoruns default view
  • Antivirus detection rate is lower for digitally signed code

Blue teams can perform the following two steps as a quick way to determine if digital signature hijack attack has been occurred on the system.

  1. Verify the validity of the digital signature hash with Get-AuthenticodeSignature
  2. Review the following registry keys and values
HKLM\SOFTWARE\Microsoft\Cryptography\OID\EncodingType 0\CryptSIPDllGetSignedDataMsg\{603BCC1F-4B59-4E08-B724-D2C6297EF351}
DLL - C:\Windows\System32\WindowsPowerShell\v1.0\pwrshsip.dll
FuncName - PsGetSignature

HKLM\SOFTWARE\Microsoft\Cryptography\OID\EncodingType 0\CryptSIPDllGetSignedDataMsg\{C689AAB8-8E78-11D0-8C47-00C04FC295EE}
DLL - C:\Windows\System32\ntdll.dll
FuncName - CryptSIPGetSignedDataMsg

HKLM\SOFTWARE\Microsoft\Cryptography\OID\EncodingType 0\CryptSIPDllVerifyIndirectData\{603BCC1F-4B59-4E08-B724-D2C6297EF351}
DLL - C:\Windows\System32\WindowsPowerShell\v1.0\pwrshsip.dll
FuncName - PsVerifyHash

HKLM\SOFTWARE\Microsoft\Cryptography\OID\EncodingType 0\CryptSIPDllVerifyIndirectData\{C689AAB8-8E78-11D0-8C47-00C04FC295EE}
DLL - C:\Windows\System32\WINTRUST.DLL
FuncName - CryptSIPVerifyIndirectData

References

 

3 Comments

  1. thankyou so much for writing such amazing an article. this has helped a lot. it has provided a good piece of information on digital signatures and digital certificates. keep writing. hope to read many such articles in future as well. keep sharing.

Leave a comment