域内横向渗透-PTT票据传递之kerberos认证原理详解
Kerberos 认证原理
首先我们根据以下这张图来大致描述以下整个认证过程:
- 首先 Client 向域控制器 **DC (Domain Cotroller)**请求访问 Server,DC 通过去 AD 活动目录中查找依次区分 Client 来判断 Client 是否可信。
- 认证通过后返回
TGT(Ticket Granting Ticket 票据认证票据)
给 Client,Client 得到 TGT。 - Client 继续拿着 TGT 请求 DC 访问 Server,
TGS(Ticker Granting Server 票据授权服务器)
通过 Client 消息中的 TGT,判断 Client 是否有访问权限。 - 如果有,则给 Client 有访问 Server 的权限 Ticket,也叫
ST(Service Ticket)
。 - Client 得到 Ticket 后,再去访问 Server,且该 Ticket 只针对这一个 Server 有效。
- 最终 Server 和 Client 建立通信。
下面讲一下详细的认证步骤,大概分为三个阶段:
• ASREQ&ASREP
• TGSREQ&TGSREP
• AP-REQ & AP-REP
ASREQ & ASREP
该阶段是 Client 和 AS 的认证,通过认证的客户端将获得 TGT 认购权证。
当域内某个客户端用户 Client 视图访问域内的某个服务,于是输入用户名和密
码,此时客户端本机的 Kerberos 服务会向 KDC 的 AS 认证服务发送一个AS_REQ认证请求。请求的凭据是 Client 的哈希值 NTLM-Hash 加密的时间戳以及 Clientinfo、Server-info 等数据,以及一些其他信息。
当 Client 发送身份信息给 AS 后,AS 会先向活动目录 AD 请求,询问是否有此
Client 用户,如果有的话,就会取出它的 NTLM-Hash,并对AS_REQ请求中加密的时间戳进行解密,如果解密成功,则证明客户端提供的密码正确,如果时间戳在五分钟之内,则预认证成功。然后 AS 会生成一个临时秘钥 Session-Key AS,并使用客户端 Client 的 NTLM-Hash 加密 Session-key AS 作为响应包的一部分内容。
此Session-key AS
用于确保客户端和 KGS 之间的通信安全。
还有一部分内容就是 TGT
:使用 KDC 一个特定账户的 NTLM-Hash 对 Session-key
AS、时间戳、Client-info 进行的加密。这个特定账户就是创建域控时自动生成的 Krbtgt 用户,然后将这两部分以及 PAC 等信息回复给 Client,即AS_REP。PAC 中包含的是用户的 SID、用户所在的组等一些信息。
AS-REP 中最核心的东西就是 Session-key 和 TGT。我们平时用
Mimikatz、kekeo、rubeus 等工具生成的凭据是 .kirbi 后缀,Impacket 生
成的凭据的后缀是 .ccache。这两种票据主要包含的都是 Session-key 和
TGT,因此可以相互转化。
至此,Kerberos 认证的第一步完成。
TGSREQ & TGSREP
该阶段是 Client 和 TGS 的认证,通过认证的客户端将获得 ST 服务票据。
客户端 Client 收到 AS 的回复AS_REP后分别获得了 TGT 和加密的 Session-Key
AS。它会先用自己的 Client NTLM-hash 解密得到原始的 Session-Key AS,然后它会在本地缓存此 TGT 和原始的 Session-Key AS,如果现在它就需要访问某台服务器上
的服务,他就需要凭借这张 TGT 认购凭证向 KGS 购买相应的 ST 服务票据(也叫
Ticket)。
此时 Client 会使用 Session-Key AS 加密时间戳、Client-info、Server-info 等数据作为一部分。由于 TGT 是用 Krbtgt 账户的 NTLM-Hash 加密的,Client 无法解密,所以 Client 会将 TGT 作为另一部分继续发送给 TGS。两部分组成的请求被称为TGS_REQ。
TGS 收到该请求,用 Krbtgt 用户的 NTLM-hash 先解密 TGT 得到 Session-key AS、时间戳、Client-info 以及 Server-info。再用 Session-key AS 解密第一部分内容,得到 Client-info、时间戳。然后将两部分获取到时间戳进行比较,如果时间戳跟当前时间相差太久,就需要重新认证。TGS 还会将这个 Client 的信息与 TGT 中的 Client 信息进行比较,如果两个相等的话,还会继续判断 Client 有没有权限访问 Server,
如果都没有问题,认证成功。认证成功后,KGS 会生成一个 Session-key TGS,并
用 Session-key AS 加密 Session-key TGS 作为响应的一部分。此 Session-key TGS 用于确保客户端和服务器之间的通信安全。
另一部分是使用服务器 Server 的 NTLM-Hash 加密 Session-key TGS、时间戳以及
Client-info 等数据生成的 ST。然后 TGS 将这两部分信息回复给 Client,即
TGS_REP。
至此,Client 和 KDC 的通信就结束了,然后是和 Server 进行通信。
AP-REQ & AP-REP
该阶段是 Client 和 Server 的认证,通过认证的客户端将与服务器建立连接。
客户端 Client 收到TGS_REP后,分别获得了 ST 和加密的 Session-Key TGS
。它会先使用本地缓存了的 Session-key AS 解密出了原始的 Session-key TGS。然后它会在本地缓存此 ST 和原始的 Session-Key TGS,当客户端需要访问某台服务器上的服务时会向服务器发送请求。它会使用 Session-key TGS 加密 Client-info、时间戳等信息作为一部分内容。ST 因为使用的是 Server NTLM-hash 进行的加密,无法解密,所以会原封不动发送给 Server。
两部分一块发送给 Server,这个请求即是AP_REQ。Server 收到AP_REQ请求后,用自身的 Server NTLM-Hash 解密了 ST,得到Session-Key TGS,再解密出 Client-info、时间戳等数据。然后与 ST 的 Client-info、时间戳等进行一一对比。时间戳有效时间一般时间为 8 小时。通过客户端身份验证后,服务器 Server 会拿着 PAC 去询问 DC 该用户是否有访问权限,DC 拿到PAC 后进行解密,然后通过 PAC 中的 SID 判断用户的用户组信息、用户权限等信息,然后将结果返回给服务端,服务端再将此信息域用户请求的服务资源的 ACL 进行对比,最后决定是否给用户提供相关的服务。通过认证后 Server 将返回最终的AP-REP并与 Client 建立通信。
至此,Kerberos 认证流程基本结束。
PAC
我们在前面关于 Kerberos 认证流程的介绍中提到了 PAC(Privilege Attribute Certificate)
这个东西,这是微软为了访问控制而引进的一个扩展,即特权访问证书。
在上面的认证流程中,如果没有 PAC 的访问控制作用的话,只要用户的身份验证正确,那么就可以拿到 TGT,有了 TGT,就可以拿到 ST,有了 ST ,就可以访问服务了。此时任何一个经过身份验证的用户都可以访问任何服务。像这样的认证只解决了 “Who am i?” 的问题,而没有解决 “What can I do?” 的问题。
为了解决上面的这个问题,微软引进了 PAC。即 KDC 向客户端 Client 返回AS_REP 时插入了 PAC,PAC 中包含的是用户的 SID、用户所在的组等一些信息。当最后服务端 Server 收到 Client 发来的AP_REQ请求后,首先会对客户端身份验证。通过客户端身份验证后,服务器 Server 会拿着 PAC 去询问 DC 该用户是否有访问权限,
DC 拿到 PAC 后进行解密,然后通过 PAC 中的 SID 判断用户的用户组信息、用户权限等信息,然后将结果返回给服务端,服务端再将此信息域用户请求的服务资源的
ACL 进行对比,最后决定是否给用户提供相关的服务。
但是在有些服务中并没有验证 PAC 这一步,这也是白银票据能成功的前提,因为就算拥有用户的 Hash,可以伪造 TGS,但是也不能制作 PAC,
PAC 当然也验证不成功,但是有些服务不去验证 PAC,这是白银票据成功的前提。