Domain Trust
Trust Technologies: Domain and Forest Trusts | Microsoft Docs
How Domain and Forest Trusts Work | Microsoft Docs
A Guide to Attacking Domain Trusts | by Will Schroeder | Medium
From Domain Admin to Enterprise Admin - Red Teaming Experiments (ired.team)
Active Directory forest trusts part 1 - How does SID filtering work? - dirkjanm.io
Attack Trusts - Pentester’s Promiscuous Notebook (snovvcrash.rocks)
基础概念
单项信任:A信任B,B不信任A。B的用户可以访问A的资源,A的用户不能访问B的资源
双向信任:AB互相信任,AB用户可互相访问对方的资源。
传递信任:AB互相信任,BC互相信任,且都是可传递的信任,AC就互相信任
非传递信任:AB互相信任,BC互相信任,不是可传递的信任,AC就不互相信任
同一林中子域与父域默认建立的是双向传递信任。
外部信任不可传递
林信任可传递
域ADC
有两个子域。A.ADC
和B.ADC
。
A.ADC
和B.ADC
和父域ADC.COM
都是双向传递信任。所以A.ADC
和B.ADC
也是双向传递信任,他们的子域也依然可以双向传递信任。
BDC
与A.ADC
双向信任。不可传递。
CDC
与ADC
双向林信任。可传递。CDC域中用户可以访问ADC的所有资源包括子域,由于外部信任不可传递,CDC不可访问BDC的资源
微软官方文档的说明域和林信任如何工作 | 微软文档 (microsoft.com)
同一林的跨域Kerberos认证
- User1 使用来自 europe.tailspintoys.com 域的凭据登录到 Workstation1。作为此过程的一部分,身份验证域控制器向用户 1 颁发一个授予票证 (TGT)。User1 需要此票证才能对资源进行身份验证。然后,用户尝试访问位于 asia.tailspintoys.com 域中的FileServer1上的共享资源 (\fileserver1\share)。
- Workstation1 联系其域 (ChildDC1) 中域控制器上的 Kerberos 密钥分发中心 (KDC) 并请求 FileServer1 服务主体名称 (SPN) 的服务票证。
- ChildDC1 在其域数据库中找不到 SPN,并查询全局编录以查看林中是否有任何域包含此 SPN。全局编录将请求的信息发送回 ChildDC1。
- ChildDC1 将推荐发送到 Workstation1。
- Workstation1 与 ForestRootDC1(其父域)中的域控制器联系,以获取对 Child2 域中域控制器 (ChildDC2) 的引用。ForestRootDC1 将引用发送到Workstation1。
- Workstation1 与 ChildDC2 上的 KDC 联系,并为用户协商一张票证以获取对 FileServer1 的访问权限。
- Workstation1 获得服务票证后,会将票证发送到 FileServer1,FileServer1 读取用户的安全凭证并相应地构造访问令牌。
每个域都有自己的一组安全策略来管理对资源的访问。这些策略不会从一个域跨越到另一个域。
不同林中的跨域Kerberos认证
- User1 使用来自 europe.tailspintoys.com 域的凭据登录到 Workstation1。然后,用户尝试访问位于 usa.wingtiptoys.com 林中的 FileServer1 上的共享资源。
- Workstation1 联系其域 (ChildDC1) 中域控制器上的 Kerberos 密钥分发中心 (KDC) 并请求 FileServer1 SPN 的服务票证。
- ChildDC1 在其域数据库中找不到 SPN,并查询全局编录以查看 tailspintoys.com 林中的任何域是否包含此 SPN。因为全局编录仅限于其自己的林,所以找不到 SPN。然后,全局编录检查其数据库中有关与其林建立的任何林信任的信息,如果找到,它将林信任受信任域对象 (TDO) 中列出的名称后缀与目标 SPN 的后缀进行比较以查找一场比赛。找到匹配项后,全局编录会向 ChildDC1 提供路由提示。路由提示有助于将身份验证请求定向到目标林,并且仅在所有传统身份验证通道(本地域控制器和全局编录)都无法找到 SPN 时使用。
- ChildDC1 将其父域的引用发送回 Workstation1。
- Workstation1 与 ForestRootDC1(其父域)中的域控制器联系,以获取到 wingtiptoys.com 林的林根域中的域控制器 (ForestRootDC2) 的引用。
- Workstation1 联系wingtiptoys.com 森林中的ForestRootDC2 以获取所请求服务的服务票证。
- ForestRootDC2 联系其全局编录以查找 SPN,全局编录找到 SPN 的匹配项并将其发送回 ForestRootDC2。
- ForestRootDC2 然后将 usa.wingtiptoys.com 的推荐发送回 Workstation1。
- Workstation1 联系 ChildDC2 上的 KDC 并协商 User1 的票证以获得对 FileServer1 的访问权限。
- Workstation1 获得服务票证后,会将服务票证发送到 FileServer1,FileServer1 读取 User1 的安全凭证并相应地构造访问令牌。
Power View
TrustType
信任类型
- DOWNLEVEL (0x00000001) — 未运行 Active Directory 的受信任的 Windows 域。 在PowerView 中以WINDOWS_NON_ACTIVE_DIRECTORY的形式输出。
- UPLEVEL (0x00000002) — 一个运行 Active Directory 的受信任的 Windows 域。在 PowerView 中输出为WINDOWS_ACTIVE_DIRECTORY 。
- MIT (0x00000003) — 运行非 Windows (*nix)、符合 RFC4120 的 Kerberos 分发的受信任域。由于 MIT 发布 RFC4120,这被标记为 MIT。
TrustAttributes
信任属性
- NON_TRANSITIVE (0x00000001) — 不能传递使用信任。也就是说,如果 DomainA 信任 DomainB 而 DomainB 信任 DomainC,那么 DomainA 不会自动信任 DomainC。此外,如果信任是不可传递的,那么您将无法从非传递点的链上的信任中查询任何 Active Directory 信息。外部信任是隐含的不可传递的。
- UPLEVEL_ONLY (0x00000002) — 只有 Windows 2000 操作系统和更新的客户端可以使用信任。
- QUARANTING_DOMAIN (0x00000004) — SID 过滤已启用(稍后会详细介绍)。为简单起见,使用 PowerView输出为FILTER_SIDS 。
- FOREST_TRANSITIVE (0x00000008) — 至少运行域功能级别 2003 或更高级别的两个域林的根之间的跨林信任。
- CROSS_ORGANIZATION (0x00000010) — 信任不属于组织的域或林,它添加了 OTHER_ORGANIZATION SID。这有点奇怪。我不记得在现场遇到过这个标志,但根据这篇文章,这意味着启用了选择性身份验证安全保护。有关更多信息,请查看此 MSDN 文档。
- WITHIN_FOREST (0x00000020) — 受信任域在同一个林中,表示父->子或交叉链接关系
- TREAT_AS_EXTERNAL (0x00000040) — 出于信任边界的目的,信任将被视为外部信任。根据文档,“ 如果设置了此位,则出于 SID 过滤的目的,对域的跨林信任将被视为外部信任。 跨林信任的过滤比外部信任更严格 。此属性将那些跨林信任放松为等同于外部信任。 ” 这听起来很诱人,我不能 100% 确定此声明的安全含义¯_(ツ)_/¯ 但如果有任何新信息出现,我会更新这篇文章。
- USES_RC4_ENCRYPTION (0x00000080) — 如果 TrustType 是 MIT,则指定支持 RC4 密钥的信任。
- USES_AES_KEYS (0x00000100) — 未在链接的 Microsoft 文档中列出,但根据我在网上找到的一些文档,它指定 AES 密钥用于加密 KRB TGT。
- CROSS_ORGANIZATION_NO_TGT_DELEGATION (0x00000200) — “如果设置了此位,则不得信任在此信任下授予的票证进行委托。” 这在[MS-KILE] 3.3.5.7.5(跨域信任和推荐)中有更多描述。
- PIM_TRUST (0x00000400) —“如果设置了此位和 TATE(视为外部)位,则出于 SID 过滤的目的,对域的跨林信任将被视为特权身份管理信任。” 根据[MS-PAC] 4.1.2.2(SID 过滤和声明转换),“域可以由林外的域进行外部管理。信任域允许其林本地的 SID 通过 PrivilegedIdentityManagement 信任。” 虽然我在现场没有看到这个,而且它只支持域功能级别 2012R2 及更高版本,但它也值得进一步调查:)
TrustDirection
信任方向:
Bidirectional: 双向
Outbound:对外信任,外部域可访问本域
inbound:对内信任 ,本域可访问外部域
4张票据
制作keytab
wireshark可以导入keytab文件来解密Kerberos认证中加密的数据。keytab就类似一个密码表。因为PAC是用krbtgt的hash加密,所以我们有了krbtgt的hash,制作keytab,导入wireshark就可以看见PAC中的每个结构了。
https://mp.weixin.qq.com/s/eTiQRoEh1DvNGEuPErYsAw。这篇文章讲了通过ntds.dit和system.hive来制作keytab,经过我的测试有不少坑。不同版本的Windows Server,ntds.dit的结构不一样。如果你的域控是Windows server 2008。可以试试这种方法,我搞了大半天。最终也没成功。
我更推荐dirkjanm的脚本,dirkjanm/forest-trust-tools: Proof-of-concept tools for my AD Forest trust research (github.com)
我们可以使用secretsdump或者mimikatz挨个导出我们需要的在用户hash。
然后添加到keytab.py中112行。
运行keytab.py生成keytab文件。导入wireshark即可解密Kerberos认证中的各个结构。
认证流程
在B.ADC
运行Get-DomainComputer -domain a.adc.com
查询A.ADC中的计算机
klist查看当前票据。
IIS01是A.ADC域控,IIS02是B.ADC 域控,DC01是父域ADC域控
一共4个票据。首先第三个票据(#2
)是B.ADC域管的TGT。
第二个票据:
客户端: Administrator @ B.ADC.COM
服务器: krbtgt/ADC.COM @ B.ADC.COM
调用的KDC是B.ADC的域控。
也就是说请求者先拿着自己的TGT(第三张票据)去找自己的域控(B.ADC)请求A.ADC的服务(这里是ldap/IIS01.A.adc.com
)。域控发现这个服务是另一个子域的。就用自己与父域的信任密钥加密TGT,返回给我们,让我们去找父域ADC。返回的这张票据就是第二张票据
第一张票据:
客户端: Administrator @ B.ADC.COM
服务器: krbtgt/A.ADC.COM @ ADC.COM
调用的 KDC: DC01.adc.com
拿着第二张票据去父域请求A.ADC的跨域TGT。这个也就是我们抓到的第一个TGS-REQ。
TGS-REP返回的就是第一张票据
第四张票据
客户端: Administrator @ B.ADC.COM
服务器: ldap/IIS01.A.adc.com/A.adc.com @ A.ADC.COM
调用的 KDC: IIS01.A.adc.com
拿着父域给的跨域TGT,去A.ADC请求对应服务的ST。
返回的就是第四张跨域的服务票据
那么这里就有一个问题。父子之间的跨域的TGT怎么验证的,还是用spn指定的服务的hash加密的吗?
信任密钥
我们使用secretsdump.py把导出三个域控的hash,对比发现下面几个hash
|
|
可以看到父域和子域之间存在一个相同的hash。我们把这些hash加到我们制作的keytab中。导入wires hark。成功解密,可以看到加密的hash是b88a3a068365e1ecdddd7348f195444d
同样的,父域给我们的票据是使用b54f5c768bff145ca1c094a6d9751f09加密
这两个hash就是信任密钥(trust key)。
这样我们再来看微软的这张同一林下的跨域Kerberos认证的图。是不是一目了然了呢。
SID筛选
林信任和同一林下的父子信任默认sid筛选不启用。但林信任确实过滤一些sid
|
|
创建一个外部信任域,sid筛选默认启用,信任关系不可传递
SIDHistory
根据微软的解释,SID History 是一个支持迁移方案的属性,每个用户帐户都有一个关联的安全标识符 (SID),用于跟踪安全主体和帐户在连接到资源时的访问权限。SID 历史记录允许将另一个帐户的访问有效地克隆到另一个帐户,并且对于确保用户在从一个域移动(迁移)到另一个域时保留访问权限非常有用。
而一个账户可以在SID-History Active Directory 属性中保存额外的 SID ,从而允许域之间进行可相互操作的帐户迁移(例如,SID-History 中的所有值都包含在访问令牌中)。
为了达到SID History攻击的目的,我们的将使用域管理员权限,将获取到的有权限的SID值插入到SID历史记录中,以实现模拟任意用户/组(例如Enterprise Admins)的权限,达到跨域提权目的。
过滤规则
[MS-PAC]:SID 过滤和声明转换 | 微软文档 (microsoft.com)
同一个林,不过滤sid。
林信任:默认启用sid筛选;过滤掉所有不存在发起者所在的林中的sid。也就是说林A的某个用户对林B的资源发起访问,林B返回给该用户的服务票据的PAC中extra sids只包含林A存在的组的sid。林B中的sid会被删除。
Dirk-jan在它的文章中提到的启用sidhistory时的sid筛选机制,但我的环境sidhistory一直启动不成功。
Active Directory forest trusts part 1 - How does SID filtering work? - dirkjanm.io
netdom有个enablesidhistory选项,再林B开启后,就不会过滤来自林A请求的sid。
1
netdom trust /d:forest-a.local forest-b.local /enablesidhistory:yes
然后两个林之间的信任关系就是
TREAT_AS_EXTERNAL
。这时候林信任就被视为外部信任。不会过滤掉本域的sid。
但是会删除Domain Admins/Enterprise Admins/Account Operators 组。
Domain Admins 组未添加到
ResourceGroup
PAC 的一部分,即使组 3101 是该组的直接成员。这是因为 Domain Admins 组是一个全局组,而PAC 中只添加了域本地组。如果跨森林信任启用 SID 历史记录,您可以 欺骗任何 RID >1000的组! 在大多数环境中,这将允许攻击者破坏森林。例如,在许多设置中允许将权限升级到 DA的 Exchange 安全组都具有大于 1000 的 RID。此外,许多组织将为工作站管理员或帮助台提供自定义组,这些组在工作站或服务器上被赋予本地管理员权限。例如,我刚刚为该
IT-Admins
组(具有 RID 3101,这是我们的黄金票据的一部分)授予了forest-b-server
机器上的管理员权限。
一些不会被过滤的sid:
S-1-5-9 Enterprise Domain Controllers
S-1-4 非唯一权威
S-1-5-15 这个组织
S-1-5-21-0-0-0-496 复合认证
S-1-5-21-0-0-0-497 索赔有效
S-1-5-1000- 其他组织
S-1-5-R-R>1000 可扩展S-1-10护照管理局
跨域
我们拿到了子域的域管权限。想要进一步拿下父域。但子域的域管并不是父域的域管。怎么办呢?
跨域金票
在子域控上导出krbtgt的hash,制作金票。也可以用信任密钥加密。其实这俩一样,只不过换了个hash加密而已。
|
|
非约束委派
学非约束委派时就提到过。域控默认都是非约束委派的机器,通过RPC强制父域控返回身份认证,在子域控上哪到父域机器账户的TGT。
这里需要注意的是,这种手法同样适用于林信任,但在外部信任不可用。如果开启了sid筛选,也抓不到TGT
|
|
信任账户攻击
很好理解的攻击方式。一张图就可以解决。
B单向信任A,A可以访问B的资源,B访问不了A的资源。
但我们知道,两个域建立信任后再每一个域都会有一个信任账户,这两账户的RC4hash是相同的。
而这个信任账户属于domain users组。那我们不就能获取另一个域的一个普通用户的凭据,即使他不信任本域。
|
|
有了凭据,那我们就可以对一个不信任我们的域进行
- AD枚举/攻击路径发现
- 网络共享枚举
- 创建 DNS 记录
- 将计算机加入域
- 利用证书模板
- kerberoasting
- 以及更多…
黄金GMSA
这个就没怎怎么看了,有兴趣自己学把,作者还提到其他几种方法,具体看文章