0x00 简介
Kerberos
是一种由MIT(麻省理工大学)提出的一种网络身份验证协议,它旨在通过使用密钥加密技术为客户端/服务器应用程序提供强身份验证。
Kerberos认证解决了”如何证明我就是我”这个问题
0x01 协议组成角色
Kerberos
协议中主要是有三个角色的存在:
- 访问服务的
Client
- 提供服务的
Server
KDC(Key Distribution Center)
密钥分发中心
KDC
默认会安装在一个域的域控中,它负责管理票据、认证票据和分发票据,但KDC
不是一个独立的服务,它是由以下服务组成:
- Authentication Server(AS):
AS
的作用就是验证Client
的身份,当验证通过时分发一个TGT(Ticket Granting Ticket)
票据给Client
- Ticket Granting Server(TGS):
TGS
的作用就是通过AS
发给Client
的票据TGT
换取访问Server
的票据ST(Server Ticket)
另外还需要补充一个AD(Account database)
,它类似于本地认证的SAM
文件,存储了所有Client
的白名单,只有存在于白名单的Client
才能申请到TGT
。
从物理层面看,KDC
和AD
均为域控制器(Domain Controller)。
0x02 认证过程
域认证流程图如下:
域认证粗略流程
粗略流程分为三大步:
Client
向KDC
请求,希望获取访问Server
的权限。KDC
得到了这个消息,首先得判断Client
是否是可信赖的,也就是白名单黑名单的说法。这就是AS
服务完成的工作,通过在AD
中存储黑名单和白名单来区分Client
。成功后,返回AS
返回TGT
给Client
Client
得到了TGT
后,继续向KDC
请求,希望获取访问Server
的权限。KDC
又得到了这个消息,这时候通过Client
消息中的TGT
,判断出了Client
拥有了这个权限,给了Client
访问Server
的权限ticket
Client
得到ticket
后,终于可以成功访问Server
。这个ticket
只是针对这个Server
,其他Server
需要向TGS
申请。
域认证
Kerberos
认证协议主要步骤如下:
- AS - REQ
- AS - REP
- TGS - REQ
- TGS - REP
- AP - REQ
- AP -REP
相关图片引用倾旋大佬blog
AS - REQ
客户端将时间戳、用户名test
、用户名所属的域、请求的服务名等信息发送给AS
服务器。其中客户端使用test
用户的NTLM hash
加密时间戳作为Authentication1
。
AS - REP
AS
收到来自客户端的数据后,先根据用户名在AD
中查找是否存在白名单中,如果存在则取出test
用户对应的NTLM Hash
来解密Autherticator1
,若解密成功得到时间戳,并且时间戳在五分钟内,则代表预认证成功,接下来发送响应包。
KDC
此时会生成一个随机字符串,叫Sesssion Key
,使用用户名test
对应的NTLM Hash
加密Session Key
,为了描述简单,这里我们用enc_key1
来代表这个被加密的Session Key
值。
另外一部分数据为TGT
,是由KDC
中一个用户krbtgt
的NTLM Hash
加密Session Key
和相关客户端信息,通常TGT
的到期时间为8个小时,如果超过这个时间就需要重新申请TGT
。
enc_key1
有些文章中也称作Login Session Key
,它的作用是用于确保客户端和KDC
的下一阶段之间的通信安全,作为下一阶段的认证密钥
TGS - REQ
客户端收到来自KDC
的响应后,用自身的NTLM Hash
对enc_key1
解密,得到KDC
中生成的随机字符串Sesssion Key
,然后将时间戳、客户端信息等数据用Session Key
进行加密得到Authentication2
,连同收到的TGT
一起发送给TGS
,换取访问指定Server
的票据。
TGT
中的数据因为是使用KDC
中特殊的用户krbtgt
的NTLM Hash
加密,所以无法解密。
PS:如果我们抓取到
krbtgt
用户的NTLM Hash
就可以伪造黄金票据
TGS - REP
TGS
收到请求后,首先会检查KDC
中是否存在所需的服务。然后解密TGT
获得Session Key
、时间戳和客户端相关信息,使用Session Key
解密Authentication2
中的数据得到用户名、时间戳等信息。验证TGT
和Authentication2
中的信息是否正确,如果正确则生成ST(Server Tikcket)
票据,和一个新的随机字符串Session Key
,我们这里称之为Server Session Key
。
其中Server Session Key
被AS-REP
中的Session Key
加密生成ent_key2
。使用服务端对应的NTLM Hash
加密Server Session Key
、客户端信息和结束时间等数据生成ST
票据。然后一起发送给客户端。
在这一阶段中,微软引进了两个扩展
S4U2SELF
和S4U2PROXY
,用来解决非约束委派不安全性问题,相关内容会在以后详细说明
AP - REQ
客户端收到TGS
的响应包后,在TGS - REQ
步骤中获得的Session Key
解密Authentication2
得到Server Session Key
,将时间戳、用户名等信息加密连同ST
一起发送给服务端。
PS:如果我们抓取到服务端的
NTLM Hash
就可以伪造白银票据
AP - REP
服务器端收到请求后,使用自身NTLM Hash
对ST
进行解密,得到Server Session Key
和客户端信息,利用Server Session Key
解密enc_key2
得到客户端信息和时间戳,验证客户端信息和时间戳。
如果验证通过,该票据会一直存在客户端内存中。
Kerberos的攻击方法
0x03 黄金票据和白银票据
黄金票据
原理
黄金票据出现在在AS - REQ & AS - REP
中。客户端通过AS
认证后,会给客户端返回TGT
和enc_key1
。其中TGT
使用krbtgt
用户NTLM Hash
加密,如果我们拥有krbtgt
用户NTLM Hash
,就可以自己给自己签发任意用户的TGT
票据。
特点
- 需要与
KDC
通信 - 需要
krbtgt
用户NTLM Hash
操作
1 | # 导出用户hash(生成Golden Ticket不仅可以使用aes256,也可用krbtgt的NTLM hash) |
白银票据
原理
白银票据出现在TGS - REQ & TGS - REP
中。客户端通过TGS
认证后,会给客户端返回ST
和enc_key2
。其中ST
使用服务端用户NTLM Hash
加密,如果我们拥有服务端用户NTLM Hash
,就可以自己给自己签发ST
票据。
特点
- 不需要与
KDC
通信 - 需要目标服务
NTLM Hash
操作
1 | # 导出用户hash |
由于白银票据需要目标服务器的Hash
,所以没办法生成对应域内所有服务器的票据,也不能通过TGT
申请。因此只能针对服务器上的某些服务去伪造,伪造的服务类型列表如下:
服务注释 | 服务名 |
---|---|
WMI | HOST、RPCSS |
Powershell Remoteing | HOST、HTTP |
WinRM | HOST、HTTP |
Scheduled Tasks | HOST |
LDAP 、DCSync | LDAP |
Windows File Share (CIFS) | CIFS |
Windows Remote ServerAdministration Tools | RPCSS、LDAP、CIFS |
区别
- 访问权限不同
黄金票据伪造TGT
,从而获取任意Kerberos
服务权限
白银票据伪造TGS
,只能访问指定Kerberos
服务
- 加密方式不同
黄金票据由krbtgt
的NTLM Hash
加密
白银票据由目标机器的对应NTLM Hash
加密
- 认证流程不同
黄金票据利用过程需要和KDC
通信
白银票据不需要
0x05 MS14-068
PAC与Kerberos
Kerberos
认证解决了”Who am I”这个问题,但没有解决”what can I do”,只要用户的NTLM Hash
正确,就可以拿到TGT
,就可以访问任意服务。所以为了解决这个问题,微软引进了PAC(Privilege Attribute Certificate)
,特权属性证书来增加认证过程中的权限认证。
在一个域中,如果判断一个域用户的权限。只需要提供域用户SID
和所在组SID
。而在域内KDC
,Client
和Server
之间,Server
只信任KDC
所提供的权限说明。所以在一个域初始时,KDC
拥有Client
和Server
的权限,KDC
告诉Server
关于Client
的权限,Server
验证权限后再决定是否让Client
访问自身的网络资源。
因此,微软在Kerveros
认证流程中的第2步AS-REP
中增加的对Client
的PAC(特权属性证书)
,也就是Client
的权限。
由上图可以看到,PAC
是被加密放置在TGT
票据中的,并且在PAC
的尾部还设置了两处签名校验:Server Signature
和KDC Signature
(此处两处签名校验均为krgtbt
账号对应NTLM Hash
生成,而TGT
也使用krgtbt
的NTLM Hash
进行加密,但三者不同点是对应的算法和加密内容不同)
AS
将PAC
加密放在TGT
中通过Client
传递给TGS
,TGS
解密后生成包含PAC
的ST
票据继续通过Client
转发给Server
,Server
即可判断Client
的权限。
在
TGS-REQ/REP
阶段,携带PAC
的TGT
被TGS
服务接收后,认证Client
的合法性后(解密Authentication2
符合认证要求),会将PAC
解密出来,首先验证尾部的两个签名是否合法,如果合法则认为PAC
没有被篡改,然后在PAC
的尾部更换两处签名:Server Signature
更换使用Server
对应NTLM Hash
生成签名,KDC Signature
使用AS
中生成的Session Key
生成签名。最后将签名的PAC
放置在ST
票据中进行加密从而传给Server
漏洞产生
在Client
发起认证请求时(AS-REQ
),通过设置include-PAC
为False
,那么返回的TGT
中不会包含PAC
信息
对于
PAC
尾部的签名算法,虽然原理上规定要求带有Key
的签名算法才可以,但是该漏洞却允许任意签名算法,只要Client
指定签名算法,KDC
便会使用指定算计对签名进行校验。所以使用不需要Key
值的MD5
进行签名,对构造好的高权data
(User SID & Group SID
)数据进行MD5
加密作为签名,KDC
中通过对data
加密比对尾部签名是否一致来认证该签名的合法。根据上文简介
PAC
的相关内容,原理上PAC
应该放置在TGT
中,但实际上PAC
放在TGS-REQ
的其他位置,并且KDC
中仍能正常解析出数据包中的PAC
信息。
PAC
被加密放在了TGS-REQ
中的req-body
里,被Subkey
(Subkey
为Client
随机生成数)加密。而解密用的Subkey
值放在Authentication2
发送给TGS
,TGS
通过解密Authentication2
得到Subkey
,从而正确解析被加密的PAC
值并验证为合法。
·
3. 前两步中设置include-PAC
为False
,验证TGT
中的PAC
数据合法性,KDC
从Authentication2
中取出Subkey
,根据Subkey
验证PAC
合法性后,KDC
重新使用自身的Server NTLM Hash
和Krbtgt NTLM Hash
生成尾部签名,拼接得到符合标准流程的PAC
文件。然后用完全合法的PAC
文件重新生成TGT
票据并返回。Subkey
加密Server Session key
生成enc_key2
,后续以便于Client
验证KDC
的身份。
也就是说,原本TGS-REP
阶段返回的ST
票据却返回了TGT
票据。
0x06 引用
Windows内网协议-Kerberos
彻底理解Windows认证 - 议题解读
内网渗透之kerberos协议分析
深入解读MS14-068漏洞:微软精心策划的后门?