Active Directory 域权限提升 (CVE-2022–26923)
2022-5-12 09:57:8 Author: mp.weixin.qq.com(查看原文) 阅读量:27 收藏

该漏洞允许低权限用户在安装了 Active Directory 证书服务 (AD CS) 服务器角色的默认 Active Directory 环境中将权限提升到域管理员。

AD CS 是一个服务器角色,用作 Microsoft 的公钥基础结构PKI 设施。它与 Active Directory 紧密集成并支持颁发证书,这些证书是 X.509 格式的数字签名文档,可用于加密、消息签名或身份验证。

我创建了CORP.LOCAL安装了 AD CS 的域。创建了一个默认的低权限用户,名JOHN. CORP-DC-CA在下面的示例中,我们向CORP-DC-CA请求证书。使用颁发的证书john.pfx对KDC进行身份认证,使用证书进行身份验证时,Certipy 将尝试请求 Kerberos TGT 并检索账户的 NT 哈希。

默认情况下,域用户可以注册User证书模板,域计算机可以注册Machine证书模板。两个证书模板都允许客戶端身份验证。这意味著颁发的证书可用于通过PKINIT Kerberos 扩展对 KDC 进行身份验证。

那么为什么 AD CS 对用户和计算机有不同的模板,简而言之,用户帐户具有用户主体名称 (UPN),而计算机帐户则没有。当我们根据User模板请求证书时,用户帐户的 UPN 将嵌入到证书中以进行识别。当我们使用证书进行身份验证时,KDC 会尝试将 UPN 从证书映射到用户。如果我们查看模板的msPKI-Certificate-Name-Flag属性User,我们还可以看到指定了SubjectAltRequireUpn( CT_FLAG_SUBJECT_ALT_REQUIRE_UPN)。

根据MS-ADTS(3.1.1.5.1.3 唯一性约束),UPN 必须是唯一的,这意味着我们不能有两个具有相同 UPN 的用户。例如,如果我们尝试将 UPN 更改Jane为[email protected],将违反约束,因为“UPN” [email protected]已被使用。

如前所述,计算机帐户没有 UPN。那么计算机帐户如何使用证书进行身份验证?如果我们查看Machine证书模板,我们会看到指定了SubjectAltRequireDns( CT_FLAG_SUBJECT_ALT_REQUIRE_DNS)。

所以让我们尝试创建一个新的机器帐户,请求一个证书,然后用证书进行身份验证

正如我们在上面看到的,证书是用 DNS 主机名颁发的JOHNPC.corp.local,如果我们查看计算机帐户JOHNPC$,我们可以注意到这个值是在dNSHostName属性中定义的。

如果我们查看JOHNPC对象的权限,我们可以看到John(机器帐户的创建者)具有“Validated write to DNS host name”权限。

这里解释了“验证写入 DNS 主机名”权限,并描述为“验证写入权限以启用与计算机名和域名兼容的 DNS 主机名属性的设置”。那么“符合计算机名和域名”是什么意思呢?

如果我们 (John) 尝试更新DNS 主机名属性JOHNPC为TEST.corp.local我们不会遇到任何问题或违反约束,并且 SAM 帐户名JOHNPC仍然是JOHNPC$。

因此,让我们现在尝试请求证书。

我们注意到证书现在使用 DNS 主机名TEST.corp.local颁发。所以现在我们确定颁发证书中的 DNS 主机名是从该dNSHostName属性派生的,并且John(作为机器帐户的创建者)具有“验证写入 DNS 主机名”权限。

如果我们阅读MS-ADTS(3.1.1.5.1.3 唯一性约束)文档,它没有提到dNSHostName计算机帐户的属性必须是唯一的。

如果我们查看域控制器的 (DC$)dNSHostName属性,我们会发现该值为DC.CORP.LOCAL。

因此,事不宜迟,让我们尝试更改dNSHostName属性。从JOHNPC修改为 DC.CORP.LOCAL。

这一次,我们收到一条错误消息,说“发生操作错误”。这与我们尝试将 UPN 更改为另一个用户的 UPN 时不同,在这种情况下我们遇到了约束违规。那么究竟发生了什么?

如果我们在将修改JOHNPC的dNSHostName属性值从JOHNPC.corp.local到TEST.corp.local时仔细观察,我们可能会注意到JOHNPC的servicePrincipalName的属性值已更新以反映新值dNSHostName。

并且根据MS-ADTS(3.1.1.5.1.3 唯一性约束),servicePrincipalName检查属性的唯一性。因此,当我们尝试更新 JOHNPC的dNSHostName属性到DC.corp.local时,域控制器尝试更新该servicePrincipalName属性,该属性将被更新为包含RestrictedKrbHost/DC.corp.local和 HOST/DC.corp.local,这将与域控制器的servicePrincipalName属性发生冲突。

因此,通过更新JOHNPC的dNSHostName属性,当域控制器也尝试更新JOHNPC的servicePrincipalName时,间接导致了约束冲突。

如果我们看一下JOHNPC的权限,我们还可以看到John(作为机器帐户的创建者)具有“Validated write to service principal name”权限。

“验证写入服务主体名称”权限在此处进行了说明,并描述为“验证写入权限以启用符合计算机 DNS 主机名的 SPN 属性设置”。所以如果我们要更新JOHNPC的servicePrincipalName,更新后的值也必须符合dNSHostName属性。

同样,这里的“合规”是什么意思?我们注意到,当我们更新dNSHostName时,只更新和检查了包含dNSHostName属性的两个值RestrictedKrbHost/TEST.corp.local和HOST/TEST.corp.local。其他两个值RestrictedKrbHost/JOHNPC和HOST/JOHNPC包含属性值sAMAccountName(没有$尾随)。 

所以只有servicePrincipalName包含dNSHostName的属性值必须符合dNSHostName属性。但是我们可以删除包含dNSHostName的值的servicePrincipalName吗?

可以。因此,如果我们现在尝试更新JOHNPC的属性dNSHostName值为DC.corp.local,域控制器将不必更新servicePrincipalName,因为没有包含任何dNSHostName的属性值。 

让我们尝试更新 JOHNPC的属性dNSHostName值为DC.corp.local。 

成功!我们可以看到该dNSHostName属性已更新为DC.corp.local,并且servicePrincipalName没有受到更改的影响,这意味着我们没有导致任何约束违规。

所以现在JOHNPC拥有和dNSHostName域控制器一样的了DC$。

现在,让我们尝试使用Machine模板为JOHNPC请求证书,该模板应嵌入dNSHostName属性作为标识。

又一次成功!我们得到了一个带有 DNS 主机名的证书DC.corp.local。让我们尝试使用证书进行身份验证。

身份验证也成功,Certipy 检索了dc$. 作为POC(概念验证),我们可以使用 NT 哈希执行 DCSync 攻击以转储所有用户的哈希。


文章来源: http://mp.weixin.qq.com/s?__biz=MzA4MDMwMjQ3Mg==&mid=2651868114&idx=1&sn=3a8fc5946a564be9fbb747e1779cc544&chksm=8442b335b3353a230e518f4aba020c3a76e2574f51587c9b500d22842546a1d841628013543b#rd
如有侵权请联系:admin#unsafe.sh