#Kerberos协议认证全流程
-
Client申请TGT
Client向KDC的AS服务器提出请求。请求中包含Client用户hash加密的时间戳、Client Info等。之后由AS认证服务解密时间戳并在AD(活动目录)中查找该账户。如果能解密,且时间戳在一定的范围内,AS会生成一个随机的Session Key,并再返回给Client一张TGT票据(由krbtgt账户hash加密的Client info和
Session Key
)和Client账户hash加密后的Session Key
。 -
Client向TGS服务申请访问目标服务的Ticket
Client利用自己的Hash对加密后的
Session Key
解密,获得Session Key
。之后Client再次请求KDC访问目标服务。该请求包含TGT和使用Session Key
加密的Client info。KDC使用Ktbtgt的Hash对TGT解密,获取Client info和
Session Key
。使Session Key
对Client发来的被Session Key
加密的Client info进行解密,获得Client info后,再比对TGT中的Client info,相同则认证通过。通过认证后,TGS会返回一张服务Ticket和使用
Session Key
加密的Server Session key。这张服务Ticket使用Server hash加密,其中包含了Server session key和Client info。 -
Client向Server提交Ticket完成认证
Client收到消息后,使用
Session Key
解密获得Server Session Key。再向Server发送Server Session Key加密的Clinet info和TGS返回的服务Ticket。Server 使用自己的Hash解密Ticket,获得Server Session Key,再使用Server Session Key解密由Server Session Key加密的Clinet info,再比对Ticket中的Client info,相同则认证通过。
#Kerberos PAC
在前面介绍的Kerberos认证流程中,只要用户的hash正确,那么就可以拿到TGT,有了TGT就可以拿到TGS,有了TGS就可以访问服务,任何一个用户都可以访问任何服务。忽略一个最重要的因素,那就是用户有无权限访问该服务。
为了解决这个问题,微软引进了PAC,引进PAC之后的kerberos流程:
-
用户向KDC发起AS_REQ,请求凭据是用户hash加密的时间戳,KDC使用用户hash进行解密,如果结果正确返回用krbtgt hash加密的TGT票据,TGT里面包含PAC(包含用户的sid以及用户所在的组)。
-
用户凭借TGT票据向KDC发起针对特定服务的TGS_REQ请求,KDC使用krbtgt hash进行解密,如果结果正确,就返回用服务hash加密的TGS票据。这一步不管用户有没有访问服务的权限,只要TGT正确,就返回TGS票据。
-
用户拿着TGS票据去请求服务,服务使用自己的hash解密TGS票据。如果解密正确,就拿着PAC去KDC询问用户有没有访问权限。
域控解密PAC,获取用户的sid以及所在的组,再判断用户是否有访问服务的权限。
注:PAC对于用户和服务全程都是不可见的,只有KDC能制作和查看PAC。
#S4U2SELF
S4U2self 使得服务可以代表用户获得针对服务自身的kerberos服务票据。这使得服务可以获得用户的授权(可转发的用户TGS票据),然后将其用于后期的认证(主要是后期的s4u2proxy),这是为了在用户以不使用Kerberos的方式对服务进行身份验证的情况下使用。很重要的一点是服务代表用户获得针对服务自身的kerberos票据这个过程中服务是不需要用户的凭据的。
s4u2self的过程如下图所示
前提条件:服务已经有通过KDC验证的TGT(是以服务的自己身份去申请的TGT)
步骤1中服务(JACKSON-PC$)使用S4U2self扩展名代表用户(administrator)获得针对服务本身(JACKSON-PC$)的服务票证。该服务将填写PA_FOR_USER数据结构,类型为S4U2SELF,再将请求发送到TGS。
如果TGS支持PA_FOR_USER扩展,则TGS在步骤2中通过KRB_TGS_REP消息返回用户的服务票证。如果服务请求了可转发选项,并且TGS的本地策略允许,则TGS检验通过后必须将票证标志字段设置为可转发。
既只要满足下面三个条件,则TGS必须将票证标志字段设置为可转发。
- 服务申请的TGT是可以转发的
- 服务配置了约束委派
- 服务请求了可转发选项
如果用户的UserAccountControl字段中设置了USER_NOT_DELEGATED位,那么返回的TGS是永远也没法转发的。例如当Administrator配置了敏感账户不能被委派,返回的TGS的flag字段没有forwardable。
#S4U2PROXY
s4u2proxy使得服务1向KDC请求访问服务2的TGS,代表用户访问服务2。
在步骤1中,服务1代表用户获取服务2的服务票证。服务1发送KRB_TGS_REQ消息,并将S4U2SELF阶段获得的票据作为请求中的AddtionTicket。
如果满足下面这些条件,则在步骤2中TGS会制作KRB_TGS_REP消息以返回服务票证(可转发的)
- 拥有来自用户的授权(在S4U2SELF阶段获得的TGS票据),放在AddtionTicket里面。
- 在请求的kdc-options中设置了CNAME-IN-ADDL-TKT标志。
- 服务请求了可转发选项
- 服务1有到服务2的约束委派,将服务2的SPN放在sname里面。
#委派
被设置委派的对象只能是拥有SPN的账户
#非约束委派
服务1被配置了非约束的委派,那么服务1可以接受任何用户的委派的去请求其他所有服务。例如:某个用户委托服务1访问某个服务,那么这个用户会将TGT(在TGS里面)发送到服务1并缓存到服务1的LSASS中。然后服务1代表用户去请求某个服务。
#约束委派
约束委派会用到两个扩展S4U2Self和S4U2Proxy。计算机用户(JACKSON-PC$
) 被配置了到某个服务的约束委派,那么JACKSON-PC$
可以模拟任何用户去请求该服务。相较于非约束委派,约束委派在配置的时候需要指定委派某个服务,而不是所有服务。
收到用户的请求后,首先代表用户获得针对服务自身的可转发的kerberos服务票据(S4U2SELF)。拿着这个票据向KDC请求访问特定服务的可转发的TGS(S4U2PROXY)并代表用户访问特定服务。
- 服务1以服务账号hash加密时间戳并设置可转发的字段,再向KDC申请可转发的TGT。
- 服务1携带可转发的TGT并使用S4U2self扩展名代表用户(例如:Administrator)获得针对服务1本身的TGS票证(可转发的TGS)。 S4U2Self
- 服务1携带步骤1申请到的TGT和步骤2获取的可转发的TGS票证作为addtionTicket一起发送给KDC。请求代表用户访问服务2的TGS。 S4U2Proxy
- 服务1拿着TGS代表用户administrator向服务2发起请求。
Tips:
- S4U2self使得服务可以代表用户获得针对服务自身的kerberos服务票据。这个过程中服务代表用户获得针对服务自身的kerberos票据,服务是不需要用户的凭据的。
- 在步骤2中如果Administrator用户被配置敏感账户不能被委派的话,那么KDC返回的TGS就不是可转发的,就无法被用来做约束委派。
#基于资源的约束委派
基于资源的约束委派只能在运行Windows Server 2012 R2和Windows Server 2012的域控制器上配置,但可以在混合模式林中应用。约束委派不能跨域进行委派,基于资源的约束委派可以跨域和林。
约束与非约束委派需要域管理员才能设置,而基于资源的约束委派则不需要域管理员权限,把设置属性的权限赋给了机器自身。
基于资源的约束委派与传统约束委派非常相似但配置相反。服务1到服务2的约束委派在服务1账户的msDS-AllowedToDelegateTo
属性中配置,定义从服务1到服务2的传出信任。基于资源的约束委派是在服务2的msDS-AllowedToActOnBehalfOfOtherIdentity
属性中配置,定义从服务1到服务2的"传入"信任。只要拥有服务2的权限就可以配置服务2的基于资源的约束委派。