滥用 Cloud Kerberos Trust 从 Azure AD 获取域管理员权限

admin 2024年7月8日07:42:08评论10 views字数 8817阅读29分23秒阅读模式

滥用 Cloud Kerberos Trust 从 Azure AD 获取域管理员权限

许多现代企业在混合环境中运营,其中 Active Directory 与 Azure Active Directory 一起使用。在大多数情况下,身份将从本地 Active Directory 同步到 Azure AD,并且本地 AD 仍然具有权威性。由于这种集成,当本地 AD 受到威胁时,通常可以横向移动到 Azure AD。从 Azure AD 横向移动到本地 AD 并不常见,因为大多数信息通常从本地流向云。云 Kerberos 信任模型在这里是一个例外,因为它从本地 Active Directory 向 Azure AD 创建信任,因此它信任来自 Azure AD 的信息以执行身份验证。在本博客中,我们将研究攻击者如何滥用此信任,获得 Azure AD 中的全局管理员权限,以在设置了云 Kerberos 信任的环境中将其权限提升到域管理员。由于这种技术是此信任类型设计的结果,因此本博客还将重点介绍管理员可以实施的检测和预防措施。

攻击模型

混合环境中的大多数攻击都是从 Active Directory 横向移动到 Azure AD,因为身份来源是本地 Active Directory,身份从该 Active Directory 同步到 Azure AD。因此,受感染的 Active Directory 几乎总是会导致受感染的 Azure AD。我过去在各种演讲和博客中介绍过几种这样的攻击路径:

  • 通过同步错误覆盖 Azure AD 管理员凭据

  • 通过 Azure AD 连接同步帐户向服务主体添加其他凭据

  • 滥用无缝单点登录通过 Kerberos冒充云中身份

从 Azure AD 到本地 AD 的攻击要少得多,因为在许多情况下,AD 不会同步 Azure AD 中的很多信息,并且现有的写回功能使用 Active Directory 的权限模型来防止更改第 0 层资源(例如域管理员)的信息。云 Kerberos Trust 功能是一个例外,因为它在 AD 中创建只读域控制器 (RODC) 并将其凭据存储在 Azure AD 中。这实际上为 Azure AD 提供了高度特权的密钥,它可以使用这些密钥对 Active Directory 中的大多数帐户进行身份验证。虽然我们无法从 Azure AD 中提取这些密钥,即使使用 Global Admin 也无法提取,但我们可以滥用一些其他攻击路径来实现 Active Directory 中的域管理员。此攻击路径假定以下起始先决条件:

  • 攻击者已获得 Azure AD 中的全局管理员权限。

  • 攻击者与本地 Active Directory 的至少一个域控制器有网络连接。

  • 云 Kerberos 信任功能已设置并正常运行。

网络连接部分使得这种攻击不能从完全外部的角度进行,但如果 Azure 托管资源和本地域之间存在任何 VPN,或者通过 Intune 推出 VPN 配置,则这应该不难获得。如果攻击者在 Active Directory 网络中并且由于某种原因获得了全局管理员权限但尚未获得域管理员权限,那么这也是一种有效的攻击。

云 Kerberos 信任

添加云 Kerberos 信任作为一种方法,用于允许使用无密码身份验证方法的帐户登录到 Active Directory 连接的资源。顾名思义,无密码方法不涉及密码,因此 Windows 无法为该帐户计算 NT 哈希或 Kerberos 密钥。由于 Active Directory 没有 FIDO2 密钥等内容的本机实现,因此建立了与 Azure AD 的信任,并为 Azure AD 提供了一组密钥,可用于为 Active Directory 颁发 Kerberos 票证。设置通常使用 PowerShell 脚本执行,该脚本在 AD 中创建只读域控制器 (RODC)。此 RODC 实际上并不作为 Active Directory 中的 Windows 服务器存在,而更像是一个虚拟帐户,纯粹用于建立此信任。RODC 由两个重要组件组成:

  • RODC 计算机帐户,名为AzureADKerberos$。此帐户的存在也表明域中正在使用云 Kerberos。

  • krbtgt名为 的辅助帐户krbtgt_AzureAD。此帐户包含用于 Azure AD 创建的票证的 Kerberos 密钥。此帐户的 SAM 帐户名称将包含密钥 ID,例如krbtgt_9898。

RODC 计算机帐户及其辅助 krbtgt 帐户通过属性链接在一起msDS-KrbTgtLinkBl。这很重要,因为 RODC 带有一组限制,这些限制是在 RODC 计算机帐户上设置的,但也适用于辅助 krbtgt 颁发的任何票证。因此,虽然 Azure AD 在技术上可以为具有管理员权限的用户(例如域管理员)颁发票证,但这些票证将被 AD 域控制器拒绝,因为 RODC 不允许为他们颁发票证。这在属性msDS-RevealOnDemandGroup和中进行管理msDS-NeverRevealGroup,在 GUI 中总结为“密码复制策略”:

滥用 Cloud Kerberos Trust 从 Azure AD 获取域管理员权限

我们看到,由于“域用户”处于默认范围内,因此域中的任何用户(明确拒绝的任何组中的用户除外)都可以从 Azure AD 进行身份验证。虽然这包括大多数默认的高权限组,但在实际域中,可能会有更多具有同等权限但不属于任何这些组的用户,因此这些将是我们稍后的目标。

Azure AD 如何颁发 Kerberos 票证

如果设置了云 Kerberos 信任,则当用户使用混合身份在 Windows 上进行身份验证时,Azure AD 将发出部分 Kerberos 票证。此过程与请求主刷新令牌 (PRT) 同时发生。Windows 表示它想要一个tgt=true请求中带有参数的 TGT。请求本身是一个签名的 JWT,其中包含用户凭据或用于身份验证的 Windows Hello 断言。我已经多次谈到过这个请求的内容,例如在去年的TROOPERS演讲中,以及今年在Insomnihack上的更多演讲。这里的重要部分是tgt参数,它将导致 Azure AD 至少包含一个可用于 Azure AD Kerberos 的云 TGT(当您通过 SMB 使用 Azure AD 连接的文件共享时最相关),并且如果配置了 AD 的 TGT:

滥用 Cloud Kerberos Trust 从 Azure AD 获取域管理员权限

tgt_cloud如果已配置并适用于我们用于身份验证的帐户,响应将具有以下tgt_ad参数:

滥用 Cloud Kerberos Trust 从 Azure AD 获取域管理员权限

参数clientKey是 TGT 会话密钥,以 JWE(JSON Web 加密)格式加密发送。Windows 将首先使用设备的传输密钥解密 PRT 的会话密钥。一旦它拥有 PRT 会话密钥,它就可以使用它来解密 TGT 会话密钥。我们将其称为部分 TGT,因为与常规 TGT 不同,它不包括用户的所有信息,只是因为 Azure AD 没有来自用户帐户的属性或组的完整列表。结果是 TGT 带有一个 PAC,它只包含基本属性,例如用户安全标识符 (SID) 及其名称。Windows 可以通过请求服务的服务票证将此部分 TGT 交换为完整 TGT krbtgt。该krbtgt服务通常在初始 TGT 请求操作期间使用,但它也可以在此流程中用于请求完整 TGT。请求在 TGS-REQ 消息中发送到域控制器:

滥用 Cloud Kerberos Trust 从 Azure AD 获取域管理员权限

域控制器将回复包含新 TGT 的 TGS-REP 消息,现在包括具有所有用户属性和组成员身份的完整 PAC。此 TGT 使用krbtgt域的主密钥加密,可用于为接受 Kerberos 身份验证的服务请求服务票证。
NTLM 身份验证
拥有 Kerberos TGT 仍然会在身份验证场景中留下空白。毕竟,如果用户想要对不支持 Kerberos 且仅接受 NTLM 身份验证的服务进行身份验证,该怎么办?为此,Windows 需要 NT 哈希来计算正确的身份验证质询/响应。拥有 NT 哈希意味着仍然需要密码,这是我们最初希望通过无密码来避免的。因此,微软提出了 Kerberos 协议的扩展,允许 Windows 在将使用辅助密钥签名的(部分)TGT 交换krbtgt为使用主krbtgt密钥签名的完整 TGT 时获取用户的 NT 哈希。请注意,虽然这仅适用于辅助密钥签名的票证,但此方案专为无密码身份验证而设计,真正的 RODC 不使用这些协议扩展。交换过程(包括 NT 哈希恢复)由Leandro Cuozzokrbtgt研究,他撰写了一篇关于它的精彩技术博客,并在 impacket 库中添加了对此的支持。
此过程中的关键是将KERB-KEY-LIST-REQ字段包含在请求的 PADATA 部分中。此行为记录在MS-KILE中,并表明如果遇到,KDC 应在回复中包含长期机密。在这种情况下,长期机密是用户帐户密码的 NT 哈希(我也曾尝试通过这种方式恢复 AES 密钥,但似乎不起作用)。正如我们在上一节的屏幕截图中看到的那样,Windows 确实将其作为 PA-DATA 类型 161 包含在请求中。如果我们查看下面的响应,我们会看到 NT 哈希包含在响应的加密部分中。Windows 可以使用 TGT 会话密钥解密它并将 NT 哈希加载到内存中。

滥用 Cloud Kerberos Trust 从 Azure AD 获取域管理员权限

将 Cloud Kerberos Trust 与 roadtx 结合使用

自去年发布以来,为 Azure AD 或混合用户请求 PRT 的过程一直是 roadtx 的一部分。请求 PRT 将自动包含对 TGT 的请求,并且生成的 TGT 将包含在文件中.prt。Roadtx 还将自动解密 TGT 会话密钥并将其包含在文件中,.prt以便其他工具也可以使用它。例如,我在这里为混合帐户获取 PRT。这假设我之前已将设备注册或加入到此 Azure AD 租户,这可以使用roadtx 设备模块完成,该模块的证书和密钥分别存储在和中talkdevice.pem。talkdevice.key这里需要注意的一点是,虽然此机制是为无密码身份验证方法设计的,但如果我们使用密码进行身份验证,Azure AD 也将包含 TGT。使用密码,我们也可以直接从 Active Directory 请求完整的 TGT,但这将在本博客的后面部分介绍。

滥用 Cloud Kerberos Trust 从 Azure AD 获取域管理员权限

由于这是 Active Directory 和 Azure AD 中都存在的帐户,因此 Azure AD 将部分 TGT 与 PRT 一起包含在内。可以从文件中提取此 TGT .prt,并使用roadtools_hybrid存储库中的某些实用程序将其交换为完整 TGT,并将其保存在 ccache 文件中。Ccache 文件与impacket兼容,因此只要我们与域控制器有网络连接,我们就可以使用getST.py脚本将部分 TGT 升级为完整 TGT。

滥用 Cloud Kerberos Trust 从 Azure AD 获取域管理员权限

我们可以使用这个 TGT 对 Active Directory 连接的服务进行身份验证。我们还可以使用略有不同的脚本恢复用户的 NT 哈希。工具包partialtofulltgt.py中的脚本roadtools_hybrid结合了这两个步骤,要么直接从文件中获取部分 TGT .prt,要么从我们保存它的 ccache 文件中加载它。它还将自动使用该KERB-KEY-LIST-REQ选项,礼貌地要求 DC 将 NT 哈希放入响应中:

滥用 Cloud Kerberos Trust 从 Azure AD 获取域管理员权限

在这种情况下,NT 哈希并不是真正秘密的,因为我们一开始就已经知道了密码,但如果我们在 Azure AD 中的混合身份之间进行任何横向移动,如果密码足够弱并且我们设法破解它,那么拥有 NT 哈希就可以让我们获得该用户的密码。

滥用 Cloud Kerberos Trust 获取域管理员权限

为了充分利用前面几节中的知识,我们需要仔细研究 Azure AD 如何确定为哪个用户颁发部分 TGT,以及在此 TGT 中放入哪些信息。Azure 门户hybrid在“本地”部分显示了我们帐户的各种相关属性:

滥用 Cloud Kerberos Trust 从 Azure AD 获取域管理员权限

Azure AD 使用“本地 SAM 帐户名称”和“本地安全标识符”属性来生成票证。作为全局管理员,我们可能会认为我们可以编辑这些属性,并可能为 AD 域中的任何用户帐户(包括未同步的用户帐户)获取票证。但是,修改这些属性并不像听起来那么容易,因为 Microsoft Graph 和 Azure AD Graph 都不允许这样做,表明这些是只读属性。还有第三种更新帐户的方法,它在允许或不允许方面更加灵活。这是 Active Directory Connect 用于创建和更新同步用户的 API。通常,此 API 仅由具有“目录同步帐户”角色的“本地目录同步服务帐户”使用。作为全局管理员,我们可以创建一个新的同步帐户并获得相同的权限。但是,我们不需要这样做,因为全局管理员角色本身也允许使用同步 API。我认为这是因为 AD Connect 帐户本身曾经是全局管理员,并且某些环境可能仍以这种方式运行。在分析 Azure AD Connect 如何更新帐户时,我们遇到了这种二进制和文本数据的丑陋混合:

滥用 Cloud Kerberos Trust 从 Azure AD 获取域管理员权限

这是 WCF 二进制 XML,这是 .NET 中用于以二进制格式传输 XML 数据的标准。幸运的是,ENRW多年前发布了一个开源 Python 解析器。甚至还有一些最近的补丁,修复了与同步 API 的兼容性问题,由@AndreasLrx和@sfonteneau贡献。使用此库解码 WCF 二进制数据,我们得到了一个可读性更强的 XML 文档:

滥用 Cloud Kerberos Trust 从 Azure AD 获取域管理员权限

我们可以使用此 API 调用来修改任何混合用户的 SAM 名称和 SID,然后如果我们进行身份验证,我们将获得包含修改后的 SID 的部分 TGT。

滥用 Cloud Kerberos Trust 从 Azure AD 获取域管理员权限

请注意,我们可以对 AADInternals 执行相同操作,它也支持二进制 XML 格式,并通过Set-AADIntAzureADObject cmdlet 通过此协议更新同步用户。

攻击前提条件

为了使攻击成功并授予我们域管理员权限,我们有几个要求:

  • 通过同步 API 修改帐户的权限。我们已经提到,在这种情况下,全局管理员或 AD Connect 同步帐户将起作用。混合身份管理员角色也将提供必要的权限,因为这可以管理 AD Connect 并创建新的同步帐户。

  • 至少一个我们可以修改并进行身份验证的混合帐户。这可能与上一点中的帐户相同,但由于最佳实践表明混合帐户不应具有高特权角色,因此管理员帐户不太可能从本地同步。

  • Active Directory 中要瞄准的受害者帐户。虽然我们可以对任何已同步的帐户使用此攻击而无需修改其属性,但我们不能在 Azure AD 租户中拥有重复的本地安全标识符,因此要修改帐户并获取票证,我们需要有一个未同步的帐户。

有多种方法可以获取混合帐户的访问权限。它们在产生的噪音量以及我们定位的真实用户是否可以继续工作或其身份验证是否会中断方面略有不同。

  • 获取任何同步帐户的密码(例如使用喷洒、本地横向移动等)。

  • 通过管理门户重置混合帐户的密码,如果启用了密码写回,这也会将在 Active Directory 中重置该密码。

  • 使用同步 API 更改已同步 Azure AD 帐户的密码。这会保留 Active Directory 中的原始密码,但会导致 Azure AD 和 AD 中的密码断开连接。我们可以通过 TGT 升级请求获取此帐户的 NT 哈希,如果我们可以从 NT 哈希中恢复原始密码,我们可以稍后将密码设置回来。

  • 为帐户分配无密码凭据。以前可以直接在帐户上配置 Windows Hello for Business 密钥,正如我在今年的各种会议上所讨论的那样,但这个问题已经解决了。另一种解决方法是为帐户分配临时访问通行证 (TAP),以此方式设置无密码方法,然后通过它们获取 PRT。

  • 通过同步 API 创建具有已知密码的新用户帐户,并直接设置目标 SID。

最后,我们需要一个在本地 Active Directory 中具有域管理员或同等权限但在 RODC 的复制配置中未被拒绝的帐户作为目标。在任何大型域中,可能都有多个具有同等权限但未明确属于域管理员组的帐户。但是,对于这种情况,我们将重点关注应存在于任何设置为混合的域中的帐户。此攻击的理想受害者实际上是 AD Connect Sync 服务使用的 Active Directory 帐户。此帐户未同步到 Azure AD,因此其 SID 可供攻击,并且由于其能够同步密码哈希(假设正在使用密码哈希同步),因此它具有域管理员同等权限。如果域使用快速安装,其名称将以MSOL_开头。如果它有不同的名称,您应该能够通过列出对域对象具有目录复制权限的所有帐户来找到它。

滥用 Cloud Kerberos Trust 从 Azure AD 获取域管理员权限

全面进攻

现在我们知道了要求,让我们进行完整的攻击。我们有一个 Global Admin 帐户[email protected]来执行攻击,还有一个可以修改以执行攻击的混合帐户[email protected]。在这种情况下,我们知道混合帐户的密码,这是我们获取帐户 PRT 所需的全部内容。我们还查询了同步帐户,该帐户MSOL_9c3bf742d8e9在我的租户中被称为并具有安全标识符S-1-5-21-1414223725-1888795230-1473887622-1104。

第一步是获取 Global Admin 的访问令牌。同步服务使用与 Azure AD Graph API 相同的资源 ID,因此我们可以使用 roadtx 获取管理员帐户的令牌。gettokens如果不需要 MFA,我们可以使用命令执行此操作,或者使用interactiveauth来获得也支持 MFA 的交互式窗口。在我的示例中,我的凭据存储在 KeePass 数据库中,因此我使用以下命令keepassauth:

滥用 Cloud Kerberos Trust 从 Azure AD 获取域管理员权限

接下来,我们可以使用中的脚本修改[email protected]身份。这里的一个重要参数是,因为它用于将用户与 Azure AD 帐户匹配。在门户中,这被称为“本地不可变 ID”,在 ROADrecon 中,您可以在用户对象上找到它作为属性。我们还可以使用不存在的来创建新用户,这只会引入一个额外的步骤来为帐户添加密码。我们还向工具提供目标 SAM 名称和所需的 SID,该工具将在用户对象上更改这些内容:modifyuser.pyroadtools_hybridSourceAnchorimmutableIdSourceAnchorhybrid@hybrid.iminyour.cloud

滥用 Cloud Kerberos Trust 从 Azure AD 获取域管理员权限

我们可以在 Azure 门户中确认用户属性已更改:

滥用 Cloud Kerberos Trust 从 Azure AD 获取域管理员权限

现在帐户已修改,我们可以为该用户请求 PRT,包括部分 TGT。最好等待一分钟以确保我们的更改已正确同步,但通常这很快:

滥用 Cloud Kerberos Trust 从 Azure AD 获取域管理员权限

通过部分 TGT,我们可以请求完整的 TGT 并恢复 NT 哈希,这次针对 MSOL 帐户:

滥用 Cloud Kerberos Trust 从 Azure AD 获取域管理员权限

使用完整的 TGT(或 NT 哈希),我们可以与域控制器通信并执行 DCSync 攻击,同步所有哈希,包括完整 KRBTGT 帐户的哈希,这使我们能够伪造自己的 TGT,从本质上提升我们对完整域管理员的访问权限。

滥用 Cloud Kerberos Trust 从 Azure AD 获取域管理员权限

最后一步,建议使用 将帐户更改回其原始 SAM 名称和 SID modifyuser.py,或者如果我们创建了新帐户,则删除该帐户。此步骤是可选的,因为据我所知,Azure AD Connect 将自动获取更改并撤消更改。

防御与检测

云 Kerberos 信任引入了从 Active Directory 到 Azure AD 的信任。如果 Azure AD 租户完全被攻破,这将允许攻击者通过上一节中的一种方法在同步身份之间横向移动。这不是可以完全预防的事情,因此这里最好的防御措施之一是使用 Azure AD 中提供的工具来保护您的高特权身份。此外,高特权用户应该只存在于他们管理的环境中。这意味着 Azure AD 管理员角色中没有同步帐户,并且不要将 AD 管理员帐户同步到 Azure AD。

Azure AD 创建的 RODC 对象也提供了一些防御可能性。与普通 RODC 一样,您可以将其他帐户和组添加到“拒绝密码复制”列表中。如果您拥有高权限组,则拒绝来自 Cloud Kerberos Trust 的组是有意义的,尽管这确实意味着他们不能再使用无密码方法对本地资源进行身份验证,因为这会阻止 Kerberos 身份验证以及 NT 哈希恢复。无论如何,添加不需要使用无密码方法进行身份验证的帐户(例如 MSOL 同步帐户)将是一个很好的起点:

滥用 Cloud Kerberos Trust 从 Azure AD 获取域管理员权限

冒充被拒绝的帐户将导致攻击失败并出现错误KDC_ERR_TGT_REVOKED。

在检测方面,有好消息也有坏消息。坏消息是 Azure AD 不会记录对 SAM 名称和 SID 属性的更改,因此您无法针对此特定攻击创建有针对性的检测。好消息是仍有一些方法可以识别其中的各个部分。混合对象的更改已记录并显示参与者(我们的全局管理员)以及修改后的“LastDirSyncTime”属性。“LastDirSyncTime”属性仅在使用同步 API 时更新,而不是在常规用户修改期间更新。

滥用 Cloud Kerberos Trust 从 Azure AD 获取域管理员权限

由于在正常操作中,全局管理员帐户不应该使用同步 API,因此这显然表明发生了一些不正常的情况。其他操作(例如重置密码或在帐户上设置无密码身份验证方法)是管理员正常工作的一部分,因此为这些操作创建检测可能会更加嘈杂。

工具和资料

这些工具可在ROADtools和ROADtools 混合GitHub 页面上找到。感谢以下人员的先前工作:

  • Timo Schmid、@AndreasLrx和@sfonteneau负责 python-wcfbin 库。

  • DrAzureAD提供了一些关于 AD Sync 协议如何工作以及他在 AADInternals 中的实现的有用详细信息。

  • Leandro Cuozzo在其博客中谈到了云 Kerberos Trust 和密钥列表攻击。

最后,在完成这篇博客时,我还注意到Daniel Heinsen和Elad Shamir昨天就类似主题发表了演讲。虽然我还没有看过他们的演讲,但我还是想对他们的工作表示赞赏,并期待阅读他们关于这个主题的方法。

https://github.com/dirkjanm/ROADtools

https://github.com/dirkjanm/ROADtools_hybrid

https://github.com/ernw/python-wcfbin

https://github.com/AndreasLrx

https://github.com/sfonteneau

https://twitter.com/DrAzureAD

https://twitter.com/0xdeaddood

https://www.secureauth.com/blog/the-kerberos-key-list-attack-the-return-of-the-read-only-domain-controllers/

原文始发于微信公众号(Ots安全):滥用 Cloud Kerberos Trust 从 Azure AD 获取域管理员权限

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年7月8日07:42:08
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   滥用 Cloud Kerberos Trust 从 Azure AD 获取域管理员权限https://cn-sec.com/archives/2928615.html

发表评论

匿名网友 填写信息