什么是委派
在域中如果出现A
使用Kerberos
身份验证访问域中的服务B
,而B
再利用A
的身份去请求域中的服务C
,这个过程就可以理解为委派。
例:
User
访问主机s2
上的HTTP
服务,而HTTP
服务需要请求其他主机的SQLServer
数据库,但是S2
并不知道User
是否有权限访问SQLServer
,这时HTTP
服务会利用User
的身份去访问SQLServer
,如果User
有权限访问SQLServer
服务才能访问成功。
而委派主要分为非约束委派(Unconstraineddelegation
)和约束委派(Constrained delegation
)两个方式,下面分别介绍两种方式如何实现。
非约束委派
非约束委派在Kerberos
中实现时,User
会将从KDC
处得到的TGT
发送给访问的service1
(可以是任意服务),service1
拿到TGT
之后可以通过TGT
访问域内任意其他服务,所以被称为非约束委派。
流程:
-
用户通过发送
KRB_AS_REQ
消息请求可转发TGT
(forwardable TGT
,为了方便我们称为TGT1
)。 -
KDC
在KRB_AS_REP
消息中返回TGT1
。 -
用户再通过TGT1向KDC请求转发
TGT
(forwardedTGT
,我们称为TGT2
)。 -
在
KRB_TGS_REP
消息中返回转发TGT2
。 -
用户使用
TGT1
向KDC
申请访问Service1的ST
(ServiceTicket
)。 -
TGS
返回给用户一个ST
。 -
用户发送
KRB_AP_REQ
请求至Service1
,这个请求中包含了TGT1
和ST
、TGT2
、TGT2
的SessionKey
。 -
Service1
使用用户的TGT2
通过KRB_TGS_REQ
发送给KDC
,以用户的名义请求能够访问Service2
的票据。 -
KDC
在KRB_TGS_REP
消息中返回Service2
到Service1
的票据。 -
Service1
以用户的名义像Service2
发送KRB_AP_REQ
请求。 -
Service2
响应步骤10中Service1
的请求。 -
Service1
响应步骤7中用户的请求。 -
在这个过程中的
TGT
转发机制,没有限制Service1
对TGT2
的使用,也就是说Service1
可以通过TGT2
来请求任意服务。 -
KDC
返回步骤13中请求的票据。 -
15和16即为
Service1
通过模拟用户来访问其他Service
。
可以看到在前5个步骤中User
向KDC
申请了两个TGT
(步骤2和4),一个用于访问Service1
一个用于访问Service2
,并且会将这两个都发给Service1
。并且Service1
会将TGT2
保存在内存中。
非约束委派的设置
Windows域中可以直接在账户属性中设置
在Windows系统中,普通用户的属性中没有委派(Delegation)这个选项卡,只有服务账号、主机账号才有。如下图所示。
约束委派
由于非约束委派的不安全性,微软在windows2003
中发布了约束委派的功能。约束委派在Kerberos
中User
不会直接发送TGT
给服务,而是对发送给service1
的认证信息做了限制,不允许service1
代表User
使用这个TGT
去访问其他服务。这里包括一组名为S4U2Self
(Service for User to Self
)和S4U2Proxy
(Service forUser to Proxy
)的Kerberos
协议扩展。
从下图可以看到整个过程其实可以分为两个部分,第一个是S4U2Self
的过程(流程1-4),第二个是S4U2Proxy
的过程(流程5-10)。
流程:
-
用户向
Service1
发送请求。 -
这时在官方文档中的介绍是在这一流程开始之前
Service1
已经通过KRB_AS_REQ
得到了用户用来访问Service1
的TGT
,然后通过S4U2self
扩展模拟用户向KDC
请求ST
。 -
KDC
这时返回给Service1
一个用于用户验证Service1
的ST
(我们称为ST1
),并且Service1
用这个ST1
完成和用户的验证过程。 -
Service1
在步骤3使用模拟用户申请的ST1
完成与用户的验证,然后响应用户。注:这个过程中其实
Service1
是获得了用户的TGT
和ST1
的,但是S4U2Self
扩展不允许Service1
代表用户去请求其他的服务。 -
用户再次向
Service1
发起请求,此时Service1
需要以用户的身份访问Service2
。这里官方文档提到了两个点:A.
Service1
已经验证通过,并且有一个有效的TGT
。B.
Service1
有从用户到Service1
的forwardableST
(可转发ST
)。个人认为这里的forwardable ST
其实也就是ST1
。 -
Service1
代表用户向Service2
请求一个用于认证Service2
的ST
(我们称为ST2
)。用户在ST1
中通过cname
(client name
)和crealm
(client realm
)字段标识。 -
KDC
在接收到步骤6中Service1
的请求之后,会验证PAC
(特权属性证书,在第一篇中有说明)的数字签名。如果验证成功或者这个请求没有PAC
(不能验证失败),KDC
将返回ST2
给Service1
,不过这个ST2
中cname
和crealm
标识的是用户而不是Service1
。 -
Service1
代表用户使用ST2
请求Service2
。Service2
判断这个请求来自已经通过KDC
验证的用户。 -
Service2
响应Service1
的请求。 -
Service1
响应用户的请求。
在这个过程中,S4U2Self
扩展的作用是让Service1
代表用户向KDC
验证用户的合法性,并且得到一个可转发的ST1
。S4U2Proxy
的作用可以说是让Service1
代表用户身份通过ST1
重新获取ST2
,并且不允许Service1
以用户的身份去访问其他服务。更多的细节可以参考官方的文档,和RFC4120
的内容。
同时注意forwardable
字段,有forwardable
标记为可转发的是能够通过S4U2Proxy
扩展协议进行转发的,如果没有标记则不能进行转发。
https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-sfu/3bff5864-8135-400e-bdd9-33b552051d94
约束委派的设置
发现域中的委派主机或账户
在域中,可以通过PowerView
脚本来搜索开启了委派的主机和用户。查询非约束委派主要是通过搜索userAccountControl
属性包含ADS_UF_TRUSTED_FOR_DELEGATION
的主机或账户。而约束委派则通过查询userAccountControl
属性包含TRUSTED_TO_AUTH_FOR_DELEGATION
的主机或用户。
非约束委派
PowerView的下载地址:PowerView
加载PowerView
脚本
Import-Module .\PowerView.ps1
查询域中配置非约束委派的账户:
Get-NetUser -Unconstrained -Domain test.com
查询域中配置非约束委派的主机:
Get-NetComputer -Unconstrained -Domain test.com
在另一个版本的PowerView
中采用的是Get-DomainComputer
Get-DomainComputer -Unconstrained-Properties distinguishedname,useraccountcontrol -Verbose | ft -a
约束委派
查询域中配置约束委派的账户:
Get-DomainUser –TrustedToAuth -Properties distinguishedname,useraccountcontrol,msds-allowedtodelegateto| fl
查看设置了约束委派的用户
Get-DomainUser -TrustedToAuth -Domain test.com
查询域中配置约束委派的主机:
Get-DomainComputer -TrustedToAuth -Domain test.com
参考文章
https://www.freebuf.com/articles/system/198381.html