模板允许自填 SAN:域用户可冒充管理员

安全审计发现 AD CS 证书模板允许申请者自填 SAN,普通域用户可申请管理员证书并用于认证。关闭自填、收紧注册权限并吊销滥用证书后收口,附模板排查方法。

问题背景

公司有一套内部 AD CS(Active Directory Certificate Services),主要给 802.1X 无线认证和 VPN 拨号签发用户证书。CA 是几年前部署的,证书模板由实施商提供,其中“VPN-Users”模板允许 Domain Users 注册,用途是让员工申请自己的拨号证书。这些年一直这么用,没人觉得有问题——证书嘛,不就是个网络准入凭证。

今年的季度安全审计请了外部团队。他们在授权范围内做 AD 域安全评估时,用普通域账号在 CA 上申请了一张证书,把 SAN(Subject Alternative Name)填成了域管理员账号,CA 居然签发了。审计报告把这条列为高危:任何普通域用户都能拿到一张“写着管理员名字”的证书,并用它完成身份认证。

故障现象

  • 审计人员在普通域账号下申请证书,请求中的 SAN 填的是另一个账号,CA 返回“颁发成功”。
  • 用这张证书做 LDAP 认证,服务端把它当成了 SAN 里那个账号,权限也随之继承。
  • CA 的颁发日志里,申请者账号与证书 SAN 不一致,但没有任何告警或拦截。
  • 该模板的注册权限包含 Domain Users,没有启用管理员审批,也没有限制可申请的 SAN 范围。
  • 审计同时确认:除了这次测试申请,历史日志里没有发现其他 SAN 与申请者不一致的证书,暂未发现实际滥用。
  • 业务侧完全无感:802.1X 和 VPN 一直正常,证书到期续签也正常,问题只存在于“证书代表谁”这个最根本的语义上。

排查过程

第一步盘点模板。在 CA 上执行 certutil -CATemplates,列出所有可用的证书模板;重点看哪些模板允许“在请求中提供使用者信息”。再用 certutil -v -template <模板名> 或直接查看 AD 中对应模板对象的属性,核对三个关键项:msPKI-Certificate-Name-Flag 是否包含 CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT(值为 0x1)、msPKI-Enrollment-Flag 是否要求管理员审批、pKIExtendedKeyUsage 是否包含客户端认证。

第二步确认注册权限。查看模板对象的安全描述符,发现 Domain Users 拥有注册权限,且没有额外的 issuance policy 限制。也就是说,任何登录域的普通账号都能发起申请,CA 不会核对 SAN 是否等于申请者本人。

第三步做授权验证。在隔离测试环境里,用普通测试账号提交了一张 SAN 为测试管理员账号的证书请求,CA 正常签发;用该证书完成一次 LDAP 认证,读到了测试管理员权限下的对象属性。验证到此为止,没有进行任何横向操作,随后立即吊销了这张证书。结论明确:这不是理论风险,而是可复现的权限提升路径。

第四步归类。对照 AD CS 的已知攻击面,这个配置命中 ESC1:模板允许申请者自填 SAN、包含客户端认证用途、低权限用户可注册、无需审批。四项条件同时满足,CA 就从“身份证明机构”变成了“身份代办机构”。

第五步查历史日志。用 certutil -viewlog 导出 CA 的颁发记录,结合事件日志里的 4886/4887(证书颁发)事件,筛选申请者与证书 SAN 不一致的记录。历史数据里没有发现异常,说明目前只是配置缺陷,尚未被利用;但这条路径已经敞开很久,不能假设没人走过。

第六步复盘来源。这个模板是部署时从一份旧实施文档里复制的,文档里勾选“允许在请求中提供使用者信息”是为了兼容某个老设备,后来设备下线了,模板设置没人回头清理。CA 本身没有错,错在模板把“谁能证明自己是谁”的决定权交给了申请者。

解决方案

  1. 关闭自填 SAN:在模板的“使用者名称”设置里取消“在请求中提供”选项,改为“从 AD 中的信息构建”,让 CA 根据申请者账号自动生成 SAN/UPN,申请者无法指定他人身份。
  2. 收紧注册权限:把模板的注册权限从 Domain Users 收敛到专门的 VPN 用户组;对敏感模板启用管理员审批,申请后必须由 PKI 管理员批准才签发。
  3. 按用途拆分模板:802.1X、VPN、服务器 TLS 各用独立模板,各自的 EKU、有效期、注册权限分开管理,避免一个宽松模板被所有场景复用。
  4. 吊销与清理:吊销测试证书和所有 SAN 与申请者不一致的证书,发布新的 CRL;对使用该模板签发的存量证书做一次复核,必要时强制重新注册。
  5. 排查其他模板:按 ESC1 的条件全量过一遍,同时检查 ESC2(any purpose EKU)、ESC3(注册代理)、ESC4(模板 ACL 过宽)、ESC6(CA 上启用 EDITF_ATTRIBUTESUBJECTALTNAME2)、ESC8(HTTP 注册端点暴露)等常见配置缺陷。
  6. 补审计与告警:开启 CA 审计,采集 4886/4887/4899/4900 事件;对“申请者与 SAN 不一致”“敏感账号证书签发”“模板权限变更”设置告警,而不是等下一次审计才发现。

根因分析

直接根因是 证书模板同时满足四个条件:允许申请者自填 SAN、包含客户端认证 EKU、Domain Users 可注册、无需管理员审批,导致普通域用户可以为任意账号申请证书并完成身份认证。

更深一层,是把 PKI 当成了网络准入的配套设施,而不是身份基础设施。证书的本质是“由 CA 背书的身份声明”,签发规则就是身份授权规则;但在很多组织里,模板是实施时一次性配好的,权限是“能让所有人用”最省事,之后几年无人复核。证书一旦能代表别人,它就不再是凭证,而是冒用工具。

还有一层是监控缺位。CA 每天在签发证书,但没人看颁发日志,没人比对申请者和 SAN 是否一致,也没有模板变更告警。配置缺陷不可怕,可怕的是它可以在无人察觉的情况下被使用很久。

预防措施

  • 建立 AD CS 模板基线:默认不允许自填 SAN,敏感模板必须审批,注册权限按组最小化,EKU 按用途最小化。
  • 每季度做一次 ESC 专项审计,用授权工具枚举脆弱模板,输出清单并跟踪整改;新模板上线前必须过同一套检查。
  • PKI 管理纳入 Tier 0 资产:CA 服务器、模板 ACL、注册端点按域控级别保护,禁止普通运维账号随意改模板。
  • 采集并监控 CA 颁发日志,重点告警 SAN 与申请者不一致、管理员账号证书签发、模板权限变更和 CRL 发布异常。
  • 把 AD CS 纳入红队演练范围,验证“普通用户能否拿到他人证书”,而不是只测口令和票据。
  • 证书生命周期与人员生命周期联动:离职、转岗时吊销个人证书,避免“人走了证书还在”。

总结

一张证书的分量,取决于 CA 愿意为它背书到什么程度。当模板允许申请者自己填 SAN,CA 就放弃了“你是谁”的审核权,转而相信申请者的自我声明;这时候签出来的证书,和一张印着别人名字的工牌没有区别。AD CS 不是网络准入的附属品,它是域内身份体系的一部分。把模板当成安全策略来管,把颁发日志当成安全日志来看,才能避免 CA 从“证明身份”变成“代办身份”。

延伸阅读

使用 Hugo 构建
主题 Stack 由 Jimmy 设计