Site Unseen: Enumerating and Attacking Active Directory Sites
Active Directory站点是一项用于优化AD内部环境网络性能和带宽使用的功能,通常由跨多个国家或地区的大型组织实施。相较于其他基于ACL的攻击向量,AD站点并未受到Active Directory攻击研究社区的过多关注。本文旨在证明,不仅存在针对Active Directory站点的攻击向量,而且这些向量可能导致严重的权限提升场景乃至域(或多个域)的完全沦陷。
我们将描述向BloodHound项目提交的一个Pull Request,该请求用于枚举站点ACL攻击路径,以及如何利用我们最近发布的与GPO(组策略对象)攻击向量相关的工具来高效利用这些路径。所述攻击场景可能允许攻击者提升权限,并在Active Directory林内横向移动。
目录
- 引言
-
- Active Directory站点基础
-
- 为何要关注?
-
- 站点枚举:将Active Directory站点集成到BloodHound
-
- 利用站点“GPO风格”进行特权提升和域(或多个域)沦陷
-
- 滥用Active Directory站点进行林内横向移动
- 结论
引言
站点与Active Directory环境的物理表示相关联,而非与其身份层面相关。因此,研究社区可能认为从安全角度来看,它们不太有趣,并将其降级为一种与情境、生产/功能相关、不提供真正攻击机会的特性。
虽然并非所有组织都依赖Active Directory站点进行网络分发,但本文旨在证明,当站点存在时,基于站点的ACL攻击向量可能非常强大,并导致一个或多个域的沦陷。因此,站点应被视为关键基础设施组件,值得集成到诸如BloodHound之类的流行攻击路径可视化工具中。
本文还将描述一种有文档记载但鲜为人知的依赖站点的利用技术。利用此类向量可能允许攻击者在林中横向移动,而不受任何SID过滤配置的阻碍。我们将展示如何利用我们几个月前发布的GPO攻击工具集来具体利用该技术。
1. Active Directory站点基础
本节将阐明什么是Active Directory站点及其在Active Directory中的具体实现方式。如果您熟悉这些概念,可以跳过。
如上文简要提及,Active Directory站点关乎网络效率和带宽使用优化。站点是分配了高连接性子网的对象——这些子网中的所有对象(计算机以及连接到这些计算机的用户)都是站点的一部分。站点将分组子网中的资源关联起来,主要有两个目的:
-
复制。在Active Directory中,当对特定域控制器应用更改时,其他域控制器(同一域的用于域数据,林范围的用于架构和配置分区)需要复制该更改。Active Directory复制有两种类型:站点内复制和站点间复制。由于单个站点内的资源可以非常快速地通信,站点内复制默认以相当规律的间隔(每5分钟)进行。由于站点间复制对网络要求更高,带宽会被压缩,并且Active Directory允许管理员通过站点链接定义复制设置(默认为180分钟)。
-
身份验证。一个站点应分配一个或多个服务器,这些服务器无非是负责该站点的域控制器。属于站点的对象将优先考虑配置为站点服务器的域控制器。
默认情况下,林中只存在一个站点(名为Default-First-Site-Name)。在创建另一个站点之前,所有对象都自动分配到此站点,所有复制都在站点内进行。如果管理员希望添加另一个站点,则必须配置它并为其分配站点链接。站点链接允许在两个站点之间进行复制,并定义复制设置(例如,复制计划)。默认情况下,站点链接是可传递的,这意味着如果站点A链接到站点B,站点A链接到站点C,那么站点B通过传递性链接到站点C。这是通过站点桥完成的,如果站点链接的可传递属性未被管理员明确禁用,则会自动创建站点桥。
请注意,由于配置错误,完全可能存在彼此未链接的孤立站点。这显然可能导致环境中的严重问题,因为复制过程不会发生,导致域控制器数据之间的差异。
最后,需要重点说明的是,Active Directory站点与域划分没有任何关联。一个站点可能包含来自林中不同、独立域的客户端和域控制器。这就是为什么Active Directory域处理内部网络资源的逻辑分段,而站点构成了环境的物理、地理表示。
更具体地说,站点、子网和站点链接都是位于配置命名上下文中的LDAP对象,该命名上下文在林范围内复制——在CN=Sites,CN=Configuration,DC=corp,DC=com容器中(更多细节见第5部分)。
可以从Active Directory图形界面“站点和服务”管理站点。
2. 为何要关注?
既然Active Directory站点背后的概念更清晰了,为什么从攻击角度来看,我们需要关注它?特别是如果站点仅用于网络效率目的而分组对象?
事实证明,可以向Active Directory站点分配组策略对象。站点对象具有gPLink属性,描述了与站点关联的所有对象将应用的GPO。这是有道理的,因为某些特定位置的配置可能需要通过站点应用(防火墙规则、浏览器收藏夹、视觉标识等)。但这也为基于GPO的攻击向量提供了有趣的机会。
事实上,如果攻击者能够以某种方式将恶意GPO链接到站点,或者毒化已链接到站点的GPO,他们就可以危害站点的所有对象,包括充当站点服务器的域控制器。
几种基于ACL的攻击路径可能促成这种场景,这就是为什么Active Directory站点ACL应被视为有趣的——甚至在枚举Active Directory环境时应被视为关键的。
3. 站点枚举:将Active Directory站点集成到BloodHound
我们观察到,与站点在Active Directory攻击研究中不受欢迎的情况一致,目前似乎没有工具收集和枚举站点ACL以突出潜在的高影响攻击路径。更具体地说,用于Active Directory攻击路径枚举和可视化的首选工具BloodHound尚未包含此类数据。
尽管影响站点的危险ACL可能不像与更常见对象类型相关的其他错误配置那样频繁,但由于其潜在的高影响,当它们存在时,捕获它们非常重要。这就是我们刚刚向SharpHound、SharpHoundCommon库以及BloodHound项目提交Pull Request的原因。这些Pull Request实现了以下功能:
- 从Active Directory环境枚举数据时,收集有关站点、站点服务器和站点子网的数据。
- 通过将每个站点与相关的服务器和子网对象关联起来,在BloodHound界面中表示站点数据。
- 将站点添加到默认高价值目标中,因为控制站点可能导致与站点关联的所有对象(包括至少一个充当站点服务器的域控制器)的潜在沦陷。
- 创建针对站点对象的控制边(GenericAll, GenericWrite, WriteGPLink),因为这些权限是可利用的(更多信息见下一部分)。
- 集成从组策略对象到站点的GPLink边,以枚举GPO何时影响站点(使得控制此类GPO更加有趣)。
4. 利用站点“GPO风格”进行特权提升和域(或多个域)沦陷
既然枚举部分已涵盖,下一节将具体描述可能影响站点对象的不同利用场景以及如何利用它们。
a. 控制链接到站点的GPO
第一个利用场景是最直接的,发生在用户对链接到站点的组策略对象具有任何类型的写权限时。在这种情况下,该用户可能会向站点链接的GPO注入恶意配置,并危害与站点关联的任何(或所有)对象。
本节其余部分的演示将基于以下环境:一家公司拥有一个Active Directory林,根域为corp.com。它有三个站点:默认的Default-First-Site-Name站点(用于组织在巴黎的主要办公室),以及用于其地区办公室的NewYork和Sidney站点。
假设攻击者已控制用户adove,该用户控制Paris_Servers_Firewall_Rules GPO。此GPO链接到默认站点Default-First-Site-Name,该站点有一个服务器,即来自corp.com根域的AD01-DC。
这可以通过将恶意配置注入到Paris_Servers_Firewall_Rules GPO中,并等待AD01-DC域控制器应用它来利用,从而危害DC的域。为此,可以使用我们最近发布的GroupPolicyBackdoor.py工具。它提供了一个稳定的Python GPO操作利用框架。项目的wiki详细描述了该工具的工作原理,并提供了命令示例。简而言之,希望注入目标GPO的配置由ini文件描述。虽然支持各种配置,但我们将注入一个简单的即时计划任务到GPO中,将我们控制的adove用户添加到本地管理员组。请注意,我们还通过使用计算机名称过滤器仅针对AD01-DC域控制器,因为我们不希望站点中的所有计算机都执行我们的任务。创建以下文件ImmediateTask_create.ini:
|
|
然后,可以简单地使用gpo inject命令将描述的配置注入到目标GPO中。
|
|
剩下要做的就是等待目标域控制器应用恶意计划任务,并将adove用户添加到本地管理员组——即corp.com域的Domain Admins组。域控制器的GPO刷新每5分钟发生一次,之后可以通过连接到管理共享C$来验证我们的用户确实是域控制器的本地管理员。
|
|
然后,可以使用gpo clean命令使用GroupPolicyBackdoor.py清除注入的配置,以删除利用痕迹。
b. 利用对站点的GenericAll、GenericWrite或WriteGPLink权限
第二个利用场景发生在用户对站点具有GenericAll、GenericWrite或WriteGPLink权限时。这可能由于嵌套组成员资格或Active Directory环境中常见的配置错误而发生。但这也可能是管理员的刻意选择。实际上,Active Directory明确允许管理员委派管理站点组策略链接的能力。
GenericAll、GenericWrite和WriteGPLink ACL都允许攻击者做一件有趣的事情:修改站点的gPLink属性。
gPLink属性是一个LDAP属性,指示哪个GPO链接到容器(域、组织单位,或在我们的情况下是站点)。通过修改gPLink的值,攻击者可以诱使链接到目标容器的对象应用恶意GPO。这可以通过两种方式实现。
第一种方式是最直接的。如果攻击者控制域中的任何GPO,他们将能够向其注入恶意配置,然后利用其GenericAll、GenericWrite或WriteGPLink权限将其链接到目标站点。再次,这可以使用GroupPolicyBackdoor.py工具执行。将恶意配置注入GPO所需的命令与上述相同。然后可以使用links link命令链接修改后的GPO。
|
|
如果攻击者没有控制GPO,仍然可以利用有限的先决条件滥用GenericAll、GenericWrite或WriteGPLink ACL。所涉及的技术最初由Petros Koutroumpis在其出色的研究“OU having a laugh”中描述。我们后来在此基础上展示了该技术如何用于危害组织单位中的受保护对象或利用有限OU权限。我们还发布了一个自动化攻击的工具OUned.py。
该攻击的原理在Petros Koutroumpis的文章以及我们的文章中都有详细解释。我们不再赘述。攻击的核心原理是向目标容器(此处为站点)的gPLink属性添加一个GPO链接。此GPO链接指向解析到攻击者控制下的机器的DNS名称,例如s1n.corp.com:
|
|
与站点关联的对象然后会尝试从攻击者的机器上获取GPO,该机器将模拟有效的组策略容器(LDAP)以及有效的组策略模板(SMB)来为尝试应用恶意GPO的客户端提供服务,从而危害这些客户端。
以下是使用OUned.py的快速演示。假设用户aacre对NewYork站点具有WriteGPLink权限,该站点有AD01-DC2作为corp.com的域控制器。
OUned.py接受一个配置文件,如下所示:
|
|
OUned.py最近进行了修改,以接受模块文件作为输入,格式与GroupPolicyBackdoor使用的相同。该文件(此处为ImmediateTask_create_computer.ini)描述了作为利用一部分将交付给目标对象的恶意配置。在本例中,该文件将再次是一个简单的即时任务,将受控用户aacre添加到本地管理员组,即NewYork站点的域控制器的域管理员组。请注意,我们仅通过定义过滤器来针对域控制器;如果您不希望站点的所有对象都应用您的恶意配置,这可能很重要。
|
|
让我们使用定义的配置启动OUned.py。OUned毒化站点的gPLink属性,然后等待与NewYork站点关联的对象更新其GPO。它将仅向站点的服务器AD01-DC2交付恶意即时任务。
|
|
最多5分钟后,AD01-DC2域控制器尝试刷新其GPO,并将尝试应用恶意GPO。通过OUned.py工具的利用模拟了有效的GPC以及有效的GPT,并交付恶意GPO。完成后,可以按CTRL+C触发清理操作(主要是恢复站点的gPLink属性)。
最后,我们可以验证aacre用户现在是AD01-DC2域控制器的本地管理员——意味着corp.com域已被攻陷。
|
|
5. 滥用Active Directory站点进行林内横向移动
最后一部分描述了另一个涉及Active Directory站点的有趣攻击向量,这次是用于横向移动。更具体地说,该技术允许已攻陷林中某个域的攻击者攻陷林中的其他域,无论SID过滤配置如何。
该技术在Jonas Bülow Knudsen、Martin Sohn Christensen和Tobias Thorbjørn Munch Torp的广泛研究“SID filter as security boundary between domains?”中有详细描述。该研究由7篇文章组成,描述了各种林内和林间横向移动技术。我们感兴趣的技术在第4部分中描述。
本节的目的是试图使该技术更广为人知,并展示如何使用GroupPolicyBackdoor.py以一种相当实用的方式利用它。
a. 攻击理论
本文前面提到,与站点相关的对象位于LDAP目录的配置命名上下文中。
命名上下文,也称为目录分区,指定中心目录的特定部分,具有独立的复制范围和时间安排数据。默认情况下,Active Directory实现三个独立的分区:
- 架构分区:中心目录的这一部分充当蓝图,描述林中存在的对象及其结构。此分区在林范围内复制,意味着林中的每个域控制器都具有架构分区的相同副本,即使它们来自不同的域。复制过程(站点间或站点内)确保分区在整个林中相同。
- 配置分区:此分区主要保存与网络拓扑和复制相关资产(例如站点)相关的信息。与架构分区相同,林中的每个域控制器都具有配置分区的相同版本,该版本在它们之间复制。
- 域分区:域分区包含与本地域关联的目录对象,例如用户和计算机。此分区在域内复制,但不与林中的其他域共享。
这里有趣的点是,配置分区在整个林中复制,林中任何域的任何域控制器都持有此分区的可写副本。
这具体意味着,已攻陷林中任何域的攻击者(例如,子域)可以修改林的配置分区。这反过来意味着该攻击者可以修改AD站点的配置。正如我们在整篇文章中演示的那样,站点可以与组策略对象关联。因此,从他们攻陷的域中,攻击者能够将恶意GPO链接到包含林中其他域的域控制器的一个或多个站点。在配置命名上下文复制后,目标域的域控制器将应用恶意GPO,从而导致它们被攻陷。
关于配置分区上的权限,默认情况下以下主体具有写入权限:林根域的Domain Admins组、Enterprise Admins和Enterprise Domain Controllers组,以及存储配置分区的任何域控制器的本地帐户NT AUTHORITY\SYSTEM。在除林根域之外的任何其他域上,成为域管理员不足以修改配置分区。为此,有必要以域控制器的SYSTEM帐户执行命令。
请注意,所描述的攻击向量不受任何与SID过滤相关的强化措施的阻碍。
该攻击工作的一个先决条件是,通过站点针对的域控制器必须与已攻陷域的至少一个域控制器具有网络连接。实际上,恶意GPO通常托管在已攻陷的域中;获取它因此需要来自目标域控制器到已攻陷域控制器的LDAP和SMB流量。这个先决条件在绝大多数情况下都会得到满足。实际上,如果已攻陷和目标域控制器在同一站点中,站点内复制要求域控制器彼此通信。同样,如果已攻陷和目标域的域控制器放置在相邻站点(通过站点链接直接链接的站点)中,通常至少一个已攻陷域控制器应该可以被目标站点中的至少一个域控制器访问(即所谓的“桥头堡服务器”)。如果网络未完全路由,并且复制通过可传递站点链接执行,则可能无法满足此先决条件。然而,始终可以跨站点链接移动并攻陷与目标站点链接的站点,以便最终转移到目标站点。
b. 实践
与基于GPO的攻击向量经常出现的情况一样,描述当前技术的文章可能并不总是提供端到端的实际演示来说明如何利用它。本节旨在描述如何具体执行利用,使用GroupPolicyBackdoor.py。
为了说明目的,我们将考虑一个Active Directory林,其根域为corp.com。该域有一个子域dev.corp.com。林只有一个站点,默认的Default-First-Site-Name,其中包含林的所有资产。攻击者已攻陷dev.corp.com子域,并希望从那里攻陷林的根域corp.com。攻击者控制了devadm用户,并且该用户是dev.corp.com上的域管理员。
执行攻击需要两个步骤。首先,应在已攻陷的域上创建恶意GPO(也可以向现有GPO中注入恶意配置)。这可以通过GroupPolicyBackdoor.py的gpo create命令实现。在这里,我们将创建一个名为LATERAL的GPO。
|
|
一旦创建了GPO,就可以向其注入恶意配置。为保持简单,我们将注入一个即时任务,将来自子域的受控用户devadm添加到本地管理员组。目标机器AD01-DC(corp.com的域控制器)将被针对。
|
|
|
|
恶意GPO已准备就绪,其GUID为4F594057-88EC-4C8C-9FC9-A167B0A75242。攻击者现在需要将其链接到Default-First-Site-Name站点。为此,如前所述,有必要在dev.corp.com的域控制器上以SYSTEM身份执行命令。有几种选择可以做到这一点。最直接的方法是使用计划任务。虽然可以使用impacket套件中的atexec.py实用程序,但如果目标机器上安装了EDR,这可能不是最佳解决方案。让我们继续利用GPO:我们将向子域的Default Domain Controllers Policy注入一个计划任务,该任务将以SYSTEM身份运行,并使用PowerShell cmdlet将恶意GPO链接到站点。
|
|
|
|
现在,剩下要做的就是等待。最多5分钟后,被修改的Default Domain Controller Policy GPO将使DEV01-DC的SYSTEM帐户执行链接操作。Default-First-Site-Name站点的gPLink值将通过附加恶意GPO LATERAL进行更新。
然后,配置分区的复制在另外5分钟后发生(因为我们在同一站点)。最后,再5分钟后,AD01-DC机器执行恶意GPO LATERAL,将devadm用户添加到本地管理员组,这意味着corp.com的Domain Admins。
要验证这一点,可以连接到AD01-DC的管理共享C$。
|
|
与往常一样,可以使用GroupPolicyBackdoor.py清理注入的配置并删除创建的GPO。
结论
涉及Active Directory站点的攻击路径可能不是最常见的,也不是最方便利用的。然而,当它们确实存在时,它们可能非常关键,因为它们可能导致整个域(或多个域)的沦陷。
从防御的角度来看,定期审查分配给您的Active Directory站点对象的ACL可能非常重要。如果您的组织出于管理目的委派了与站点相关的权利,则尤其如此。此外,可以为与基于GPO的攻击向量相关的工件创建检测规则,例如GPO修改、创建或敏感容器gPLink属性的更改。
注释:
- 请注意,当启动OUned时,我们将AD01-DC2指定为域控制器——这样,
gPLink属性将在此DC上修改——如果我们选择了位于另一个站点的另一个DC,我们将不得不等待180分钟(默认)进行复制,并且NewYork站点的对象才会拾取其站点关联的gPLink属性的修改。 - 例如,假设一个三站点拓扑。站点A链接到站点B,站点A链接到站点C。站点B和C通过站点A可传递链接,站点A充当中间站点。在这种情况下,如果一个域的所有域控制器都位于站点B中,而另一个域的所有域控制器都位于站点C中,则两个域的域控制器之间可能存在没有网络链接(因为复制通过站点A进行)。那么,通过当前描述的技术,从站点B中的已攻陷域到站点C中的目标域的直接横向移动可能是不可能的,因为目标域控制器可能无法连接到已攻陷的域控制器。然而,始终可以利用该技术从站点B攻陷站点A,然后最终转移到站点C。