域渗透-约束委派与非约束委派
这个是在打春秋云镜的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
然后我们再看一下约束委派的用户,同样它的userAccountControl
属性包含了TRUSTED_TO_AUTH_FOR_DELEGATION
,但是它比非约束委派的用户多了一个msDS-AllowedToDelegateTo
属性,里面包含了允许委派的服务
注意 : 委派的用户只能是————————-主机用户和服务用户
为什么需要域委派
为什么需要域委派呢,比如现在有web服务器和文件服务器,当用户A访问web服务器去请求某个资源时,web服务器上本身并没有该资源,所以web服务器就会从文件服务器上调用这个资源,其中发生的过程若以域委派的形式进行,那么就是:
用户A访问web服务器,服务器再以用户A的身份去访问文件服务器。
域委派流程
一个域内普通用户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能访问的服务)了
非约束委派的请求过程(图来自微软手册):
上图的Kerberos请求描述分为如下步骤:
1 | 1. 用户向`KDC`发送`KRB_AS_REQ`消息请求可转发的`TGT1`。 |
注:TGT1(forwardable TGT)
用于访问Service1
,TGT2(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
这个主机用户设置为非约束委派
然后我们以administrator
的身份通过WinRM
服务远程连接DM2008
注:常见的连接方式还有:MSSQL和IIS,不过我们这里为了方便演示就直接用WinRM了
这个时候域管理员的TGT已经缓存在DM2008
了,我们用mimikatz即可dump出来
1 | privilege::debug |
可以看到[0;1622d8]-2-0-60a00000-Administrator@krbtgt-QIYOU.COM.kirbi
即为域管理administrator
的TGT
此时我们访问域控是被拒绝的
然后通过ptt将TGT注入到当前会话中
1 | kerberos::ptt [0;1622d8]-2-0-60a00000-Administrator@krbtgt-QIYOU.COM.kirbi |
成功访问
注意:访问域控要用主机名或者是FQDN
,使用IP还是会提示拒绝访问
这里将域管理员的TGT票据注入到本机内存中后 那么我们就拥有了域管理员的权限了
如果想执行命令的话,我们可以用WinRM
服务来远程连接域控服务器
1 | Enter-PSSession -ComputerName WIN-QFPHJSM1L7G |
-ComputerName
指定主机名- 如果你WinRM服务端口改了的话,可以用
-Port
指定WinRM
端口,默认是5985
注:Windows Server 2012
及以上默认是开启WinRM服务的,Windows Server 2008 R2
需要winrm quickconfig -q
来启动WinRM
服务,还要注意一点就是这条命令运行后会自动添加防火墙策略,防火墙默认会放行5985端口的。(这里的话是给被控主机开启这个WinRM服务)
非约束委派+Spooler打印机服务
如果只是单纯的非约束委派话需要管理员主动连接,所以在实战环境利用比较鸡肋。
利用非约束委派+Spooler打印机服务可以强制指定的主机进行连接,这个利用场景是tifkin_
,enigma0x3
和harmj0y
在DerbyCon 2018
提出的
演讲PPT:地址
利用原理:利用Windows打印系统远程协议(MS-RPRN)
中的一种旧的但是默认启用的方法,在该方法中,域用户可以使用MS-RPRN RpcRemoteFindFirstPrinterChangeNotification(Ex)
方法强制任何运行了Spooler
服务的计算机以通过Kerberos
或NTLM
对攻击者选择的目标进行身份验证。
(这里的话重点看利用原理就行了 简单易懂)
注:Print Spooler
服务默认是自动运行的
(用自己电脑搜索就行了 是可以看到是默认开启的)
操作环境:
- 域:
test.local
- 域控:系统:
Windows server 2012R2
主机名:DM2012
,ip:192.168.141.134
- 域内主机:系统:
windows 10
,主机名:win10
,ip:192.168.141.165
这个实现了前提是:需要获取一台主机账户开启了非约束委派域内机器的权限
我们给win10这个主机账户开启非约束委派
注:是主机账户开启非约束委派,而不是服务用户
tifkin_
在他的github上开源了POC:https://github.com/leechristensen/SpoolSample
向DM2012的Spooler
服务发送请求,强制其访问win10进行身份验证
1 | SpoolSample.exe dm2012 win10 |
然后使用mimikatz.exe导出域管理员的TGT票据
1 | privilege::debug |
可以发现成功导出来自DM2012$
的TGT
得到TGT之后,我们用ptt将票据注入到当前会话后,可以用dcsync
导出域控中所有用户的hash,然后用krbtgt
用户的hash生成黄金票据
1 | kerberos::ptt [0;862bdd]-2-0-60a10000-DM2012$@krbtgt-TEST.LOCAL.kirbi |
得到krbtgt
用户的hash之后生成一张administrator的黄金票据
1 | kerberos::golden /user:Administrator /domain:test.local /sid:S-1-5-21-662417213-3583657854-423750704 /krbtgt:683545df56ea57b168d0ad090e209616 /ptt |
成功以administrator的身份访问域控
执行命令可以用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
是域内的另外一台主机,下面我们设置了服务用户qiyou
对DM08
的cifs
服务的委派
概述那里我们讲了在约束委派的情况下,服务用户只能获取某个用户(或主机)的服务的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
: 指定票据名称,不过这个参数没有生效,可以忽略
得到服务用户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服务
上面是知道服务用户明文的情况下,kekeo同样也支持使用NTLM Hash
在请求服务用户的TGT那步直接把/password
改成/NTLM
即可
已知我们服务账号qiyou
的NTLM hash
是b4f27a13d0f78d5ad83750095ef2d8ec
1 | tgt::ask /user:qiyou /domain:qiyou.com /NTLM:b4f27a13d0f78d5ad83750095ef2d8ec |
1 | kerberos::ptt TGS_Administrator@qiyou.com@QIYOU.COM_cifs~dm08.qiyou.com@QIYOU.COM.kirbi |
如果我们不知道服务用户的明文和NTLM Hash,但是我们有了服务用户登陆的主机权限(需要本地管理员权限),我们可以用mimikatz
直接从内存中把服务用户的TGT dump出来
1 | mimikatz.exe "privilege::debug" "sekurlsa::tickets /export" exit |
注:sekurlsa::tickets
是列出和导出所有会话的Kerberos
票据,sekurlsa::tickets
和kerberos::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 |
1 | kerberos::ptt TGS_Administrator@qiyou.com@QIYOU.COM_cifs~dm08.qiyou.com@QIYOU.COM.kirbi |
利用约束委派生成黄金票据
操作环境:
- 域:
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 | Import-Module ActiveDirectory |
我们可以用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
然后用mimikatz进行ptc
(pass the cache),将缓存注入当前会话中
klist查看缓存的票据
访问域控
执行命令的话我们可以用impacket
系列或者powershell
都可以
1 | wmiexec.exe -no-pass -k administrator@WIN-QFPHJSM1L7G.qiyou.com -dc-ip 192.168.141.145 |