不可导出证书私钥提取方法

admin 2024年2月18日16:14:21评论53 views字数 4221阅读14分4秒阅读模式
概述

        为方便管理用户使用的证书、密码,主流操作系统中都提供了自己的证书/密钥管理系统。

  • Windows 会将证书及私钥存放在证书存储(Certificate Store)中,用户可以使用 Windows 证书管理器查看、导出、导入和删除证书。

  • 钥匙串(Keychain)是 macOS 中的密码管理系统,在 Mac OS 8.6 中被引入。一个钥匙串可以包含多种类型的数据:密码(包括网站、FTP服务器、SSH帐户、网络共享、无线网络等)、私钥、证书等。

  • 钥匙环(Keyring)是 GNOME 提供的密钥管理工具,能够存储密码、密钥、证书,并提供给其它程序使用。

        当系统、应用程序导入包含私钥的证书时,通常会为私钥添加不可导出属性,以防止存储在操作系统中证书私钥数据被第三方获取。例如,在Windows的证书管理器中导出包含不可导出私钥的证书时,私钥导出选项会为灰色:

不可导出证书私钥提取方法

        在macOS的钥匙串中导出时也会弹出如下提示:

不可导出证书私钥提取方法

        而在进行取证调查工作时,我们可能需要获取包含私钥的完整证书,这时就需要绕过操作系统的限制,实现对不可导出的证书私钥的提取。本文将简要介绍在Windows和macOS下的一些提取方法。

01

Windows中的证书私钥

1.1

相关背景

Windows 提供了两套用于存储、使用加密密钥和证书的接口:

  • CryptoAPI (Microsoft Cryptography API)

    提供数据编解码、数据摘要、数据加解密、数据签名及验证、基于证书存储的数字证书管理等功能,支持 PKI 和对称密钥加密。首次引入于 Windows NT 4.0,并在后续版本中得到增强,在当前最新的 Windows 中仍然受到支持。 

    实际的加密操作由加密服务提供程序 (CSP) 执行。

  • CNG (Cryptography API: Next Generation)

    CNG 旨在替代 CryptoAPI,提供了更好的安全性,且兼容 CryptoAPI 1.0 中提供的算法。CNG 提供了新的加密配置系统,提升了加密灵活性,并且支持了椭圆曲线 (ECC) 加密算法;提供线程安全保证;可替换随机数生成器;支持使用内核模式加密;为私钥及相关加密操作提供关键进程隔离, 由托管在 LSASS 进程中 KeyIso 服务  (CNG key isolation service) 实现。CNG 在 Windows Vista、Windows Server 2008 中首次引入。

1.2

由 CryptoAPI 管理的私钥

        在Windows中导入使用 RSA 算法的证书时,系统默认使用的就是 CryptoAPI。

        在 CryptoAPI 中,可以使用 CryptExportKey 导出密钥。CryptExportKey 会检查密钥的属性,对于设置了不可导出属性的密钥,会产生错误 0x8009000B (NTE_BAD_KEY_STATE),表示无权导出该密钥。

        在导出私钥时,CryptExportKey 函数执行流程如下:

不可导出证书私钥提取方法

        但由于但是 CryptoAPI 是在用户空间的用于处理密钥的,因此我们可以从调用过程入手控制其代码执行,对相关函数的实现过程或关键变量进行修改。

        在现有的工具中,mimikatz 是通过修补代码段中的跳转语句来绕过检查的,JNE 指令来覆盖 JMP 指令来改变执行流程,详见于 mimikatz/modules/crypto/kuhl_m_crypto_patch.c 。在 mimikatz 中使用如下命令即可导出包含私钥的证书,其中第一条命令的作用就是修补 CryptoAPI:

crypto::capicrypto::certificates /export

    而 exportrsa 则是基于偏移量为进程内存中的私钥添加 CRYPT_EXPORTABLE 属性来绕过检查:

// Mark the certificate's private key as exportable and archivable*(ULONG_PTR*)(*(ULONG_PTR*)(*(ULONG_PTR*)  #if defined(_M_X64)    (hKey + 0x58) ^ 0xE35A172CD96214A0) + 0x0C)  #elif (defined(_M_IX86) || defined(_ARM_))    (hKey + 0x2C) ^ 0xE35A172C) + 0x08)  #else    #error Platform not supported  #endif    |= CRYPT_EXPORTABLE | CRYPT_ARCHIVABLE;

1.3

由 CNG 管理的私钥

        导入使用 ECC 算法的证书时,由于 CryptoAPI 不支持 ECC 算法,因此会使用 CNG 管理私钥。

由于 CNG 使用了 Keyiso 服务将密钥与使用它们的应用程序完全隔离,且 Keyiso 服务会托管在 LSASS 进程的内存中,而系统对 LSASS 进程的保护级别较高,加之近年来微软对Protected Process Light (PPL) 机制的优化,这意味着想要使用类似前面的通过修改进程内存提取私钥的方法会比较困难,使用 mimikatz 等工具修补 Keyiso 时通常会在打开进程时出现 0x00000005 错误,表示权限不足。

不可导出证书私钥提取方法

        但是,Windows 会使用 DPAPI(数据保护接口)加密存储证书私钥到计算机本地,比如用户证书通常会存储在注册表项 HKEY_CURRENT_USERSOFTWAREMicrosoftSystemCertificates 中,用户的一些个人证书也会存储在 %APPDATA%MicrosoftSystemCertificatesMyCertificates,关联的用户私钥主要加密存储于 %APPDATA%MicrosoftCryptoRSAUser SID (由 CryptoAPI 管理的私钥)和 %APPDATA%MicrosoftCryptoKeys(由 CNG 管理的私钥)。

因此,可以尝试解密这些加密存储的私钥文件,主要流程如下:

  • 确定想要从证书存储中提取的证书的加密私钥文件的存储位置;

  • 获取解密相关私钥所需的 DPAPI 主密钥(MasterKey);

  • 调用 `CryptUnprotectData` 函数解密私钥文件。

    mimikatz 的 dpapi 模块就提供了加密文件的解密功能。

    在本地用户环境下,可以使用如下 mimikatz 命令获取包含私钥的完整证书:

# 解密并导出私钥dpapi::cng /in:"C:Users用户名AppDataRoamingMicrosoftCryptoKeys加密私钥文件" /unprotect# 导出不含私钥的证书crypto::system /file:"C:Users用户名AppDataRoamingMicrosoftSystemCertificatesMyCertificates证书文件" /export# 使用私钥及证书重新创建 PFX 证书crypto::kutil /key:"第一步导出的私钥文件" /cert:"第二步导出的证书文件" /out:2.pfx

在域环境中,用户主密钥的副本使用 DPAPI 备份密钥进行加密,这种备份密钥是所有域控制器中共享的,使用 DPAPI 域备份密钥可以解密任何域用户的主密钥文件。因此可以使用如下 mimikatz 命令获取私钥:

# 获取 PVKlsadump::backupkeys /system:DC CONTROLLER /export# 解密得到域用户的MasterKey值dpapi::masterkey /in: /pvk:导出的PVK文件# 解密并导出私钥dpapi::cng /in:"C:Users用户名AppDataRoamingMicrosoftCryptoKeys加密私钥文件" /masterkey:用户MasterKey /unprotect

02

导出macOS中的证书私钥

        Chainbreaker:https://github.com/n0fate/chainbreaker,可用于以取证方式从钥匙串中提取数据。

        完成工具安装后,执行如下命令,并输入钥匙串解锁密码(默认为归属用户的密码),即可输出钥匙串中存储的证书、私钥、密码等数据到 output 目录下:

python -m chainbreaker -pa ~/Library/Keychains/login.keychain-db -o output

其中,~/Library/Keychains/login.keychain-db 也可以替换成存储在其他位置的钥匙串数据库。

参考文章
  • Exporting Non-exportable RSA Keys:https://research.nccgroup.com/wp-content/uploads/2020/07/exporting_non-exportable_rsa_keys.pdf

  • Certified Pre-Owned Abusing Active Directory Certificate Services:https://specterops.io/wp-content/uploads/sites/3/2022/06/Certified_Pre-Owned.pdf

  • Reading DPAPI Encrypted Keys with MimiKatz:https://www.coresecurity.com/core-labs/articles/reading-dpapi-encrypted-keys-mimikatz

  • Exporting Outlook Private Keys and decrypting S/MIME emails:https://www.errno.fr/OutlookDecrypt/OutlookDecrypt.html

  • ExportNotExportablePrivateKey:https://github.com/luipir/ExportNotExportablePrivateKey/

  • mimikatz:https://github.com/gentilkiwi/mimikatz

  • Chainbreaker:https://github.com/n0fate/chainbreaker

不可导出证书私钥提取方法

不可导出证书私钥提取方法

欢迎关注 Asimov攻防实验室

原文始发于微信公众号(Asimov攻防实验室):不可导出证书私钥提取方法

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年2月18日16:14:21
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   不可导出证书私钥提取方法https://cn-sec.com/archives/2499991.html

发表评论

匿名网友 填写信息