0x01 漏洞背景
前些日子的靶场中涉及到了域内提权,当时刚好爆出CVE-2022-42278这个域内提权漏洞,正好下载下来了POC试了试,确实不错,于是打算看看这个只需一个域用户,就能获取域控权限的漏洞怎么回事,便有了这篇文章。
0x02 环境搭建
在这里搭建了一个简单的内网环境,主机AD_USER将445端口暴露在外,并且存在ms17_010,hacker通过AD_USER的445端口进入域内,随后通过CVE-2021-42287拿下AD。环境详情:
主机IP
Hacker:192.168.80.128
AD_USER:192.168.80.133/192.168.30.20
AD:192.168.30.10
域环境
角色 USERNAME Password
域控 Administrator ???
域用户 Use qnmb@123!
0x03 POC展示
由于hacker拿下AD_USER的shell比较简单,使用ms17_010即可,所有进行省略
可见存在域的同时定位域控IP:
192.168.30.10
获取明文密码:
域控ip:192.168.30.10 ,域用户:user/qnmb@123!使用脚本成功获取Shell:
Python3 sam_the_admin.py HACKER/user:qnmb@123! -dc-ip 192.168.30.10 -shell
这个脚本仅仅利用了域控的IP和当前域用户,就成功获取了域控的Shell。
接下来详细分析一下CVE-2021-42287的问题。
Github:
https://github.com/WazeHell/sam-the-admin
0x04 分析
在这篇分析文章中,我将先简述Kerberos认证过程,并分析一下其中的一些问题,S4U2self协议,以及CVE-2021-42278的问题所在,将这些串联起来,组成我们的主角CVE-2021-42287域提权漏洞。
一、Kerberos认证简述:
在上面这张图大致简述了Kerberos认证用户访问服务的过程,但是这里存在一个问题,就是用户只需要成功获取到TGT就可以请求任何服务的TGS,这样缺少了用户权限管理,于是在微软引入了PAC的概念。
二、PAC简述
在讲述S4U2self提权之前,必须了解微软对原先Kerberos的改进,即PAC的概念
由于我们在上文提过在之前的Kerberos中存在缺少对访问服务的权限管控问题,因此在原来的Kerberos基础中加入了PAC。
通过上述的过程,我们可以发现:
1.用户请求TGS依旧是仅仅需要提供的TGT可以被kbrtgt hash即可,然后在使用TGS访问服务时才会对用户权限进行校验。
2.用户对PAC的签发和验证是无感知的,PAC签发和验证等工作是由KDC负责的。通过PAC的引入实现了用户对服务的权限控制,成为了Kerberos的安全机制之一。那么,如果我们拥有域控的TGT,然后通过S2U4self获取域控的TS(PAC有KDC生成),就获得了域控权。
三、CVE-2021-42278(伪造AD机器用户)
如果要解释CVE-2021-42287的原理,那么一定离不开CVE-2021-42278
这个是正常机器用户ROOT-PC$ ,SAMTNEADMIN-39$这两个机器用户末尾都带一个$,但是AD没有对域内机器用户名进行验证,于是可以存在这种用户:
这里的SAMTHEADMIN机器用户不存在$,而这就是CVE-2021-42278
四、 CVE-2021-42287
看完上面的CVE-2021-42278,你怕不是要说“就这?”实际上我们可以创建一个与机器用户同名的不带$的机器用户,擦除这个机器账户的SPN后,去请求一个TGT。接下来我们将这个不带$的伪域控机器名更名,这个时候我们拿着这个TGT使用S4U2self协议去请求TS:那么就会获取到一个使用域控hash加密,并且附带PAC的TS,这样我们就可以调用域控的服务了。1.使用不带$的,与域控机器账户同名的账户请求一个TGT2.擦除当前用户SPN(不擦除SPN会导致在使用S2U4self生产TS的时候报错)。3.将伪造的AD机器账户更名。4.使用刚刚获取的TGT通过S4U2self进行TGS请求5.域控在找不到刚刚伪造的机器用户后,会傻傻的给TGT中的client info中的name加一个$,然后再去查询,发现这个TGT发clint不就是俺自己嘛??然后就把自己的PAC加入TS中,并且用自己的hash加密了TS。
五、 S4U2self协议:
这个协议是在PAC引入后,引入的一种扩展协议,他被作为约束委派的实现方法之一:S4U2self协议是为了当用户没有使用kerberos认证,登陆了service A(用户可能通过Web服务NTML,或者其他方式)这个时候当这个用户想访问域内资源的时候,没有Kerberos的TGT就无法获取TS进而无法访问其他服务。S4U2self协议给出的解决方案:
图片来自微软官方
1.User通过非Kerberos登陆Service 1在请求Service 1中的某项功能时需要访问Service 2可以理解为USER通过WEB服务访问了Service 1现在需要调用Service 2的SQL中的资源。
2.这时Service 1会使用自己的TGT向KDC请求一种授权访问自己服务的TS。KDC解密来自Service 1的TGT后返回一个新的TS1(这个TS证书可转发,因为后面需要使用S4U2proxy协议),由于这个TS中的PAC是生成的并非原来TGT中发PAC,所以KDC在匹配到服务账户后,会生成与服务账户同权的PAC放入TS1,这也是CVE-2022-42287在拿着与域控同名无$的TGT返回的TS1为什么包含域控的PAC。
3. Service 1 拿着TS1通过S4U2proxy将TS1发送给KDC,即作为User的身份向KDC请求指向Service 2的TS
4. KDC解密TS1后把指向Service 2的TS 2返回给Service 1。
5. Service 1 再拿着TS2去请求Service 2的服务
总的来说,S4U2self的作用是使服务器获取用户身份,然后代理用户向KDC请求。因此S4U2self协议发送的TGSREQ中的Cname,Sname都是指向自己的。
0x05总结
在这个利用过程中,因为域控在获取TGT发送TGS时存在问题,导致CVE-2021-42278进化成了这个漏洞,KDC在解密TGT的使用使用的是Kbrtgt hash,因此AD认为这个TGT中的信息为可信的,进而进一步检索Client info被欺骗后,因为S4U2self这个协议的特殊性,导致服务证书(TS)用自己的hash加密,并且附上了生成的与域控同权限的PAC。
参考文章
1、CVE-2021-42287/CVE-2021-42278Windows域提权漏洞分析 - 安全客,安全资讯平台 (anquanke.com)
2、Kerberos 委派攻击原理之 S4U2 利用详解_HBohan的博客-CSDN博客_kerberos s4u
4、域内提权漏洞 CVE-2021-42287与CVE-2021-42278原理分析 - FreeBuf网络安全行业门户
POC:https://github.com/WazeHell/sam-the-admin
声明
以上内容,均为文章作者原创,由于传播,利用此文所提供的信息而造成的任何直接或间接的后果和损失,均由使用者本人负责,长白山攻防实验室以及文章作者不承担任何责任。
长白山攻防实验室拥有该文章的修改和解释权。如欲转载或传播此文章,必须保证此文章的副本,包括版权声明等全部内容。声明长白山攻防实验室允许,不得任意修改或增减此文章内容,不得以任何方式将其用于商业目的。