在工作组中常见的就是点对点的认证,基于`NTLM`认证协议,而在域中,则依赖`kerberos`认证协议。`kerberos`是一种计算机网络认证协议,为域中网络通信的两端提供身份验证服务,类似于第三方的信托机构。
- 在工作组中常见的就是点对点的认证,基于
NTLM
认证协议,而在域中,则依赖kerberos
认证协议。kerberos
是一种计算机网络认证协议,为域中网络通信的两端提供身份验证服务,类似于第三方的信托机构。 - 参考:https://seevae.github.io/2020/09/12/%E8%AF%A6%E8%A7%A3kerberos%E8%AE%A4%E8%AF%81%E6%B5%81%E7%A8%8B/
- https://ssooking.github.io/2019/12/%E5%9F%9F%E6%B8%97%E9%80%8F%E4%B9%8Bkerberos/
类比kerberos认证
- 这里类比一个场景来理解kerberos认证。假设有一家高级餐厅,这里转为高级官员用餐的地方,在这里用餐只能用凭借
会员证
、用餐券
才能入住就餐。有一个VIP用户想去就餐,那么他肯定要经过以下流程: - 用户到服务中心提供自己的姓名、身份证、手机号等信息请求服务中心颁发会员证
- 服务中心将用户提供的信息拿到数据库中进行核实是否存在这么一个VIP用户,存在则颁发会员证。
- 用户凭借会员证再到服务中心请求兑换用餐券,根据会员证上的等级和个人信誉信息,拿到了一张指定房间的用餐券。
- 用户拿着用餐券到指定房间用餐,若去其他房间则无法用餐。
- kerberos认证的机制与其相似,可以看出这里最重要的就是
会员证
和用餐券
。先拿到会员证,再凭借会员证去拿用餐券,服务中心则是KDC
,这里两次验证则类比分别对比我们KDC
中的AS
和TGS
,而指定的房间则类似于我们所请求的服务,会员证则类比于TGT
,用餐券则类比于Ticket
。
协议中的角色
- KDC(Key Distribution Center):密钥分发中心,包含AS和TGS两部分。
AS
可以生成TGT
,客户端将TGT
传输到TGS
,TGS
生成Ticket
返回给客户端,客户端带着Ticket
请求服务器。 - AS (Authentication Service):KDC中专门用来认证客户端身份的的身份认证服务服务器,客户端请求后鉴别成功后生成
TGT
。 - TGS (Ticket Grant Service):票据分发服务,
- TGT (Ticket Granting Ticket):票据授予凭证
- Ticket :票据,请求服务器的凭证。
Kerberos认证
- 这里分为三步走,
请求AS获得TGT
- 由于客户端是第一次访问KDC,KDC也无法确定客户端的身份是否为伪造的,因此第一次访问就是确认客户端的身份,我们发送的则是明文,请求响应如下。
- 客户端以明文的方式发送请求,其中请求包含用户名、IP、时间戳等信息。
AS
服务器收到请求数据后,将用户名拿到数据库进行查询,这里的数据库不再是Windows系统中常见的sam
,而是域控制器(DC)
上的NTDS.dit
,KDC
一般都部署在域控制器上面。此时只判断用户是否存在,有以下两种情况。
- 如果用户名不存在,认证服务结束。
- 如果用户名存在,那么AS服务器则会生成相应的数据返回给客户端。
- 返回的数据当中包含两部分:
TGT
(票据授权票据)、Session Key
(会话密钥)。
-
TGT
中包含域控制器中的存储客户端的用户名、IP、时间戳、访问的TGS服务器名称、TGT的有效时间(这里只有五分钟的实效),还有访问TGS的Session Key
,我理解为登陆的Cookie吧,这些都是经过TGS加密的,加密密钥在本地获取,没有网络传输,因此不存在劫持破解的风险,这里的密钥是域krbtgt账户的Hash
,只存在于域控制器上,因此客户端无法破解。 -
Session key
是KDC生成的一串随机字符串,然后再使用客户端的的NTLM Hash加密该Session Key
和客户端的用户、IP、请求时间戳、请求的TGS服务器后的得到第二部分加密内容。
- 密钥均未在网络中传输,因此不会被劫持,是比较安全的。客户端只有输入正确当前请求用户的Hash才可以解密第二部分的数据得到访问
TGS
的Session Key
,因此第一次通信结束。
请求TGS获得Ticket
- 客户端接收到
AS
服务器响应的内容后,因为我们不知道krbtgt账户的Hash
,因此只能解密第二部分的对响应。利用本地用户的Hash对第二部分响应进行解密,得到Session key
、请求时间戳和请求的TGS服务器等信息。判断请求时间戳于当前时间戳差值大于5分钟
则认为该请求无效或AS
服务器被伪造,否则便向TGS服务器发送请求,请求响应如下。
- 将AS响应的数据解密,发送以下请求。
- 以明文的形式发送想要访问的服务到TGS服务器。
- 将请求AS得到的TGT直接发送给TGS服务器。
- 将解密得到
Session Key
当作密钥加密客户端用户名、IP、时间戳、进行加密发送到TGS服务器。
TGS
服务器接收到请求后,判断请求到服务是否存在,有以下两种情况。
- 服务不存在,认证服务结束。
- 服务存在,继续进行验证。
- TGS用
krbtgt用户的Hash
对TGT进行解密,得到AS认证时记录的客户端信息、时间戳、请求IP信息、Session Key
。在用Session Key
对第二次请求对数据进行解密,对比两次数据的请求是否一致,是否发生篡改,如果可以解密,数据一致则认为认证成功。然后返回响应数据,响应数据包含两部分,如下:
- TGS生成一个
Service Session Key
用于客户端访问服务器的Session,并用之前的Session Key
对其进行加密处理。 - TGS生成
Server Ticket
,包含Service Session Key
和客户端的一些信息,并用服务器密码的Hash
对其进行加密。
- 目前我们这里只能对第一部分进行解密,因为我们有向AS服务器发送请求对
Session Key
。
携带Ticket请求服务器
- 客户端收到TGS的响应,这里会发送两部分数据,请求和响应结果如下:
- 客户端发送的请求如下:
- 收到响应因为无法解密
Server Ticket
票据,因此直接发送即可。 - 然后再用收到
Service Session Key
加密我们客户端的用户名、IP、请求时间戳等信息。
- 服务端收到消息之后用
服务器密码Hash
对Server Ticket
进行解密得到Service Session Key
,再对第二部分请求进行解密得到客户端的信息,因此则认证成功。服务器响应的数据如下:
- 将解密后的客户端信息用
Service Session Key
重新加密发送给客户端。 - 将加密后的
Server Ticket
缓存在自己的内存中
- 客户端收到消息后用本地缓存的
Service Session Key
对响应数据进行解密,如果数据和请求数据一样,那么则认证服务器的身份没有被篡改或劫持。 - 至此
kerberos认证
结束,后面访问只需携带Ticket即可,则无需再次认证。
总结
- 这里的有三次通信,第一次学习需要慢慢梳理,每次的请求都是随机生成的
Session Key
,且有时长限制,因此不用担心被破解,并且用户密钥都是在本地,并没有在网络中传播。但是这里认证过程中的Server Ticket
仍可能被伪造,就是后面所要提到的PTT(Pass The Ticket)票据传递攻击。 - 这里借用
seevae
师傅的一张图。
逆水行舟,不进则退。