写给蓝军的滥用 DPAPI 操作指南(下)

丝绸之路 内网渗透 2019年6月27日发布
Favorite收藏

导语:提醒一下: 我没有想出下面所要描述的任何内容,我只是记录下来,并尽我所能解释它。 下面所有的荣誉都归功于本杰明在这个领域的杰出工作。

(上篇文章)

证书管理器和 Windows Vault

提醒一下: 我没有想出下面所要描述的任何内容,我只是记录下来,并尽我所能解释它。 下面所有的荣誉都归功于本杰明在这个领域的杰出工作。

Windows 7开始,凭证管理器允许用户存储网站和网络资源的凭证。 凭据文件存储在C:\Users\<USER>\AppData\Local\Microsoft\Credentials\ for users %systemroot%\System32\config\systemprofile\AppData\Local\Microsoft\Credentials\中。 这些文件由用户(或系统)指定的 DPAPI 主密钥保护。

与之相关的是 Windows Vault,它存储在 C:\Users\<USER>\AppData\Local\Microsoft\Vault\<VAULT_GUID>\  中,稍微复杂一些。 vault文件夹中,有一个 Policy.vpol 文件,其中包含两个密钥(AES128 AES256) ,这两个密钥由用户指定的 DPAPI 主密钥保护。 然后使用这两个密钥解密同一个文件夹下的*.vcrd 证书。

这里就有点复杂了。

有几种方法可以获得这些 vaulte 证书。 如果凭据保存的是 Internet ExplorerEdge 的登录信息,则可以使用来自 vaultcli.dll 的一系列 API 调用枚举这些凭据。 这可以通过 Mimikatz vault::list 模块、 Massimiliano Montoro Vault Dump 代码 Matt Graeber PowerShell 端口代码 Dwight Hohnstein C# 版本的Graeber 代码或者 Seatbelt 整合 Dwight C# 代码(Seatbelt.exe DumpVault.)来实现。但是,在运行这些代码库时,你会注意到一些有趣的现象: 并非所有的vault凭据都会返回。 为什么呢? 🤔

你猜怎么着? 本杰明已经在他的Wiki上记录了近一年的确切原因(和变通方法) 下面的描述是对他的 Wiki文章的重新编排,所以我的意思是建议你去阅读他所有的 Wiki

据我所知,vault::list 将列出并尝试从 \AppData\Local\Microsoft\Vault\ 这个位置解密凭证,而 vault::cred 将列出并尝试从\AppData\Local\Microsoft\Credentials\解密凭证。 虽然我不是百分之百的确定凭证为什么以及如何在两个文件夹之间被分开,但是看起来网络凭证似乎是以vault的形式存储的,保存的 RDP 或文件共享凭证似乎是以凭证文件的形式存储的。 正如本杰明所说:

 image.png

https://security.stackexchange.com/questions/173815/view-windows-vault-with-mimikatz/173870#173870

虽然这个链接不再活跃,但我相信这条推文包含了所提到的信息的截图。

正如本杰明在他的 wiki 中详细说明的,微软对于vault凭证声明如下:

如果 Type 成员是 CRED_TYPE_DOMAIN_PASSWORD,则此成员包含用于 UserName 的明文 Unicode 密码。 CredentialBlob CredentialBlobSize成员不包含尾部的零字符。 还有对于 CRED_TYPE_DOMAIN_PASSWORD 此成员只能由身份验证包读取。

所以 LSASS 不希望我们轻易地暴露这些凭据。本杰明描述了两种变通方法。 一个危险的方法是运行 vault::cred /patch LSASS 的逻辑打一次补丁使得 CRED_TYPE_DOMAIN_PASSWORD检查失效。 这是绝对不推荐的(本杰明如是说) ,因为操控 LSASS 逻辑是一个有风险的操作,可能导致事情出错。 除此之外,还有一个更好的方法: moar DPAPI

本杰明描述了我们在这里遇到的另一个问题 根据微软的说法,"LSA 线程可以使用 DPAPI 并指定 CRYPTPROTEC_SYSTEM标志来保护在 LSA 之外不能得到保护的数据。" . 因此,如果尝试使用 CryptUnprotectData ( /unprotect)对这些类型的数据块进行解密,就会出现错误。 但是,如果我们检查其中一个数据块,我们可以看到用于加密它的 DPAPI 主密钥:

 image.png

如果你知道用户的明文密码,你可以使用来自 Chrome 的方法: 场景1轻松地解密这个主密钥。 如果你没有解密成功,不要担心,Mimikatz依旧爱着你。

正如本杰明详细介绍的,MS-BKRP (Microsoft BackupKey Remote Protocol)的一个组件,它运行在域控制器上的 RPC 服务器,该控制器通过其域范围内的 DPAPI 备份密钥为授权用户处理 DPAPI 密钥的解密。换句话说,如果我们当前的用户上下文"拥有"一个给定的主密钥,我们可以很好地请求一个域控制器来为我们解密这个主密钥! 这不是一个"漏洞",这也是一个设计方式,并且这意味着一种在用户更改或丢失密码的情况下的故障保护措施,并支持各种智能卡的功能。

因此,如果我们简单地从拥有主密钥的用户上下文中运行 mimikatz # dpapi::masterkey /in:”%appdata%\Microsoft\Protect\<SID>\<MASTER_KEY_GUID>” /rpc (类似于 Chrome 的场景3) Mimikatz 将要求当前域控制器(通过 RPC)解密主密钥:

 image.png

现在我们可以使用带有 dpapi::cred 模块的 / masterkey:X 标志来解密保存的凭证!

更妙的是,由于我们没有涉及 LSASS,我们可以在没有任何提升特权的情况下为当前用户执行此方法。 如果我们想对其他用户执行这种类型的"攻击"Chrome 部分的场景2-4仍然适用。

"那么计划任务凭证呢? ? ! !" 你可能(不)是在问。 本杰明也提到了我们所说的这一点 你可以从内存(使用 sekurlsa::dpapi) LSA (使用 lsadump::secrets)提取系统的 DPAPI 密钥,然后使用该密钥解密%systemroot%\System32\config\systemprofile\AppData\Local\Microsoft\Credentials 中保存的凭据。

但是,加密文件系统(EFS)的文件该怎么处理呢?,你可能也(不)会问。 令人惊讶的是,本杰明也提到了这一点🙂

甚至还有一种解密 Windows 10 SSH 原生 SSH 密钥的方法,其中包括本杰明提供的一个很好的演示视频 还有一些模块用于 dpapi::wifi dpapi::wwan (文件位置见此推文)以及其他模块。

 image.png

远程桌面连接管理器

在我起草这篇文章的时候,本杰明发布了更多的 DPAPI

 image.png

Windows 远程桌面连接管理器可以选择保存 RDP 连接凭据,明文密码同样存储为 DPAPI 数据块。 这些配置文件存储在 .rdg 文件中,可以用新的 dpapi::rdg 模块解密。 这个模块还没有出现在 Beacon mimikatz 模块中,但应该会在下一个或两个更新中出现。 /unprotectplaintext/hash sekurlsa::DPAPI masterkey 或者域备份密钥(参见 Chrome 场景1-4)同样也可以在这里工作:

image.png 

请参阅本文的安全带章节,了解如何轻松枚举这些文件。

旁注: Mimikatz DPAPI 缓存

正如本文前面提到的,由于 Beacon 的作业架构,每个 mimikatz 命令都将在一个新的进程中运行,因此 mimikatz 命令之间不会保留状态。 但是,本杰明实现了一个非常酷炫的 DPAPI 特性(缓存) ,我希望确保能够提及这个特性。

如果你使用的是 mimimikatz.exe 独立缓存,Mimikatz 会将检索到的所有 DPAPI 密钥添加到一个 volatile 缓存中,供以后使用。 因此,例如,如果你检索域备份 DPAPI 密钥,然后你可以解密任何你想要的主密钥,它也将被添加到缓存中:

 image.png

image.png

 

 image.png

你还可以为每次重用保存或加载缓存:

 image.png

安全带

我最近将一些与 DPAPI 相关的文件检查整合到了安全带(更多关于安全带或ghostpack 的信息请点击这里) Seatbelt.exe MasterKeys将搜索用户主密钥,无论是当前用户还是所有用户,如果上下文的权限是升级过的。 这个检查现在也是 SeatBelt.exe user 检查的默认选项:

 image.png

凭据文件用 CredFiles 命令枚举,现在也是默认用户检查,也应用于相同的用户/提升枚举:

 image.png

远程桌面连接管理器设置和 .rdg 文件用 RDCManFiles 命令枚举,现在也是默认的用户检查,同样也应用于 用户或提升的枚举:

 image.png

现在还有一些额外的上下文,用于在默认用户检查时发现浏览器 cookie 文件(包括 Chrome) :

 image.png

这将指引你到合适的安全带指令,Mimikatz 模块,或者@djhohnstein 的令人敬畏的新 SharpWeb 项目中的指令。

防御

防止这些类型的 DPAPI 滥用是很困难的事情,主要是因为这只是滥用预期的或现有的功能。 阅读和解密 DPAPI blobs 是系统和应用程序一直在做的事情,因此没有太多机会捕获异常。

要从内存中提取 DPAPI 密钥,应该应用 Mimikatz/LSASS 读取的标准防御指南。

我不确定使用 BackupKey 远程协议(MS-BKRP)或远程 DPAPI 备份密钥检索的最佳防御指南是什么,但我想就每个方面提出一些想法。

微软确实为 Windows 10 Server 2016实现了一组事件日志,以允许审计 DPAPI 的活动,但是对于所有事件都声明,"这个子类别中的事件通常具有信息目的,并且很难通过这些事件检测到任何恶意活动。 主要用于 DPAPI 故障排除。" 对于事件4695("未尝试保护可审计的受保护数据") ultimatewindowssecurity.com 指示的注释为:"这个事件可能表明恶意行为,但是我也看到它在一个干净的、隔离的测试系统的正常操作过程中被记录。" 因此,虽然这些特定的事件需要一些额外的侦查潜力的调查,他们可能不是高精确度的指标。

BackupKey 远程协议

当我通过 MS-BKRP  调用  dpapi::masterkey /in:<KEY> /rpc这个 mimitz 模块从系统执行 masterkey 检索时,网络流量包括:

· SMB 连接到远程系统的 IPC$接口

· 在远程系统上创建保护存储器(protected_storage命名管道

· 几个通过 SMB 的带有使用加密的存根数据部分的[ MS-RPCE ]RPC 调用

· 从名为 protected_storage 的命名管道中读取备份密钥

· 清理

· 然而,由于这个协议在现代领域中有很多正常用途,尝试对这个流量进行签名似乎不太有效。

远程 LSA 秘钥检索

当我从我的系统执行远程 LSA 秘钥检索到我的测试域控制器时,网络流量包括

· 连接到远程系统的 IPC$ 接口的 SMB 连接

· 在远程系统上创建 lsarpc 命名管道

· lsa_OpenPolicy2 RPC 调用 (通过 SMB[MS-RPCE] RPC)opnum 44

· lsa_RetrievePrivateData RPC 调用,opnum 43

·  lsarpc 命名管道读取备份密钥

· 清理

我还试图查看在这次远程 LSA 秘钥检索期间是否在 DC 上创建了任何特定的事件日志,但无法发现任何有用的信息。 如果有人知道如何调整 DC 的事件日志来检测远程 LSA 秘钥读取,请让我知道,我会更新这篇文章。

微软高级威胁分析可疑活动指南确实有一个"恶意数据保护隐私信息请求"的条目:

 image.png

然而,我不确定他们是如何实现这种检测的,也不确定这个指标的精确度。

总结

DPAPI是个很酷的东西。 我对自己没有花时间去正确理解本杰明在这个领域所做的所有伟大工作以及我们以前忽视的所有机会感到沮丧,但是我很高兴在我们的工具箱里有另一个 TTP

再次感谢@gentilkiwi 对本文所提及的研究、工具集和反馈所做的工作!

本文翻译自:https://posts.specterops.io/operational-guidance-for-offensive-user-dpapi-abuse-1fb7fac8b107如若转载,请注明原文地址: https://www.4hou.com/system/18777.html
点赞 0
  • 分享至
取消

感谢您的支持,我会继续努力的!

扫码支持

打开微信扫一扫后点击右上角即可分享哟

发表评论