Kerberos认证协议
Kerberos认证协议也称三头犬协议,因为在Kerberos认证过程中,需要有三个角色:Client、Server以及KDC(Key Distribution Center)密钥分发中心。
Kerberos认证协议的目的是为客户端/服务端提供身份验证。最主要的问题是如何证明“你是你”。
认证过程中涉及到的名词:
- AS(Authentication Server) 认证服务器
- KDC(Key Distribution Center) 密钥分发中心
- TGT(Ticket Granting Ticket) 票据授权票据
- TGS(Ticket Granting Server) 票据授权服务器
- SS(Service Server) 特定服务提供端
- session_key随机生成的字符串
KDC(密钥分发中心),由Authentication Server(认证服务器)和Ticket Granting Server(票据授权服务器)组成,认证的时候,它会访问AD数据库。
Kerberos认证步骤
认证步骤主要有三个来回,过程简单描述为:
- 用户向KDC发送请求验证自己的身份
- KDC确认用户身份并给用户发送凭证
- 用户向KDC发送网络服务访问请求凭证
- KDC给用户发送网络服务凭证
- 用户使用网络服务凭证访问相应的网络服务
- 网络服务器确认网络服务凭证有效并向用户提供网络服务
详细过程为:
K(c,tgs):session_key(client与tgs之间的通信)
K(c,s):session_key(client与server之间的通信)
-
client->dc(kdc(as)):客户端向认证服务器(AS)发送一个认证请求,给AS发送的信息:
- 用户hash加密的时间戳以及其他一些信息
- 用户名明文
- TGS的一些信息
-
DC(KDC(AS))->client:认证服务器(AS)认证通过后(对比用户名是否在AD中),给客户端发送的信息:
- TGT(里面包含了PAC),也就是用krbtgt用户的hash加密后的Session Key以及时间戳
- Session Key明文
-
Client->DC(KDC(tgs)):客户端用Session_key加密自己的相关信息以及时间戳,向TGS申请ST(Service Ticket),向TGS发送的信息:
- TGT
- Session_key加密的自己的相关信息以及时间戳
- 客户端自己的信息(明文)
-
DC(KDC(tgs))->client:TGS拿到TGT和Session_key加密的信息之后,首先检查自身是否存在Client所申请的服务,如果存在就用krbtgt用户的hash解密TGT,获得session_key,再用session_key解密加密的信息,对比明文客户端信息和时间戳,如果都没问题,TGS会生成一个Server Session_key,给客户端发送的内容:
- AS的session_key加密的TGS session_key
- ST(ST中的PAC是TGT中的PAC复制进去的),也就是客户端申请的服务对应的hash加密TGS session_key
这一步不管用户有没有访问服务器的权限,只要TGT正确,就返回TGS。这也是**SPN提权(Kerboasting)**可以利用的原因,任何一个用户,只要hash正确就能拿到TGS,然后爆破TGS,拿到用户的密码。
-
Client->Server:客户端先用AS的session key解密得到TGS session_key,然后用TGS session_key加密时间戳,然后去访问服务器(无双向认证的话,认证通过后,即可访问,若双向认证,认证通过后继续走到第6步),给服务器发送的信息:
- ST
- TGS session_key加密的时间戳
-
Server->Client:服务器先用自己的hash解密ST,得到TGS session_key,再用TGS session_key解密加密的信息,校验时间戳,如果都没问题,放行,并且给客户端发送一个加密的时间戳,用于让客户端识别是否访问正确的服务端。给客户端发送的信息:
-
用TGS session key加密时间戳
-
S4U2SELF协议
微软引入s4u2self(Service for User to Self)和s4u2proxy(Service for User to Proxy)协议的目的是为了增强其身份验证和授权机制。
假设用户A访问服务B,服务B需要代替A去访问服务C。(约束委派)(如果是非约束委派,那就不用S4U2这两个扩展了,因为非约束委派那个时候他俩还没设计出来)
S4U2SELF使得服务B可以代表用户A获得服务B自身的kerberos服务票据。也就是也会拿到一个用户A对B的TGS,不过申请人是服务器B自身,而不是用户A。服务B自己拿着A的TGT申请的对于自己的TGS,我称为SSTGS,这个SSTGS会被用到后面的S4U2PROXY认证。这里面很重要的一点就是服务B获得SSTGS的整个过程中,服务B是不需要用户A的凭据的。
S4U申请的TGS会重新生成PAC,这也就是**sAMAccountName spoofing(CVE-2021-42278)**的核心原理
S4U2PROXY协议
S4U2PROXY协议则扩展了s4u2self协议的功能,允许服务B使用SSTGS去KDC那里请求服务C的TGS,并且代替用户A访问服务C,而且只能访问服务C。这种代理访问模式使得服务能够通过代表用户的身份请求其他服务的资源,而无需用户自己拥有直接访问该资源的权限。
Kerberos漏洞产生
- 密钥来源于用户密码
- 密钥存储在内存中
- 使用RC4加密算法的密钥没有进行加密处理,NTLM哈希值即为RC4密钥
- KDC密钥分发中心使用的密钥来源于krbtgt用户密码
- krbtgt用户密码很少更改,且更改后的旧密码仍然可用
- TGT票据使用krbtgt密钥进行加密,PAC数据使用krbtgt密钥进行签名
- Kerberos在用户登录20分钟后才会验证用户账户
基于以上原因,攻击者可借助krbtgt密码绕过身份验证系统,获取管理员访问权限,进而执行一系列管理员操作,还可以根据密码为用户创建响应的密钥。
kerberos漏洞利用
-
Kerberoasting
简单来说就是利用高权限账户的SPN进行申请TGS,通过爆破TGS得到高权限用户的密码,后面会有文章专门介绍。这里就不多说。
-
黄金票据
黄金票据主要发生在kerberos认证的第三步和第四步上,当我们知道krbtgt的ntlm_hash时,就可以伪造TGT凭证,发送给票据生成服务器(TGS),跳过了AS认证,直接向TGS申请ST。
我们自己伪造的TGT就是黄金票据
mimikatz利用命令:
kerberos::golden /user:xxx /domain:xxxx /sid:xxxx /krbtgt:xxxxxxx /ptt(直接pass the ticket) 如果后面不跟/ptt,那就还需要: kerberos::ptt xxxxx.kirbi mimikatz、kekeo、rubeus生成的票据是以.kirbi为后缀的。impacket生成的票据是以.ccache为后缀的。两种票据主要包含的都是session_key和加密的ticket,因此可以相互转化。 用aeskey也可以 mimikatz#kerberos::golden /user:xxx /domain:xxxx /sid:xxxx /aes256:xxxxxxxxxxxx /ptt
参数说明:
- sid:域SID
- user:伪造的用户名
- domain:域名
- krbtgt:krbtgt用户的hash
-
白银票据
白银票据主要是发生在第五步上,只要我们有了server_ntlm_hash,我们就可以伪造Ticket,也就是白银票据,它跳过了AS和TGS两大步,直接与Server进行对接。
mimikatz利用命令:
kerberos::golden /user:xxxxx /sid:xxxxx /domain:xxxxx /target:xxxxxx /rc4:xxxxx /service:xxx /ptt
但是我们伪造的白银票据没有带有有效KDC签名的PAC。如果将目标主机配置为验证KDC PAC签名,则银票将不起作用。
黄金票据和白银票据的不同点:
-
访问权限不同
黄金票据:伪造TGT,可以获取任何kerberos服务权限
白银票据:伪造TGS,只能访问指定的服务 -
加密方式不同
黄金票据由krbtgt的hash加密
白银票据由服务账号(通常为计算机账户)Hash加密 -
认证流程不同
黄金票据的利用过程需要访问域控,而白银票据不需要
PAC
在TGS_REP这一步中,TGS不管用户有没有访问服务器的权限,只要TGT正确,就返回TGS(ST)。但是这样就忽略了用户对该服务的访问权限的问题。
为了解决这个问题,微软就引进了PAC,PAC是可选的(但是在微软对于CVE-2021-42287的修补中,PAC已经是强制要求了,不然认证将失败),如果选择启用PAC。然后kerberos流程中主要有两步发生了变化::
- AS_REP,返回给用户的TGT中包含了PAC,PAC包含用户的sid,用户所在组。
- TGS_REP,返回给用户的TGS中包含了PAC,PAC包含用户的sid,用户所在组。
- AP_RES ,服务使用自己的hash解密TGS,如果解密成功,就拿着PAC去KDC询问该用户有没有访问权限,域控解密PAC。获取用户的sid,以及所在组,再判断用户是否有权限访问该服务。
PAC对于用户和服务全程都是不可见的。只有KDC能制作和查看PAC
因为PAC的安全问题导致的提权漏洞也有很多,比如说出名的ms14-068、sAMAccountName spoofing(CVE-2021-42278)等。