在梳理完单域的攻击手法后 于是就打算重新开这一篇文章来写这个关于域森林的文章

参考文章

https://www.geekby.site/2020/05/%E5%9F%BA%E4%BA%8E%E5%9F%9F%E4%BF%A1%E4%BB%BB%E5%85%B3%E7%B3%BB%E7%9A%84%E5%9F%9F%E6%94%BB%E5%87%BB/#%E5%9F%9F%E4%BF%A1%E4%BB%BB

https://www.boundaryx.com/info/2145.html

https://www.t00ls.com/articles-69791.html

前言

在实战中单域出现的概率远大于域森林出现的概率,但在一些大型公司或企业可能会见到。本篇主要是针对域控的在复杂内网环境中的攻击方式来进行梳理并且介绍了域信任、利用域信任进行横向移动以及一些在信任利用中涉及到的知识和概念。

(环境就不自己搭建了 图片就照搬上面参考文章的了)

域信任

域环境分单域、父子域、域树和域森林,在实战中单域是最常见的,也是相对最简单的,但是想要在域森林中进行横向移动就必须要了解单域中的利用方式和相关原理。接下来说父子域,父子域就是一个域(父域)下分出了很多个子域,可能子域下还有子域,当这种关系复杂化之后就形成了域树,当域树多了之后就形成了域森林。

域信任关系可以是单向\双向信任可传递\不可传递信任内部\外部信任跨域链接信任(cross link trust)等类型。例如,2 个域之间有单向可传递的外部信任关系。同一个森林(Forest)内部的域信任关系,一般隐含为双向可传递的内部信任关系

image-20240528205053959

跨域链接信任(cross link),指的是在同一个森林的两个子域间建立直接的信任关系。因为在同一个森林中,域的组织关系是树状结构,从一个子域到另外一个域,需要从树枝的子域顺寻到根域(Forest Root),然后从根域继续顺寻到另外一个子域,而跨域链接相当于 在 2 个子域之间之间建立了一个快捷方式的信任关系,以减少认证和授权的时间和步骤。

内部信任指的是森林内部域之间的信任关系。相应地,外部信任(External Domain Trust)指的是域和所在森林之外的域之间的信任关系。

父子信任关系是最常见的域信任关系,在同一个森林内部,加入一个新域时,最常见的是子域模式(Parent- Child),或者是树根模式(Tree-Root),这两种模式分别会建立父子信任\树根信任关系,都是双向可传递的内部信任关系。

image-20240528205359797

根据这个图来看

  • adsec.comlab.adsec.com是父子域的关系
  • adsec.comres.com是树根域的关系
  • adsec.comtestlab.com是林域的关系 (这两者就是森林外部的相互信任了 )

跨域认证和资源访问授权

当 2 个域之间建立域信任关系时,会建立共享的域间密钥(Inter-Realm Key,简写为IRKey),其作用相当于 Krbtgt,只不过 IRKey 用于相互信任的 2 个域之间的认 证,而 Krbtgt 用于同一个域服务器的 AC 和 KDC 之间的认证。这个IRKey其实就是信任用户的ntlm值,而且在双向信任的情况下,ntlm的值也是不同的(这也说明了双向信任其实就是两个单向信任的叠加)

  • 当设置域B 到域A 的单向信任时(B信任A),将在域A中创建一个名为B$ 的信任帐户。当域 A 中的用户请求域 B 中的服务票证时,此信任帐户的Hash 用于加密域间 TGT。

信任域之间的认证授权过程,与同一个域中的认证授权大抵相似,但仍然有不少区别。

image-20240528211221175

  1. Jack 向 DC1 发起认证请求,数据由 Jack 的口令 NTLM 值加密;
  2. DC1 使用 Jack 的口令 NTLM 值验证收到的认证请求,返回一个通过认证的 TGT 票据给 Jack;
  3. Jack 使用 TGT 票据,向 DC1 发起授权请求,发起 请求访问 DC2 中文件服务的 TGS_REQ;
  4. DC1 检查到文件服务在 DC2 中,返回一个可转投的 TGT(Referral TGT),指明需转投到 DC2,使用 IRKey 加密可转投 TGT 中的认证信息;
  5. Jack 收到可转投的 TGT 后,根据提示信息,使用转投 TGT,发起访问 DC2 中文件服务的请求 TGS_REQ;
  6. DC2 收到请求后,使用 IRKey 验证可转投 TGT 中的认证信息,返回一个允许访问文件服务的 TGS 票据,票据中部分信息使用运行文件服务的服务账号的口令 NTLM 值加密;
  7. Jack 使用收到的 TGS 票据访问 DC2 中的文件服务;
  8. 文件服务的服务账号使用口令 NTLM 值校验 TGS

(这里所说的IRKey其实就是信任用户的ntlm值 这个东西很重要)

当 2 个域之间建立信任关系时,会在全局域数据库中存档对方的 SPN、DNS 等信息,方便访问时进行查询。例如,上图中,DC1 会存档 DC2 中所有的服务 SPN、DNS 等信息。

如果 Jack 请求访问的服务在 DC1 的全局数据库中,则会返回转投 TGT,如果不在,如果 DC1 有父域,则 DC1 会向父域请求直至森林的根域服务器,如果 DC1 本身是根服务器(本例中 DC1 是根域服务器),则直接告诉 Jack,请求访问的服务不存在。

一个森林只有一个全局数据库。

SIDHistory 版跨域黄金票据

SIDHistory

每个用户帐号都有一个对应的安全标识符(Security Identifiers,SID),SID用于跟踪主体在访问资源时的权限。如果存在两个同样SID的用户,这两个帐户将被鉴别为同一个帐户,原理上如果帐户无限制增加的时候,会产生同样的SID,在通常的情况下SID是唯一的,他由计算机名、当前时间、当前用户态线程的CPU耗费时间的总和三个参数决定以保证它的唯一性。
为了支持AD牵移,微软设计了SID History属性,SID History允许另一个帐户的访问被有效的克隆到另一个帐户。

一个完整的SID包括:

  • 用户和组的安全描述
  • 48-bit的ID authority
  • 修订版本
  • 可变的验证值Variable sub-authority values

例:S-1-5-21-310440588-250036847-580389505-500
第一项S表示该字符串是SID;第二项是SID的版本号,对于2000来说,这个就是1;然后是标志符的颁发机构(identifier authority),对于2000内的帐户,颁发机构就是NT,值是5。然后表示一系列的子颁发机构,前面几项是标志域的,最后一个标志着域内的帐户和组。
可以注意到最后一个标志位为500,这个500是相对标识符(Relative Identifer, RID),账户的RID值是固定的。一般克隆用户原理就是篡改其他用户的RID值使系统认为对应用户是管理员。
常见的RID:500-管理员 519-EA 501-Guest

SIDHistory(在 PAC 结构中为 ExtraSids 字段)是为了方便用户在域之间的迁移。当一个用户迁移到新的域后,原来的 SID 以及所在组的一些 SID,都可被加入到新域中新用户的 SIDHistory 属性。当这个新的用户访问某个资源时,根据 SID 或者 SIDHistory 在资源 ACL 中的匹配性来判断是拒绝或者允许访问。因此 SIDHistory 相当于多了一个或者多个组属性,权限得到了扩张

制作跨域黄金票据SIDHistory

在一个域中,一旦我们获取 Krbtgt 的 NTLM 值,则可以构造黄金票据,伪造成域内任意用户,包括管理员,获取对域的完全访问控制权限。但是在同一个森林的不同域中,黄金票据不再有效(是因为每个域的Krbtgt的ntlm值不同)。

回顾一下黄金票据的几大要素,即域名、域的SID(Security Identifier)、本域 Krbtgt 用户口令 NTLM 值、想伪造票据的用户 RID(Relative Identifier,在无特别指明情况下,Mimikatz 工具会设置 RID 为域管理员的 RID)。不同的域有不同的 Krbtgt,导致黄金票据在不同的域之间失效。

如果一个用户的 SIDHistory 属性被设置为高权限组或者用户的 ID,则该用户也具备等同于高权限组或者用户的权限。如果我们伪造的黄金票据中加入目标域的域管理员组的 SID,则可以获取目标域的域管理员权限,黄金票据SIDHistory 的结合,可实现跨域黄金票据。

由于每个域的 SID 都不同,叠加 SIDHistory 的黄金票据不具备通用性。根据微软的描述,在同一个域森林内部,企业管理组 EA(Enterprise Administrators) 会自动被森林内部所有域加入到本域的域管理员组,且 EA 只存在于根域中,所以企业管理组 EASID 固定为根域的 SID 加上固定的 RID519

因此,如果将使用企业管理组 EASID 设置 SIDHistory 属性,和黄金票据结合,则在只获取任意一个域 krbtgt 账号 NTLM 值的前提下,可实现森林内部所有域的跨域黄金票据,这种票据可简称为 SIDHistory 版黄金票据。

当然也可以添加森林内某个指定域的管理员组 SIDSIDHistory,但是这样的黄金票据只对该指定域有效,对其他域无效。不如使用企业管理员 SID 的票据那样有通用性。

(简单点说就是伪造当前域管 然后将域管的sidhistory给改了)

1
mimikatz.exe "kerberos::golden /user:anyusername sids:[EA组的sid] /sid:[lab.adsec.com域的sid] /domain:lab.adsec.com /krbtgt:16ed27ee7848756cfa96b33c25e3ad3d /ptt" exit

image-20240529001535543

仍然在 lab.adsec.com 域中构造黄金票据,但添加了 SIDS 参数,使用根域的企业管理员 SID 作为参数值,即 SIDHistory 版黄金票据,对 lab.adsec.comadsec.com 域均有效。

这里需要注意的是,实现 SIDHistory 版黄金票据的基础是森林内信任关系,因为如果不是森林内信任关系,则 SIDHistory 会被微软的 SID Filter 规则过滤掉,从而失效,但森林内部不会有 SID Filter 规则。这也是为什么说是森林而非域才是安全边界。

(这里所说的SID Filter过滤规则其实是在林信任的时候才会生效 在森林内的话是不会生效的)

IRKey 版跨域黄金票据

当 2 个域之间建立域信任关系时,需要建立共享的域间密钥(Inter-Realm Key,简写为 IRKey),其作用相当于 Krbtgt,只不过是用于相互信任的 2 个域之间,而 Krbtgt 用于同一个域服务器的 AC 和 KDC 之间。

只要获取森林内部任意域的 krbtgt 账号的 NTLM 值,则通过 SIDHistory 版黄金票据,即可获取全森林所有域的控制权。因此为了防御,必须 2 次修改森林内部所有域的 krbtgt 账号的 NTLM 值。

在多域环境中,IRKey 和主机账号类似,系统默认每 30 天自动修改一次 NTLM。所以即使 2 次修改森林内所有域的 krbtgt 账号的 NTLMIRKeyNTLM 大概率仍然没有发生改变(小概率是 krbtgtNTLM 修改正好碰上了 IRKey 的修改周期)。

类似白银票据,可以使用 IRKey 伪造域间可转投票据(Inter-Realm Referral TGT),获取目标域的域管理员权限,再结合上一节的 SIDHistory 版黄金票据,再次获取整个森林的控制权。这里需要注意的是 SID 为目标域的 SID

在域中,大部分带 ‘$’ 符号的账号为 Computer 账号,但是 User 组带 ‘$’ 符号的账号为信任账号,可以通过域服务器自带的 Powershell 命令 Get-ADUser 获取所有 带 ‘$’ 符号的 User 账号,下图中 ADSEC$ 账号为信任账号,隶属于 Users 组。(当设置域B 到域A 的单向信任时(B信任A),将在域A中创建一个名为B$ 的信任帐户。当域 A 中的用户请求域 B 中的服务票证时,此信任帐户的Hash 用于加密域间 TGT。)

https://geekby.oss-cn-beijing.aliyuncs.com/MarkDown/20200504112640.png-water_print

有 2 种方式可以获取信任账号的 NTLM 值。

Dcsync 获取信任账号的 NTLM 值

下图采用 Dcsync 方式,获取 lab.adsec.com 域中信任账号 adsec$NTLM 值,结果表明该账号的类型为 TRUST_ACCOUNT

https://geekby.oss-cn-beijing.aliyuncs.com/MarkDown/20200504112712.png-water_print

lsadum 获取信任账号的 NTLM 值

采用 lsadump::trust /patch方式。从下图中可看到有 [IN] LAB.ADSEC.COM -> ADSEC.COM[OUT] ADSEC.COM -> LAB.ADSEC.COM 两种不同的 NTLM 值,分别是往外到其他域和往内到本域访问时用到的值。因为双向信任关系其实是 2 个单向信任关系的叠加,所以会有 2 个密钥。这里我们要从本域构造 IRKey 版黄金票据访问森林内部其他域,所以使用 IN 这个 NTLM 值。

https://geekby.oss-cn-beijing.aliyuncs.com/MarkDown/20200504113851.png-water_print

由于 IRKey 存在于森林内部的信任域之间,也存在于森林外部的森林之间,均可用于转投认证。在 SIDHistory 版黄金票据中,由于 SID Filter 规则,在森林之间不能使用,但是 IRKey 版不涉及这个安全过滤规则,仍然有效IRKey 版黄金票据可以分作森林内部的、森林外部的 2 种,操作方法类似,这里我们着重介绍森林内部的 IRKey 版黄金票据。

https://geekby.oss-cn-beijing.aliyuncs.com/MarkDown/20200504114210.png-water_print

(这里面的krbtgt是信任用户的ntlm值 这里指定的service和信任域的原因是为了伪造tgt)

/service

  • 指定服务为krbtgt,这意味着生成的票据将由信任域的krbtgt服务签名,用于请求信任域的TGT(Ticket Granting Ticket)。

/target:

  • 指定目标信任域,表示生成的票据将用于这个信任域,使攻击者能够在该域中操作。

域间转投票据的认证,依靠 IRKey 加密。在我们已知 IRKey 的前提下,可以伪造持有该 IRKey 的信任域的任意用户。测试中,我们构造一个票据,告诉 adsec.com 域,转投认证的用户为 administrator,而且 SIDHistory 为根域的企业管理员。

构造成功后,具备 adsec.com 的管理员权限,但是不能高权限访问 lab.adsec.com,因为构造的票据是到 adsec.com 域的管理员票据。在获取 adsec.com 域的高权限后,可以获取该域的 krbtgt 账号的 NTLM 值,在此基础上,继续构造 SIDHistory 版黄金票据,从而可以获取整个森林的控制权。

绕过SID过滤

外部信任就是指的是两个域林之间的域的信任

林信任就是指的是两个域林之间根域的信任

(两者相较而言 外部信任的限制更少)

外部信任和林信任中存在SID过滤机制,所以无法利用SID History获取权限,SID过滤机制在林内部默认被禁用。但是可以通过netdom命令手动开启即允许跨域林信任的SID-history
SID过滤机制是如何工作的,以及SID过滤机制过滤了哪些SID
在域林A和外部域林B中,存在SID过滤,比如域林A中的用户请求林B中的资源,会过滤SID-history属性值(过滤不属于林A中的用户SID,因为在跨域的金票制作中,我们会将根域的企业管理员用户的SID放进ExtraSids中,但是在这种过滤下,这种方法不在有效),但是试想一下,如果林A中的用户在林B中被赋予了特殊权限,我们还是可以通过这种方法进行利用的,或者通过netdom(偷图)

image-20240530154700034

img

ldap导出 TrustAttributes结构,可以看到TREAT_AS_EXTERNAL标志
img
微软关于这个标志位的说明如下

img

如果设置了此位,则出于 SID 过滤的目的,对域的跨林信任将被视为外部信任。跨林信任比外部信任过滤得更严格。此属性将那些跨林信任放宽为等同于外部信任。有关如何过滤每种信任类型的更多信息,请参阅 [MS-PAC] 第 4.1.2.2 节。
在林A和林B中SID过滤机制会过滤林A中的SID,我们分析TREAT_AS_EXTERNAL这个标志了解到如果设置了此位(netdom命令),则出于 SID 过滤的目的,对域的跨林信任将被视为外部信任~,也就是说减小了我们的限制,此时我们依然可以将林B中的用户SID放进ExtraSids中,但是仍然会过滤一些用户的sid如DA/EA/Account Operators组的用户,总结的来说就是虽然减小了限制,但是只能通过SID-history攻击sid为1000以上的用户(如果高权限组自定义为1000以上了也是可以利用的,比如exchange相关的一些组)。
img

利用SQLServer链接

这种利用方式的原理和SID没有任何关系,只不过前面几种方式都限制在了SID过滤。SQLServer的信任连接(Linked Servers)是跨林的所以我们也可以利用这点来进横向。下面是微软关于(Linked Servers)的解释,我们只需要大致了解它的使用场景并且知道Linked Servers是可以跨域的就可以了。使用SQL Server时,可能会这种情况,需要从一个SQL Server服务器A中,查询另一个SQL Server服务器B中的表,然后将SQL Server服务器A中的表和SQL Server服务器B中的表进行JOIN,像类似这种跨SQL Server服务器的SQL语句操作,我们就可以通过在SQL Server中建立Linked Servers来实现。利用过程就是在林A的SQL上发现了林B的信任链接,那就代表可以使用这个链接,此后就可以在林B的SQL上执行SQL语句(MSSQL的利用方式了,到了这里还可以通过烂番茄实现本地提权)
img
创建漏洞环境
img

img

img
结果类似下面这样
img

利用GPO

GPO是Group Policy Object的缩写,译为组策略对象,作用在于控制用户可以干什么不可以干什么,比如密码必须要符合要求,特定文件夹访问权,安装附加功能或者以管理身份运行某些软件等等,这一套策略就叫组策略对象。GPO支持任务计划是从windows2008开始。如批量下发GPO中利用的就是通过GPO下发任务计划,但域内组策略更新的时间为90分钟,需要通过命令(gpupdate)来强制进行触发,因为GPO可以实现跨域同步,所以可以用来进行跨域攻击。

img

在子域域控上以system(否则会报错)可以链接GPO到AD 复制站点,包括父域DC所在的站点

image-20240530161315733

img
img
将fire.goal.lab的名为pentest的GPO链接到父域goal.lab

img

链接到父域的时候 就可以看到这个组策略了 然后我们添加定时任务

image-20240530161431138

这个是时候在父域是看不到这个组策略的 因为组策略的更新时间为90分钟 我们得在子域上执行gpupdate 强制更新

image-20240530161621140

强制更新之后 组策略就会触发

利用委派

可以看到m03配置了非约束委派,其实域控默认都是配置了非约束委派的,也就是说如果父域访问m03就会留下父域的TGT,假设我们已经拿下了子域fire.goal.lab的域控m03
img
在子域的域控上进行监听
img
接下来开始强制认证
开启了webclient(不开也可以触发成功),可以用PetitPotam强制进行认证,我尝试了以下几个trigger,但只有PetitPotam成功进行了强制触发,并且在低版本系统中PetitPotam是可以进行性匿名强制触发的。
img
使用不同的trigger强制触发认证
img
img
img
收到凭据
img
处理后dcsync拿到企业管理员hash
img

img
同样可以登录子域域控
img

这个强制认证的打ntlm中继的攻击可以看https://forum.butian.net/share/1944

总结

这里只是记录了一部分的攻击方法 并且这个攻击也适用于林域内 因为为了安全 可能林内也会开启这个sid filter预防sidhistory攻击