2024年12月补丁日,微软放出了CVE-2024-49019的修复公告,归类是Active Directory Certificate Services(ADCS)的权限提升漏洞。如果你不是专门盯着证书服务这一条攻击面,大概率会把它当成又一个不起眼的小提权漏洞扫过去。但把时间轴拉回到2022年的CVE-2022-26923(安全社区熟知的Certifried),再对照今天的ESC15,你会发现这件事根本不是一个孤立漏洞,而是ADCS攻击研究"补丁—绕过—再补丁—再绕过"循环里的最新一环。
这篇文章我打算换一个角度写。网上关于ESC15利用链的讨论已经有一些了,我不想再做攻击视角的复读机。这篇内容基本是写给防御者和研究者的:这个漏洞的本质到底是什么,为什么ADCS一而再再而三地在这个方向上翻车,作为域管理员、安全运维或者渗透测试工程师,你此刻应该去机房查什么日志、看哪些配置,以及未来这类漏洞还会往哪里长。这不是保姆级攻击教程,而是帮你把证书攻击的底层逻辑彻底想明白的一份深度笔记。
1. 为什么ADCS成了域内最危险的攻击面:证书本身就是特权令牌
1.1 一张证书为什么能当"域管"用
先把最基础的事情讲透:证书在AD域环境里意味着什么?很多人觉得证书就是个用来做HTTPS或者Wi-Fi认证的文件,但在ADCS作为企业CA运行、并且把CA证书发布到NTAuthCertificates对象之后,域内任何通过该CA签发的证书,理论上都可以通过PKINIT协议向域控申请Kerberos票据。
打个比方,证书是一把钥匙胚。钥匙胚本身没有名字,但当CA在上面刻了"域控的主机名"或者"域管理员的UPN",这把钥匙胚就变成了一把能打开域控后门的成品钥匙。攻击者拿到这种证书后,用PKINIT申请TGT,就能直接获得对应主体的全部权限——是的,包括域管理员。
所以ADCS领域几乎所有攻击研究的最终目标都是一致的:想办法让CA签发一张"不该签发的证书"。一旦CA帮你签出一张主体名称为域控或域管的证书,后面的事情就纯粹是标准化操作了。这也是为什么我把ADCS称为"域内最危险的合法攻击面"——它所有的问题最后都会收敛到同一个致命结论。
1.2 ESC家族攻击的三种"病根"
ADCS攻击研究的历史,基本就是ESC(Escalation of Certificates)编号的增长史。从ESC1走到ESC15,攻击手法五花八门,但如果你把它们拆开看,能下手的地方一共就三类:
- 输入伪造:攻击者直接控制证书签名请求(CSR)里的内容,典型的就是Subject和SAN字段。如果CA或者证书模板允许请求者自己指定主体名称,而这个模板又恰好能被低权限用户注册,那就直接把域管的UPN写进去,让CA签出证书。ESC1、ESC6就是这么干的。
- 身份冒充:这个更隐蔽。攻击者不直接指定主体名称,而是通过操纵AD对象自身的属性,让CA在"根据AD信息构建主体名称"时,误以为当前申请者就是某个高权限实体。CVE-2022-26923就是教科书式的案例。
- 中继绕过:攻击者不直接与CA交互,而是通过NTLM Relay的方式,把高权限用户的凭证中继到ADCS的HTTP接口,让CA误以为请求来自域管本人。ESC8、ESC11属于这一挂。
ESC1到ESC15,本质上都是在这三个点上反复横跳。ESC15的新意不在于发明了第四种攻击维度,而在于它绕过了前人对"身份冒充"这条攻击面的修复。
先放一张简化版的ESC家族速查表,后面的讨论会用到。这张表基于社区公开研究整理,我刻意压缩了细节,重点是让你看清它们分别落在哪个攻击面:
| 编号 | 攻击面分类 | 一句话概括 |
|---|---|---|
| ESC1 | 输入伪造 | 模板允许请求者在CSR中指定SAN |
| ESC2 | 输入伪造 | 模板启用任意EKU,证书用途彻底失控 |
| ESC3 | 身份冒充 | 注册代理模板被滥用,可代他人申请证书 |
| ESC4 | 权限委派 | 低权限用户对证书模板有写ACL权限 |
| ESC5 | 权限委派 | CA自身ACL或证书发布点被篡改 |
| ESC6 | 输入伪造 | CA允许CSR中的SAN(EDITF_ATTRIBUTESUBJECTALTNAME2) |
| ESC7 | 权限委派 | CA"管理CA"权限被错误委派 |
| ESC8 | 中继绕过 | NTLM Relay到ADCS的HTTP端点 |
| ESC9/10 | 身份映射 | 证书映射与NTAuthCertificates校验逻辑问题 |
| ESC11 | 中继绕过 | ICertRequest接口的NTLM中继 |
| ESC13 | 身份映射 | 模板中的SID扩展被映射到高权限SID |
| ESC14 | 身份映射 | altSecurityIdentities相关的证书映射绕过 |
1.3 2022年的旧账:Certifried为什么至今阴魂不散
讲清楚ESC15,绕不开CVE-2022-26923,也就是安全社区常说的Certifried。这个漏洞是Truesec的研究员Oliver Lyak在2022年公开的,思路极其优雅。
默认情况下,AD域允许普通用户在域里创建机器账户(MachineAccountQuota默认值是10个),而且机器账户加入域后,默认状态下对自己对象的很多属性有写权限,其中就包括dNSHostName。攻击者要做的事情就三步:创建一个机器账户,把它的dNSHostName改成域控的FQDN,然后拿这个机器账户去申请一张客户端认证证书。CA在构建证书主体名称时会去AD里读取该账户的dNSHostName,于是域控的FQDN就被堂堂正正地写进了证书里。后面就是拿证书申请域控TGT的标准流程。
微软当时修复CVE-2022-26923的方式是硬性的:在ADCS的证书签发逻辑中增加校验,要求证书里的dNSHostName必须与请求者账户的sAMAccountName一致,也就是机器账户的dNSHostName对应的机器名,必须和它的sAMAccountName去掉结尾"$"号后的名字对得上。
这个修复堵住了"直接改dNSHostName指向域控"这条路,但问题的深层结构并没有被解决——ADCS在构建证书主体名称时,本质上还是在信任"AD对象属性"和"证书请求主体"之间的对应关系,而不信任请求方本身的身份状态。只要攻击者能找到另一个可写属性、或利用属性之间的等价关系,让CA在某个分支里产生误判,这个口子就会再次打开。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 拆解CVE-2024-49019:这个"致命绕过"到底绕过了什么
2.1 微软公告里有限的信息,以及藏在二进制里的真相
CVE-2024-49019于2024年12月10日被微软修复,官方归类是ADCS权限提升漏洞(Elevation of Privilege),严重等级标记为Important而非Critical。公告本身极其吝啬,只说了三件事:漏洞存在、ADCS受影响、攻击者可以获得权限提升。至于漏洞具体出在哪个函数、哪条路径,公告里一个字没提。
这类公告其实已经是微软近年来的标准操作:越敏感的ADCS漏洞,公开信息越少。想要还原漏洞本质,只能靠补丁二进制比对。从社区研究者的初步diff结果来看,修复改动集中在CA构建证书主体名称时的属性校验逻辑上。也就是说,这不是一个新的中继端点被发现,也不是某个模板ACL出了问题,而是ADCS在处理AD对象属性与证书主体名称映射关系时,存在一个校验盲区。
顺着这个线索,目前安全社区的主流推测是:CVE-2024-49019是CVE-2022-26923的一次补丁绕过。攻击者找到了另一条路径,让CA在构建主体名称时仍然能写入一个与请求者账户不对应的名称,只是这一步不再直接依赖简单的dNSHostName字段,或者不复用2022年补丁所校验的那段代码分支。用一句大白话总结就是:微软把大门锁了,但攻击者发现旁边那扇窗户的锁扣坏了。
2.2 触发链路还原:一个"受信任的内部人"如何蒙混过关
我基于现有公开情报,把ESC15的触发链路做一次原理层面的还原。这里只讲逻辑,不给具体操作,原因是这篇文章的定位是防御视角,而完整攻击链对防御者理解场景已经足够,不需要落成命令。
第一步,攻击者手上有一个低权限域账户,且该账户能创建机器账户。这一步依赖的完全是AD默认配置——普通用户在默认情形下可以创建最多10个机器账户。
第二步,攻击者在AD里准备一个特殊的机器账户,然后利用对该机器账户对象拥有的合法写权限,修改某些名称类属性。这里的关键词是"某些"——如果直接用dNSHostName就能打通,那2022年的补丁会直接拦住。所以更可能的情况是,攻击者选中的属性与dNSHostName在CA的校验逻辑里处于不同分支,或者在该机器账户的特定创建方式下,sAMAccountName与dNSHostName之间的一致性校验没有被完整执行。
第三步,攻击者以该机器账户身份向ADCS提交证书申请。这里有个很重要的点:证书模板不需要启用"允许在请求中指定SAN",不需要篡改任何ACL,也不用改CA上的任何标志。模板只需要是常见的客户端认证类模板,机器账户和用户账户都能注册的那种商会模板就可以。
第四步,CA收到请求后,按照模板配置去AD里读取该账户信息并构建主体名称。由于CA在构建时参考的是攻击者之前准备好的名称属性,最终签发的证书主体名称变成了域控主机名。攻击者拿到证书,用PKINIT向域控申请TGT,提权完成。
整个过程没有一次使用高权限用户账号,没有利用任何业务系统漏洞,全部操作都在"合法身份+合法接口"上完成。这就是这类攻击让蓝队最头疼的地方:很难用传统行为分析规则去捕捉,因为每一环单看都是域内日常操作。
2.3 为什么微软只给了Important而不是Critical
很多安全从业者看到"可提权到域管理员"的漏洞只配了个Important,第一反应是微软又双标了。其实微软的定级逻辑里,ADCS这类漏洞的利用条件写得很明白:需要ADCS已部署、需要存在可利用的证书模板、需要攻击者先获得域内账户。三重前置条件叠加,在微软的评分模型里就被压到了Important。
但把这三条放到真实企业环境里一对照,你会发现它们经常是同时满足的。ADCS在中小规模以上的企业网络里几乎是标配;默认模板没清理、注册权限偏宽是常态;域内"服务水平"账户数量几百上千。这意味着现实世界中,绝大多数企业其实都站在"可利用"这一侧。
所以我的建议很明确:不要因为官方定级是Important就降低处置优先级,要按照你所在环境的实际暴露面来打分。对一个证书服务全量部署、域用户规模超过500人的企业来说,CVE-2024-49019的实际风险并不比一个Critical级别漏洞低。
3. 从防御视角模拟一次完整利用:攻击者需要什么,又会留下哪些痕迹
3.1 攻击前置条件盘点:默认配置下有多容易满足
不要被"低权限账户"这几个字迷惑,我来把攻击者对环境的要求完整列一遍:
- ADCS已部署,CA能被域内用户正常访问(这是利用的物理前提)
- 至少有一个证书模板允许机器账户或普通用户账户注册,且其EKU是客户端认证或智能卡登录
- 攻击者已控制一个普通域用户,并能创建机器账户(默认配额10次)
- 攻击者对自建机器账户有一组合法的属性写权限(这在默认ACL下是成立的)
你看,这里面没有任何一条需要管理员"额外犯错"才能满足。攻击者需要的只是一个默认配置的ADCS环境,这恰恰是最普遍的情况。这也是我把ESC15归类为"现实威胁"而不是"实验室漏洞"的原因。
3.2 攻击完成后,审计日志里的"脏证据"散落在哪
从Windows事件日志的角度看,攻击链会产生几个典型的日志指纹:
- 机器账户创建:Windows安全日志事件ID 4741。新增机器账户本身不算异常,但如果短时间内出现多个新机器账户集中创建,或者某个低权限用户持续创建机器账户,就值得排查。
- AD属性修改:如果域控开启了目录服务变更审计,会有事件ID 5136。需要重点关注对dNSHostName及相关名称类属性的修改。但这里有个现实问题——很多企业的域控默认没有开启5136审计,导致这一环完全失明。
- 证书服务签发:在CA服务器上,事件ID 4886表示收到证书申请,4887表示证书已颁发。关键检测点是:证书主体名称与申请者账户名称是否匹配。如果一张申请者是机器账户的证书,最终主体名称却是域控FQDN,那就是最直接的攻击信号。
- 异常Kerberos认证:PKINIT预认证成功会触发事件ID 4768。如果看到来自非域控IP、却以域控机器名为密钥主体进行认证的流量,需要第一时间与CA日志做关联。
最吓人的一点是:如果不开启5136审计,并且不对4887做主体名称匹配检测,整个攻击链条只会产生几个"日常噪音级别"的日志记录。没有一个事件会触发常规的安全告警阈值。
3.3 攻击者的"时间窗武器":把攻击动作拉长成正常行为
实际红队操作中,这类链条还有一个很难防御的特点——动作可以拆开。星期一创建机器账户,星期五修改属性,下星期三再提交证书申请。中间所有操作都间隔几天甚至一周,让每个单独时间点上的日志看起来都像是业务操作的一部分。
这种低慢式攻击对检测系统的挑战是巨大的。所以我在给企业做检测设计时,通常强调要用时间窗聚合而不是单点匹配——将近30天内同一源头关联的机器账户创建、属性修改、证书申请三类事件全部拉通,才有可能提高置信度。这也是我坚持建议企业把域控和CA日志留存时间至少拉到90天的根本原因。
4. 检测与狩猎:在没有补丁的机器上,怎么把攻击者从日志里捞出来
4.1 该看哪些Windows事件ID:速查表
下面的表格是我在多个实战项目中沉淀下来的事件ID清单,覆盖了ADCS攻击链的各个环节:
| 事件ID | 日志来源 | 检测意义 |
|---|---|---|
| 4741 | 安全日志(域控) | 计算机账户创建,关注非标准的批量创建 |
| 5136 | 目录服务变更日志(域控) | AD对象属性修改,需要手动开启审计策略 |
| 4738 | 安全日志(域控) | 用户账户对象被修改 |
| 4886 | 证书服务日志(CA) | 证书服务收到证书申请 |
| 4887 | 证书服务日志(CA) | 证书服务批准并签发证书,核心检测点 |
| 4888 | 证书服务日志(CA) | 证书服务拒绝证书申请,可辅助发现探测行为 |
| 4768 | 安全日志(域控) | Kerberos服务票据请求,关注异常密钥主体 |
| 4913 | 证书服务日志(CA) | CA服务器上证书对象的属性被修改 |
需要特别说明的是,5136必须在域控上手动开启"目录服务变更审核"策略后才会产生,这是最容易被遗漏的检测盲区。如果你现在管的域里没有开启这个策略,建议先把事件ID 5136的审计补上,再考虑其他的高级检测。
4.2 可落地的SIEM查询规则示例
我平时习惯用Microsoft Sentinel的KQL做狩猎规则,这里给你几条可以直接抄走的查询,都已经过匿名化处理,去掉环境相关信息:
查询一:找出"主体名与申请者不匹配"的已签发证书
kql复制Event
| where Source == "Microsoft-Windows-Eventlog"
| where EventID == 4887
| extend Request = parse_xml(EventData).DataItem.EventData.Data
| extend Requestor = tostring(Request.[3])
| extend Subject = tostring(Request.[4])
| where Requestor != Subject
| project TimeGenerated, Requestor, Subject, Computer
查询二:关联"机器账户创建+属性修改"的组合行为
kql复制let AccountCreation = Event
| where EventID == 4741
| summarize CreationTime = min(TimeGenerated) by TargetAccount, Account;
let AttributeChange = Event
| where EventID == 5136
| where tostring(EventData["AttributeLDAPDisplayName"]) in ("dNSHostName", "sAMAccountName", "servicePrincipalName")
| summarize ChangeCount = count(), FirstChange = min(TimeGenerated) by TargetAccount;
AccountCreation
| join kind=inner AttributeChange on TargetAccount
| where datetime_diff('day', FirstChange, CreationTime) between (0 .. 30)
| project CreationTime, TargetAccount, Account, ChangeCount, FirstChange
查询三:CA上短时间高频证书申请行为
kql复制Event
| where EventID == 4886
| summarize RequestCount = count() by Requestor, bin(TimeGenerated, 1h)
| where RequestCount > 5
| project TimeGenerated, Requestor, RequestCount
这三条规则配合起来,能覆盖ESC15攻击链中"机器账户准备"和"证书滥用落地"这两个最容易被记录下来的环节。当然,规则命中不代表一定被攻击,也可能是业务侧的异常联动,需要结合上下文研判。但从我的实际经验来说,这些规则开起来以后,误报率是可以接受的,反而经常能捞出一些意想不到的配置问题。
4.3 日志盲区:为什么你查不到,不代表没发生
讲一个我在项目里反复遇到的现象:企业安全团队接到ADCS告警后去翻日志,结果什么都没查到,然后得出"没有攻击迹象"的结论。实际上,大部分时候不是没有攻击,而是日志压根没记下来。
最常见的盲区有三个。一是CA服务器自身没有开启IIS日志和CAPI2日志,导致证书服务相关的请求记录全部缺失;二是域控没有开启目录服务变更审计,5136事件不存在;三是日志留存周期太短,被拉长到两周前的攻击动作早就被覆盖掉了。
所以我给所有客户的第一句话都是:在考虑"怎么检测"之前,先确认"有没有日志"。没有日志,一切检测规则都是空中楼阁。
5. 缓解与加固:把ADCS从"最弱一环"变成"最难咬的骨头"
5.1 应急响应第一步:补丁、配置、风向标三件事
如果你确认环境里存在暴露风险,第一步一定是打补丁。2024年12月的安全更新已经修复了CVE-2024-49019,这是优先级最高、成本最低的处置动作。
如果因为变更窗口等原因暂时无法打补丁,可以采取临时缓解措施:
- 在CA服务器和所有域控上启用证书服务相关的增强日志,先把可观测性拉起来
- 针对事件ID 4887启动主体名称与申请者的自动比对,发现异常立即暂停对应的证书模板
- 对已发出的证书做一次全量回扫描,检查是否存在主体名称为域控或域管、但申请者是低权限账户的证书,一旦发现立即吊销
应急期过了之后,重点就转移到永久加固上。这里我给一份按优先级排列的加固清单:
| 优先级 | 加固项 | 说明 |
|---|---|---|
| P0 | 给CA和域控打满补丁 | 消除已知漏洞,包括CVE-2024-49019 |
| P0 | 吊销并重新签发疑似异常证书 | 切断已被利用后的持久化通道 |
| P1 | 收紧证书模板注册权限 | 将注册权收敛到具体的业务用户组和计算机组 |
| P1 | 清理不再使用的证书模板 | 从CA上禁用模板,减少攻击面 |
| P2 | 关闭CA上的SAN自定义标志 | 确认EDITF_ATTRIBUTESUBJECTALTNAME2为关闭状态 |
| P2 | 检查MachineAccountQuota | 若无业务需求,可以将其降为0 |
| P3 | 开启域控目录服务变更审计 | 补上5136事件盲区 |
| P3 | 启用CAPI2和IIS日志 | 保留CA侧完整请求痕迹 |
5.2 证书模板瘦身,才是真正的"深水区"
多数企业的ADCS攻击面问题,根源不在某个CVE,而在于证书模板的垃圾存量。我见过太多环境,CA上挂着三四十个模板,很多是2012年部署时从默认模板里复制出来的,注册权限写着"Authenticated Users"——意思是任何域用户都能申请。
在ESC15这类漏洞的语境里,一个能被低权限用户申请、且EKU包含客户端认证的模板,就是走向域控的直通车。所以模板瘦身的动作要细致:
- 逐个梳理CA上已发布的模板,确认每个模板的业务归属
- 将注册权限从Authenticated Users和Domain Users收缩到具体的业务安全组
- 模板的EKU按最小化原则配置,不需要的勾选全部取消
- 对支持"在请求中提供主体名称"的模板重点排查,原则上全部禁止,改用"从AD信息构建"
这条路上最麻烦的是业务兼容性。有些老应用确实依赖某些特定模板的宽松配置,所以清理动作一定要有业务确认环节,别一刀切把业务切死了。但从安全角度看,把几个"宽进宽出"的老模板从CA上拿下来,收益远大于风险。
5.3 身份安全的新方向:从"证书依赖"走向"证书生命周期自动化"
从长远看,ADCS攻击频发的本质原因是"静态证书+宽松注册权限"的旧有模式已经跟不上现代身份安全的要求。证书一旦签发,在有效期内就是一把可以在域里反复使用的钥匙,除非吊销,否则无法收回。
我比较推荐的方向是往"证书生命周期自动化"和"短有效期证书"靠拢。比如引入基于证书模板策略的自动续期机制,将签发的证书有效期从传统的两三年缩短到以天为单位的级别;同时配合CA侧的严格审计和自动吊销策略,让一张潜在问题证书即便被签发,也很快会进入自然过期或被主动替换的流程。
另外,有条件的企业可以把身份认证的主干往Windows Hello for Business、FIDO2这类现代无密码认证方案上迁移。证书服务保留给真正需要的场景,而不是作为通用身份凭证的默认基础设施。这不只是针对ESC15的防御,而是对整个ADCS攻击面的战略性收缩。
6. 防御前瞻:从ESC15看ADCS攻击研究的"下一站"
6.1 为什么证书攻击会"越补越多"
回顾ADCS攻击研究的历史,你会发现一个规律:几乎每一次修复,都会在几个月后的时间里催生一个新的绕过。原因其实不复杂。
ADCS不是一个独立产品,它是AD域、证书模板、IIS Web服务、NTLM认证、Kerberos协议多层组件的缝合怪。任何一个组件里的"合理行为",在另一个组件的语境里都可能变成"漏洞条件"。证书模板说"允许从AD信息构建主体名称",AD说"机器账户可以修改自己的名称属性",CA说"我信任AD里查到的信息"——三个都是一本正经的合理设计,但组合起来就成了CVE-2022-26923;补丁堵上了其中一个组合路径,下一个组合又会在别处冒出来。
这种问题不是改一行代码或者打一个补丁就能根治的,它是架构层面的复杂性带来的必然结果。也是因为这个原因,我预测ADCS在未来的两三年里还会持续输出新的ESC编号——除非企业环境的身份认证架构发生大的迁移。
6.2 未来值得紧盯的四个方向
从公开研究和漏洞拍卖会的动态来看,ADCS后续的攻击研究会围绕这几个方向展开:
- 属性等价关系挖掘:继续寻找与dNSHostName拥有相同"证书构建效力"但校验路径不同的AD属性。
- HTTP端点变种:ADCS的历史兼容接口很多,Web Enrollment之外还有CEP/CES、NDES等,只要有新的端点接进来,NTLM中继类的攻击就有新的着落。
- 证书映射策略:微软近年对强证书映射(Strong Certificate Mapping)做了多轮收紧,但每次收紧都会伴随反向研究,ESC9/10/14就是这条线的产物。
- 多云与混合身份:ADCS与云身份基础设施的桥接是新的混合攻击面,证书同步、联盟信任、跨林信任里可能潜藏新一轮问题。
6.3 给三类角色各三条行动建议
如果你是企业蓝队/安全运维,你现在要做的是:检查CA模板清单和注册权限;开启缺失的5136审计;在SIEM里落地4887主题名匹配规则,并准备一份基于事件ID 4887的证书记录基线。
如果你是红队/安全研究员,我的建议是:在代码分析之外,多花时间搭建"默认配置"实验环境,因为ADCS的脆弱性经常藏在"所有产品都开了默认配置"的组合里;研究时优先关注补丁的旁路路径而不是正门;每次研究完成后,顺手完善自己的检测规则库,这会让你的研究价值放大很多倍。
如果你是负责安全决策的管理者,一句话:把ADCS安全和域控安全放到同一优先级来对待。证书服务的危害半径和域控是同一个等级,它不是"边界安全的一部分",而是"核心身份基础设施的一部分"。
结尾的部分,聊点实际的。我每次帮客户评估ADCS环境,无论是什么项目,都固定先打开三张表:CA上发布的模板清单、每个模板的注册权限ACL、最近90天的4887事件列表。这三张表看完,基本就能判断一个企业到底是不是ADCS攻击的活靶子。CVE-2024-49019的补丁打了,但下一轮绕过也许已经在某个研究者的虚拟机里跑通了。在这个猫鼠游戏永远不会停歇的领域里,唯一能让你站稳脚跟的,不是赌下一个漏洞不会来,而是把自己的日志留够了、配置收紧了、主动权握在自己手里。
