开卷有益 · 不求甚解
防守方对 msDS-KeyCredentialLink 的看法
TL;博士;
本文是关于我跟踪 msDS-KeyCredentialLink 属性更改以验证其来源是否合法或潜在攻击(又名影子凭据)的旅程。如果你只是想知道它的“要点”,向下滚动到底部,你会找到一个思维导图。
msDS-KeyCredentialLink(又名“kcl”)属性可用于将 RSA 密钥对与计算机或用户对象链接,以便针对 KDC 使用所述密钥对进行身份验证以接收 Kerberos TGT。因此,kcl 实际上是一组与用户名/密码一起使用的备用凭据。关于 msDS-KeyCredentialLink 的一个极好的信息来源是Michael Grafnetters 在 Black Hat 2019 上的演讲以及他著名的 powershell 模块DSInternals。我强烈建议您观看他的演讲,因为他还解释了 msDS-KeyCredentialLink 和 Windows Hello 企业版 (WHfB) 之间的关系。
快进几年,操纵 kcl 已成为一种众所周知的攻击技术,称为“影子凭证” ,如果您不熟悉该主题,我特别推荐Elad Shamir 的这篇文章和Charlie Bromberg 的这篇文档以获取更多详细信息. 简而言之:如果攻击者可以编写帐户的 kcl,他/她将能够冒充该帐户以获得访问权限或持久性。可以通过 ACL 错误配置、控制另一个高特权帐户或通过中继 (NTLM) 身份验证来实现对 kcl 的写访问。NTLM-relay-scenario 实际上是让我研究此事的原因,原因有两个:
可以通过常见的“审核目录服务更改”子类别跟踪此属性的操作,从而导致事件5136: A directory service object was modified
。查看 elastic 的这篇文章,了解如何启用审计,不要忘记为用户和计算机对象设置适当的 SACL。
以下是此类恶意事件的外观。Subject
指演员,而是Object
被修改的帐户。
A directory service object was modified.
Subject:
Security ID: NETCORP\evil
Account Name: evil
Account Domain: NETCORP
Logon ID: 0xBCDACDirectory Service:
Name: netcorp.at
Type: Active Directory Domain Services
Object:
DN: CN=pc1,OU=Client,OU=Computer,OU=company,DC=netcorp,DC=at
GUID: CN=pc1,OU=Client,OU=Computer,OU=company,DC=netcorp,DC=at
Class: computer
Attribute:
LDAP Display Name: msDS-KeyCredentialLink
Syntax (OID): 2.5.5.7
Value: B:828:<Binary>:CN=adlab-01,OU=Client,OU=Computer,OU=company,DC=netcorp,DC=at
Operation:
Type: Value Added
Correlation ID: {5bff0e70-432c-4ae9-9081-06675dba7869}
Application Correlation ID: -
现在我们已经开始收集这些事件,我们必须想办法验证单个事件的合法性。例如,上述事件的主客体不同,但这是否总是一个有用的指标?事实证明,答案在很大程度上取决于您的个人环境,并且如果您指的是计算机或用户对象,则会有所不同。因此,有必要识别调用 kcl 属性修改的合法用例。我将在以下部分中描述对我来说最常见的两种情况,但这不是一个完整的列表。正如 Michael Grafnetter 在他的演讲中所展示的,可能会有更多(未记录的)用例。
如果您在 Internet 上搜索有关 kcl 的信息,您最终会阅读很多有关 Windows Hello 企业版 (WHfB) 的信息。有大量关于 WHfB 的非常好的文档可用,它比我能更好地解释细节(包括前面提到的 Michael Grafnetter 的演讲),所以我不会在这篇文章中介绍它。
简短的故事是:在 WHfB 注册期间,用户将生成一个密钥对并将公钥链接到 AAD 中的用户对象。在下一个同步周期中,Azure AD Connect 会将此公钥同步到本地 AD 中用户对象的 msDS-KeyCredentialLink 属性以及一些其他信息。请注意,这是指启用了 WHfB 的混合 AAD 加入环境。
在这种情况下生成的修改事件如下所示:
A directory service object was modified.
Subject:
Security ID: netcorp\MSOL_8bee7c7b05af
Account Name: MSOL_8bee7c7b05af
Account Domain: netcorp
Logon ID: 0xAFEC9FDirectory Service:
Name: netcorp.at
Type: Active Directory Domain Services
Object:
DN: CN=whfbuser,OU=WHFB,OU=DomainUser,OU=User,OU=company,DC=netcorp,DC=at
GUID: CN=whfbuser,OU=WHFB,OU=DomainUser,OU=User,OU=company,DC=netcorp,DC=at
Class: user
Attribute:
LDAP Display Name: msDS-KeyCredentialLink
Syntax (OID): 2.5.5.7
Value: B:854:<Binary>:CN=whfbuser,OU=WHFB,OU=DomainUser,OU=User,OU=company,DC=netcorp,DC=at
Operation:
Type: Value Added
Correlation ID: {10148d86-8374-4197-84d6-586a201dfa4b}
Application Correlation ID: -
如果您在没有 WHfB 甚至没有混合 AAD 加入的环境中看到这样的事件,那么这显然是一个危险信号。因此,对于以下检测和验证工作流程,我们将假设我们生活在这样的环境中,并希望确保它实际上是一个合法事件。
让我们尝试浏览我们拥有的信息。关注上面的事件数据,我们看到主题/参与者是 AAD Connect 同步帐户。通常,这应该是修改此属性的唯一帐户。另外,请注意对象类是user
. 如果用户注册 WHfB,则密钥将写入用户对象,而不是用户通过注册的计算机对象。该事件还包含一个登录 ID,它是将修改事件 5136 链接到登录事件 4624 的唯一标识符。下面是相应的示例。
An account was successfully logged on.Subject:
Security ID: NULL SID
Account Name: -
Account Domain: -
Logon ID: 0x0
Logon Information:
Logon Type: 3
Restricted Admin Mode: -
Virtual Account: No
Elevated Token: Yes
Impersonation Level: Impersonation
New Logon:
Security ID: netcorp\MSOL_8bee7c7b05af
Account Name: MSOL_8bee7c7b05af
Account Domain: NETCORP.AT
Logon ID: 0xAFEC9F
Linked Logon ID: 0x0
Network Account Name: -
Network Account Domain: -
Logon GUID: {a095cd77-3ac7-c998-61d3-9995308dc76d}
Process Information:
Process ID: 0x0
Process Name: -
Network Information:
Workstation Name: -
Source Network Address: fe80::2d5f:1c5a:ede5:89c8
Source Port: 54856
Detailed Authentication Information:
Logon Process: Kerberos
Authentication Package: Kerberos
Transited Services: -
Package Name (NTLM only): -
Key Length: 0
在该事件中密切关注源网络地址。这允许您验证身份验证是否确实来自运行 AAD Connect 的服务器,这已经为您提供了三个验证指标:
如果您对所有三个问题都回答“是”,那么我会说这已经是一个强有力的论点,但我们可以走得更远。让我们看看使用 DSInternals 的 AD 中的 kcl 属性。
Get-ADUser -Identity whfbuser -Properties * | select -expand msds-keycredentiallink | Get-ADKeyCredential
用户“whfbuser”注册了两个凭据。每个凭据都与一个设备 ID 相关联,该设备 ID 映射到 AAD 中计算机对象的设备 ID 属性。在撰写本文时,像Whisker这样的公共攻击工具只是生成一个随机 GUID,因为没有可关联的真实设备。我们可以使用 AzureAD powershell 从防御的角度检查这一点。
Get-AzureADDevice | ? {$_.deviceid -eq "<device-id>"}
我们可以看到两个凭证都映射到现有设备,我们现在可以使用来自第三方数据库(如 CMDB)的信息来检查这些设备是否真正属于用户。同样,根据攻击者已经拥有的访问权限,这并不是万无一失的,但仍然没有那么糟糕。作为最后的验证步骤,我们可以联系客户端以获取生成的公钥,并验证这是否真的是存储在 kcl 属性中的同一个公钥。Stephan Waelde 在他的博客文章中描述了如何从设备到 Azure AD 并返回到本地 AD ,因此我将向您推荐他的指南。
最后,我们可以将到目前为止我们学到的所有东西都放在一个漂亮的思维导图中。
Credential Guard 的使用是鲜为人知的(至少据我所知)kcl 人口的触发器之一。Microsoft 文档的这篇文章中只是简要提到了它。
此操作的相应事件 5136 如下所示。
A directory service object was modified.
Subject:
Security ID: NETCORP\PC1$
Account Name: PC1$
Account Domain: NETCORP
Logon ID: 0xA170DDirectory Service:
Name: netcorp.at
Type: Active Directory Domain Services
Object:
DN: CN=pc1,OU=Client,OU=Computer,OU=company,DC=netcorp,DC=at
GUID: CN=pc1,OU=Client,OU=Computer,OU=company,DC=netcorp,DC=at
Class: computer
Attribute:
LDAP Display Name: msDS-KeyCredentialLink
Syntax (OID): 2.5.5.7
Value: B:754:<Binary>:CN=pc1,OU=Client,OU=Computer,OU=company,DC=netcorp,DC=at
Operation:
Type: Value Added
Correlation ID: {cb1839a0-32c4-4843-bf57-a5b5308dbd73}
Application Correlation ID: -
可以看到主客体是相同的,这使得我们很难仅从事件数据中得出有用的结论。如果我们考虑通过 NTLM 中继引入的恶意更改,这将成为一个更大的问题,如开头所述。这是使用 ntlmrelayx 进行 NTLM 中继攻击后此事件的处理方式。
A directory service object was modified.
Subject:
Security ID: netcorp\PC1$
Account Name: PC1$
Account Domain: netcorp
Logon ID: 0x125BAFDirectory Service:
Name: netcorp.at
Type: Active Directory Domain Services
Object:
DN: CN=pc1,OU=Client,OU=Computer,OU=company,DC=netcorp,DC=at
GUID: CN=pc1,OU=Client,OU=Computer,OU=company,DC=netcorp,DC=at
Class: computer
Attribute:
LDAP Display Name: msDS-KeyCredentialLink
Syntax (OID): 2.5.5.7
Value: B:828:<Binary>:CN=pc1,OU=Client,OU=Computer,OU=company,DC=netcorp,DC=at
Operation:
Type: Value Added
Correlation ID: {971bae70-6821-4b8c-bdbf-dbb14101b21c}
Application Correlation ID: -
你看不出有多大区别?我也不。您可以再次访问相应的事件 4624 并检查 IP 地址,但这通常是客户端不太可靠的信息来源,并且还暗示您有 DHCP 日志之类的东西。因此,让我们再看看 msDS-KeyCredentialLink 本身。请注意,我们正在分析合法凭证,而不是 ntlmrelayx 添加的凭证。
Get-ADComputer -Identity pc1 -Properties * | select -expand msds-keycredentiallink | Get-ADKeyCredential
如果将此密钥凭证与上一个用例中的凭证进行比较,您会发现两个不同之处。
请记住,whisker 和 ntlmrelayx 等工具默认自动设置设备 ID,因此它们模仿了前面讨论的 WHfB 用例,但在涉及 credentialguard 用例时实际上会引发危险信号。这对初学者有好处,但是您显然可以毫不费力地更改工具,然后我们又回到了起点。
那么我们为什么不将设备上的密钥与 AD 中的密钥进行比较呢?事实证明,该密钥的位置和结构并未被 Microsoft 公开记录。但是,有一个人已经为我们提供了保障,这不足为奇;)
微软称这个密钥存储在“机器绑定证书”中的结构,Benjamin Delpy 不仅知道在哪里找到它,而且知道如何提取它。好的。不幸的是,由于各种原因,防御者通常不能四处走动并随机执行 Mimikatz,因此我选择了一种不太优雅的方式来“重新实现”功能。该脚本使用 PSRemoting 来获取machineboundcertificate
主机注册表值的内容,并与 AD 中 kcl 属性中的公钥内容进行逐字节比较(非常快速和肮脏 - 我知道 ^^)。
下面是这个脚本的输出的样子。
一个非常关注 opsec 的攻击者仍然可以通过正确设置注册表值的内容来解决这个问题,但我认为这仍然是一个值得关注的指标。最后,又是思维导图时间。
审核 msDS-KeyCredentialLink 更改很容易,验证更改并非如此,并且很大程度上取决于对您环境中什么是“正常”的扎实知识。我希望这篇文章能让你在这个过程中节省一些时间。到目前为止,我花了很多时间才解决这个问题,但我仍然有强烈的感觉,我错过了一些东西(或很多东西)。因此,如果您阅读本文并且比我了解更多,如果您能告诉我,我会很高兴。也就是说,这是另一个思维导图,因为MindMapsAreFun
:)
近期阅读文章
,质量尚可的,大部分较新,但也可能有老文章。开卷有益,不求甚解
,不需面面俱到,能学到一个小技巧就赚了。译文仅供参考
,具体内容表达以及含义, 以原文为准
(译文来自自动翻译)尽量阅读原文
。(点击原文跳转)每日早读
基本自动化发布(不定期删除),这是一项测试
最新动态: Follow Me
微信/微博:
red4blue
公众号/知乎:
blueteams