需要云计算吗? 即刻开始体验

滥用 DHCP DNS 动态更新技术欺骗 DNS 记录

Ori David

寫於

Ori David

December 07, 2023

Ori David

寫於

Ori David

Ori David is a Security Researcher at Akamai. His research is focused on offensive security, malware analysis, and threat hunting. 

任由用户覆盖 DNS 记录而不加任何身份验证,将使攻击者在网域中的主机上轻易获得“中间机”的位置。

执行摘要

  • Akamai 研究人员发现了一系列针对 Active Directory 网域的新攻击,这些攻击会使用 Microsoft 动态主机配置协议 (DHCP) 服务器。

  • 利用这些攻击,攻击者可以欺骗敏感的 DNS 记录,进而造成从凭据盗用到全面入侵 Active Directory 网域的各种后果。这些攻击不需要任何凭据,并且会使用 Microsoft DHCP 服务器的默认配置。

  • 受影响的企业可能数量巨大。Microsoft DHCP 服务器在全世界得到了广泛使用;根据我们的观察,Akamai 所监控的网络中有 40% 都在运行此服务器。

  • 我们已将发现结果报告给 Microsoft,但他们尚未计划实施修复。

  • 在本博文中,我们将 详细介绍配置 Microsoft DHCP 服务器以抵御这些攻击的最佳实践 ,并将 分享一款工具 ,供系统管理员和蓝队用于检测存在风险的配置。

  • 在后续的博文中,我们还将会分享相关的技术细节,介绍从攻击者的角度如何实施这些攻击。

前言

对于攻击者来说,如何能欺骗 DNS 记录极具吸引力,因为这可能会造成破坏性的后果,包括敏感数据泄露、凭据泄露,甚至是远程代码执行。

在本博文中,我们将调查 DNS 中很少有人研究并由看似无害的 DHCP 功能所暴露出来的一个攻击面。通过使用它,我们发现了攻击者可用来欺骗 Microsoft DNS 服务器上的 DNS 记录的一些不同方法, 包括未经身份验证的任意 DNS 记录覆盖。

除了攻击流之外,我们还将详细介绍 Microsoft DHCP 服务器的内部工作原理、它与 DNS 和 Active Directory 的交互以及如何正确地保护这些接口。虽然网上有很多零散(且不准确!)的 DHCP 相关资源,但是我们相信本博文的内容才是有关该主题的准确、全面的资源。防御者只需认真阅读这篇博文,即可获得所有关键信息。

DNS 和 Active Directory

文章内容将从 Active Directory (AD) 开始。AD 的运行高度依赖于 DNS。每个网域都需要一台 DNS 服务器来托管一个特殊的 DNS 区域,这个区域称为 Active Directory 集成 DNS (ADIDNS) 区域(图 1)。此区域用于托管所有已加入网域的机器的 DNS 记录以及 AD 中的不同服务。

每个网域都需要一台 DNS 服务器来托管一个特殊的 DNS 区域,这个区域称为 Active Directory 集成 DNS (ADIDNS) 区域(图 1)。 图 1:默认 ADIDNS 区域

ADI 区域中的记录使用称为 动态更新的 DNS 功能进行管理。此功能让每个客户端可以自行管理其记录。当需要创建或修改 DNS 记录时,客户端会发送一条特殊的 DNS 请求,其中包含需要在服务器上修改的数据(图 2)。当 DNS 服务器收到此请求后,它会相应地修改客户端的记录。

 此功能让每个客户端可以自行管理其记录。当需要创建或修改 DNS 记录时,客户端会发送一条特殊的 DNS 请求,其中包含需要在服务器上修改的数据(图 2)。 图 2:DNS 更新内容示例

DNS 动态更新一个的重要功能是 安全更新,该功能旨在控制谁可以修改区域中的每条 DNS 记录。如果没有安全更新功能,DNS 服务器就会盲目地遵从所有更新请求的要求,从而让攻击者能够轻松地覆盖现有记录。有了此功能,默认情况下 DNS 服务器将仅接受对 ADI 区域执行安全更新(图 3)。

有了此功能,默认情况下 DNS 服务器将仅接受对 ADI 区域执行安全更新(图 3)。 图 3:DNS 动态更新默认设置

使用安全更新时,服务器接收的所有更新请求都会经过身份验证和授权。 在 ADI 区域中,此操作使用 Kerberos 执行。在更新发送到服务器时,其中包含用于验证用户身份的 Kerberos 票证(图 4)。如需详细了解通过 DNS 进行 Kerberos 身份验证的过程,请参阅 Dirk-Jan Mollema 有关 通过 DNS 中继 Kerberos的研究。

在更新发送到服务器时,其中包含用于验证用户身份的 Kerberos 票证(图 4)。 图 4:DNS 更新中的 Kerberos 票证

每条 DNS 记录都会受到访问控制列表 (ACL) 的保护,该列表用于确定每个主体的访问权限。这些访问权限是在记录初次创建时确定的:当客户端通过发送 DNS 动态更新来创建 DNS 记录时,创建该 DNS 记录的机器帐户会被自动指定为该记录的所有者,并被授予相关权限。通常,每个 DNS 客户端都会使用自己的机器帐户票证来执行 DNS 更新。为了对更新请求进行授权,DNS 服务器会根据已经过身份验证的主体来验证该记录的 ACL。

在图 5 中,我们可以看到主机“PC.aka.test”的 DNS 记录的 ACL。此记录由该计算机帐户创建,因此它具有修改权限。

在图 5 中,我们可以看到主机“PC.aka.test”的 DNS 记录 ACL。此记录由该计算机帐户创建,因此它具有修改权限。 图 5:默认 DNS 记录 ACL

其他主体(一些拥有高级权限的内置组除外)不应拥有对该记录的相关权限。当其他主体尝试修改不属于它们或它们没有相关权限的 DNS 记录时,服务器会拒绝该更新。

攻击者可能对 ADIDNS 区域非常感兴趣。 NETSPI 的 Kevin Robertson 先前的研究 突出了一些针对这些 DNS 区域的令人感兴趣的攻击。我们想详细阐述此攻击面,因此开始深入研究其他相关功能,这让我们发现了一个有意思的功能,即 DHCP DNS 动态更新。

DHCP DNS 动态更新

DHCP 是一项网络管理协议,用于向客户端自动分配 IP 地址和其他网络选项。当客户端加入一个新网络时,它会尝试通过发送广播消息来联系 DHCP 服务器,以请求获取网络配置。在 DHCP 服务器收到此请求后,它会使用指定的 IP 地址对该客户端作出响应。

DHCP 是大多数企业网络中一项很常用的协议,尤其是 Microsoft DHCP 服务器,它是一个广泛使用的选项。 我们发现,我们所监控的数据中心网络中有 40% 都在运行 Microsoft DHCP 服务器。

虽然现代的 Windows 客户端(Windows 2000 及更高版本)通常会通过发送 DNS 动态更新来创建自己的记录,但也有例外情况。DNS 记录也可以使用称为 DHCP DNS 动态更新的 DHCP 功能进行创建。 此功能的用途在于,允许 DHCP 服务器代表其客户端注册 DNS 记录。只要客户端由 DHCP 服务器指定 IP 地址,后者就可以联系 DNS 服务器并更新客户端的 DNS 记录。为了执行这些更新,DHCP 服务器会使用(惊喜,惊吓!)DNS 动态更新。

这两个名称很相似,让人非常困惑,因此我们来说明一下:

功能

协议

用途

DNS 动态更新

DNS

允许 DNS 客户端在 DNS 服务器上创建或修改 DNS 记录

DHCP DNS 动态更新

DHCP

允许 DHCP 服务器代表其客户端创建或修改 DNS 记录,更新则使用 DNS 动态更新来执行

图 6 显示了 DHCP DNS 动态更新过程。

动态更新过程 图 6:DHCP DNS 动态更新过程
  1. DHCP 客户端从 DHCP 服务器获得一个 IP 地址并向其告知自己的 FQDN。

  2. DHCP 服务器将动态更新请求发送给 DNS 服务器。

  3. DNS 服务器会验证该请求,创建相关记录,并在动态更新响应中将结果告知 DHCP 服务器。

请注意,即使启用了 DHCP DNS 动态更新功能,默认配置也会要求客户端明确指定由 DHCP 服务器代表其创建 DNS 记录(图 7)。

请注意,即使启用了 DHCP DNS 动态更新功能,默认配置也会要求客户端明确指定由 DHCP 服务器代表其创建 DNS 记录(图 7)。 图 7:DHCP DNS 动态更新默认配置

要指定此设置,客户端需要发送专用的 DHCP 选项。DHCP 选项(图 8)是可以添加到 DHCP 数据包中的附加字段,客户端和服务器使用这些字段来交换信息。

要指定此设置,客户端需要发送专用的 DHCP 选项。DHCP 选项(图 8)是可以添加到 DHCP 数据包中的附加字段,客户端和服务器使用这些字段来交换信息。 图 8:DHCP 选项示例

在我们的示例中,客户端发送了 FQDN 选项,此选项在 RFC 4702中进行了具体说明。此选项允许 DHCP 客户端向服务器告知其完全限定域名 (FQDN),并指定该服务器是否应代表客户端注册 DNS 记录。为此,客户端可以使用属于 FQDN 选项的 Server 标志。将此项设置为 1 即是告诉服务器应根据所提供的 FQDN 来创建记录(图 9)。

 将此项设置为 1 即是告诉服务器应根据所提供的 FQDN 来创建记录(图 9)。 图 9:带有 FQDN 选项的 DHCP 请求

收到此请求后,DHCP 服务器会发送 DNS 动态更新并创建所请求的记录(图 10)。

收到此请求后,DHCP 服务器会发送 DNS 动态更新并创建所请求的记录(图 10)。 图 10:包含新记录的 ADI DNS 区域

此功能很有用,但现在不常用(如上所述,大多数现代 Windows 客户端可以直接创建自己的记录)。尽管如此, Microsoft DHCP 服务器默认情况下已启用此功能,这意味着 DHCP 服务器将为发出 DNS 记录请求的任何客户端创建 DNS 记录。

请注意,DHCP DNS 动态更新 不需要由 DHCP 客户端进行身份验证 ,即网络中的任何人都可以从 DHCP 服务器租用一个 IP,因此从本质上来说,攻击者可以使用 DHCP 服务器代表他们自己对 DNS 服务器进行身份验证。 这让攻击者无需任何凭据即可访问 ADIDNS 区域。

Microsoft 似乎已注意到此功能带来的潜在风险,并确认了其中的一些风险,但攻击者和防御者中大多数人仍然对此攻击面一无所知

以下各部分将详细介绍可以通过滥用 DHCP DNS 动态更新实施的攻击。

DHCP DNS 欺骗

先前介绍的 ADIDNS 欺骗攻击 将 ADIDNS 变成了用来改进典型 LLMNR/NBNS 欺骗 攻击的武器。在确定名称解析尝试失败(“失效主机”)后,攻击者会在 ADI 区域中注册名称,并使后续名称解析尝试指向攻击者的机器。

此攻击可能会造成严重影响,但它需要满足一个重要的前提条件,即有效的网域凭据。 通过使用 DHCP 服务器,我们可以绕过此要求并在没有任何凭据的情况下进行操作。我们只需针对 ADI 区域中不存在的任何 FQDN 发送 DHCP DNS 动态更新,然后 DHCP 服务器将为我们创建该 FQDN。我们将该攻击的此变化称为 DHCP DNS 欺骗。TrustedSec 的 Hans Lakhan 撰写的 一篇博文中也介绍了 此技术。

我们可以将什么 DNS 名称用于此攻击?此外,根据 Robertson 的研究结果,一些显而易见的候选项不适用。

没有了这两个候选项,我们只能选择确定特定于网络的失效主机。我们可以对网络进行监测,以获得通过本地链路多播名称解析 (LLMNR) 或 NetBIOS 名称服务 (NBT-NS) 进行的名称解析广播,从而确定这些主机。在识别出潜在的失效主机后,我们可以发送 DHCP DNS 动态更新来创建匹配的 DNS 记录(图 11)。

 在识别出潜在的失效主机后,我们可以发送 DHCP DNS 动态更新来创建匹配的 DNS 记录(图 11)。 图 11:利用 DHCP DNS 动态更新欺骗失效主机名
  1. 网络中的主机会尝试解析名称“PC.aka.test”并向 DNS 服务器发送查询。

  2. “PC.aka.test”对于 DNS 服务器是未知的,因此后者会以“无此类名称”进行回应。

  3. 然后,主机会发送 LLMNR 多播,以尝试在其 LAN 中找到“PC.aka.test”。

  4. 攻击者会识别此尝试,然后请求从 DHCP 服务器租用一个 IP 并将“PC.aka.test”作为 FQDN。

  5. 服务器会将动态更新请求发送到 DNS 服务器,并且将创建该记录。

现在,在网络中的任何主机下一次尝试解析“PC.aka.test”时,它们会被重定向到攻击者所在位置。攻击者现在要做的是触发 ntlmrelayx.py 并等待身份验证尝试。

此方法比标准 LLMNR/NBNS 欺骗方法和 ADIDNS 欺骗变化的效果更好。

  • 典型 LLMNR/NBNS 欺骗不需要进行身份验证,但其受害者有限,都位于同一 LAN 中(因为 LLMNR/NBNS 是基于多播的)。

  • ADIDNS 欺骗让我们能够以 LAN 外部的受害者为目标(因为 DNS 可以跨子网工作),但需要已经过身份验证的用户。

利用 DHCP DNS 动态更新,我们可以做到两全其美——攻击既能够作用于 LAN 外部的受害者,又不需要任何身份验证。

这真的非常棒,但我们能够做得更好。

覆盖现有记录

创建不存在的 DNS 记录很棒,但这让我们想起了另一个选项:如果我们尝试为已存在的主机名创建一条记录,会怎么样?我们能否以某种方法覆盖它们?理想情况下,这无法实现,对吧?但是…

我们发现了一些案例,在这些案例中未经身份验证的攻击者可以覆盖现有记录。我们将此技术称为 DHCP DNS 覆盖。在介绍这些案例之前,我们先来探讨一下有关 DHCP 动态更新过程的一些更多详细信息。

DNS 记录类型及其所有者

在论及 DHCP DNS 攻击时,需要明确两种类型的 DNS 记录之间的重要区别(图 12)。从现在开始,我们将使用以下术语:

  • 客户端记录:直接由 Windows 客户端创建的记录

  • 托管记录:由 DHCP 服务器代表客户端创建的记录

在论及 DHCP DNS 攻击时,需要明确两种类型的 DNS 记录之间的重要区别(图 12)。 图 12:DNS 记录类型

这些记录之间的关键区别在于它们的所有者。正如我们 在本博文先前部分中所述,在执行 DNS 更新时,系统会创建客户端记录,并将发送更新请求的主体指定为记录所有者。对于正常的 Windows 客户端,此主体为该客户端的机器帐户。

有人可能会猜想托管记录的所有者也是发出请求的客户端,但情况并非如此。当 DHCP 服务器代表客户端发送 DNS 更新时,它也会使用 自己的 机器帐户进行身份验证,而该帐户将成为记录所有者。

我们可以在图 12 中看到这一差别。PC2 是客户端所拥有的客户端记录,而 PC1 是 DHCP 服务器所拥有的托管记录。

访问控制列表可以限制 DHCP DNS 覆盖

在尝试对现有记录(在本示例中为“PC.aka.test”记录)执行 DHCP DNS 动态更新时,我们失败了。我们观察到一个有趣的行为:DHCP 服务器实际上 确实发送了包含我们所提供的 FQDN 的 DNS 更新,但该服务器随后拒绝了此更新(图 13)。

我们观察到一个有趣的行为:DHCP 服务器确实使用我们提供的 FQDN 发送了 DNS 更新,但是此更新被服务器拒绝了(图 13)。 图 13:DHCP DNS 更新被服务器拒绝

出现这种情况的原因是该 DHCP 服务器未获得授权,无法修改记录。

PC.aka.test 是 客户端 记录,其所有者是 PC$ 主体。当 DHCP 服务器发送 DNS 更新时,它会使用自己的机器帐户 DHCP$进行身份验证。由于该帐户没有权限修改记录,因此更新被拒绝(图 14)。

由于该帐户没有权限修改记录,因此更新被拒绝(图 14)。 图 14:DNS 记录覆盖失败

总结如下:攻击者可以使用 DHCP 服务器发送任意 DNS 更新,但由于存在 ACL,DNS 记录应该不会被覆盖。

现在,我们了解了应该可以防止覆盖的机制,接下来我们将了解如何继续执行记录覆盖。

托管记录覆盖

虽然由于 ACL 的限制作用,覆盖现有客户端记录无法实现,但覆盖托管记录(由 DHCP 创建的记录) 可以实现,因为身份验证机器也是记录所有者(图 15)。

此操作是可行的,因为 DHCP 服务器不会验证 DNS 记录所有权并且会针对任何所请求的 FQDN 的发送 DNS 更新。

尽管由于 ACL 的限制,覆盖现有客户端的记录不起作用,但覆盖托管记录(由 DHCP 创建的记录)却能成功,因为身份验证设备同时也是拥有记录的设备(图 15)。 图 15:DHCP 服务器记录的 DHCP DNS 覆盖

正如我们看到的那样,DHCP 服务器会使用拥有记录的帐户(它自己)来执行更新,因此更新可以成功完成。

我们来看一个示例。我们启动了一台 Ubuntu 服务器,该服务器不属于该网域,因此无法注册它自己的 DNS 记录。它会改为让 DHCP 服务器代表它来执行此操作(图 16)。

该服务器请求 DHCP 服务器代表其进行注册(图 16)。 图 16:DHCP 服务器代表 Ubuntu 服务器注册 DNS 记录

此记录的所有者是 DHCP 服务器机器帐户。现在,在租用过程中,我们通过攻击机器请求从 DHCP 服务器获取同一 FQDN。我们检查 DNS 区域,发现覆盖成功,现在记录指向刚才租给我们的 IP(图 17)。

我们检查 DNS 区域,发现覆盖成功,现在记录指向刚才租给我们的 IP(图 17)。 图 17:覆盖 Ubuntu 服务器的 DNS 记录

此攻击没有问题,但其影响十分有限,因为它只影响托管记录。正如我们先前所提到的,这些记录远不如客户端记录更常用,而后者不会受到此攻击的影响。尽管如此,在某些情况下,客户端无法注册它们自己的记录,但我们仍然可以找到托管记录。这些客户端包括:

  • 非 Windows 客户端

  • 旧版 Windows 客户端

  • 禁用客户端 DNS 更新的 Windows 客户端

DHCP 自覆盖

为了扩大潜在的影响,我们希望能够覆盖任何 ADI 区域中存在的记录,即客户端记录。问题在于,这些记录的所有者是创建它们的机器,并且我们只能使用 DHCP 服务器的机器帐户进行身份验证。

但是, DHCP 服务器的 DNS 记录呢? 当 DHCP 服务器创建它自己的 DNS 记录时,其机器帐户便成为了记录所有者!这证明, 我们可以让 DHCP 服务器自己执行 DHCP DNS 覆盖。 如果我们提供 DHCP 服务器名称作为我们的 FQDN,DHCP 服务器会针对自己的客户端记录发送 DNS 更新,这样此覆盖便会成功完成!

我利用 DHCP 来破坏 DHCP 图 18 显示此攻击过程。
DHCP DNS 覆盖 图 18:DHCP 服务器 DNS 记录的 DHCP DNS 覆盖

此攻击更加可靠:如果 Microsoft DHCP 服务器存在于网络中,则可以保证获得匹配的客户端记录,而托管记录(先前的覆盖情境所需的)更加少见。

关于影响,攻击者将能够拦截发往 DHCP 服务器的任何通信。严重性取决于此流量的性质。在大多数情况下,拦截发往 DHCP 服务器的通信的能力可能会被滥用于拦截并中继凭据,或者捕获可能会安装在服务器上的其他服务的敏感流量。

说到敏感服务:如果 DHCP 服务器安装在网域控制器 (DC) 上,会怎么样?我们能否覆盖 DC 记录?嗯,事实证明我们可以做到。

DHCP DC 任意覆盖

如果 DHCP 服务器安装在 DC 上,我们可以对 DC 自己的记录执行 DHCP DNS 覆盖(其原因与我们先前在本博文中说明的原因一样)。这可能非常有用,但我们还可以做更多事情。

正如我们已经知道的,如果 DHCP 服务器安装在 DC 上,则发送 DNS 更新时将使用该 DC 的机器帐户。有意思的是,如果我们检查任意 DNS 记录的默认 ACL,我们会发现 ENTERPRISE DOMAIN CONTROLLERS 主体对区域中的每条 DNS 记录都拥有写入权限,而这与谁创建了这些记录无关! (图 19)。

有趣的是,如果我们检查任意 DNS 记录的默认 ACL,我们会看到 ENTERPRISE DOMAIN CONTROLLERS 主体对该区域中的每条 DNS 记录都有写入权限——无论创建者是谁(图 19)。 图 19:所有网域记录的默认 ACL 均包含 ENTERPRISE DOMAIN CONTROLLERS 组

这是个大问题。如果 DHCP 服务器是 DC,则它对区域中所有记录都拥有相关权限,攻击者能够以未经身份验证用户的身份使用它来 覆盖 ADI 区域内的所有 DNS A 记录! 此攻击如图 20 所示。

这是个大问题。如果 DHCP 服务器是 DC,则它拥有区域中所有记录的权限,攻击者作为未经身份验证的用户,可以利用此功能覆盖 ADI 区域内的任何 DNS A 记录!此攻击如图 20 所示。 图 20:DHCP 服务器为 DC 时的任意 DHCP DNS 覆盖

我们的数据表明,在我们所观察到使用 Microsoft DHCP 服务器的网络中,这种存在风险的配置相当常见, 有 57% 的网络都将 DHCP 服务器安装在 DC 上。默认情况下,所有这些网域都容易受到攻击。

虽然 Microsoft 已在其文档中 确认了此风险,但我们认为,对这种错误配置的认识与其潜在影响不相符。

对 DHCP DNS 攻击的抵御措施以及攻击者如何能够绕过这些措施

上述所有攻击都适用于 Microsoft DHCP 服务器的默认配置。但是,有两种能够帮助抵御其中部分攻击的设置。我们来了解一下这些设置,以及攻击者如何绕过它们。

DHCP 名称保护

据我们所知,在 DHCP 服务器创建 DNS 记录后,将没有办法能够阻止其他客户端请求获取同一 FQDN 并强制服务器覆盖它。 名称保护 是一项旨在阻止出现此情况的功能。

名称保护是使用 DHCID(DHCP 客户端标识符)这一特殊 DNS 记录类型实现的。启用名称保护后,每次 DHCP 服务器代表客户端注册记录时,都会创建一条额外的 DHCID 记录(图 21)。

启用名称保护后,每次 DHCP 服务器代表客户端注册记录时,都会创建一条额外的 DHCID 记录(图 21)。 图 21:DHCP 服务器在启用名称保护的情况下创建的 DHCID 记录

正如您所看到的,DHCID 记录值是以 Base64 编码的数据块。此值(我们稍后将在本博文中分析它)是一个独特的签名,旨在识别请求进行记录创建或更新的 DHCP 客户端。

当 DHCP 服务器收到修改 DNS 记录的请求时,它会计算客户端的 DHCID 值,并发送包含更新后的数据以及该 DHCID 值的 DNS 更新。

如果 DNS 服务器上尚不存在该记录,它会直接创建该记录和匹配的 DHCID 记录。但是,如果主机 (A) 和 DHCID 记录已存在,DNS 服务器会将现有的 DHCID 值与 DHCP 服务器发送的值进行比较。只有在两个值匹配的情况下,才会执行更新。

因此,从本质上来说,DHCID 记录用于将 DNS 记录与创建它的客户端相关联。在此关联创建后,只有此原始客户端才能修改该记录。

绕过名称保护

我们发现了一个使用 DHCP 释放消息来绕过名称保护的方法。当 DHCP 客户端不再需要它们所租用的 IP 地址时,它们会发送该消息来告知服务器。为了跟踪租用的地址,DHCP 服务器保存了一份表格,其中存储不同的地址、地址的到期时间和租用这些地址的客户端的唯一标识符(图 22)。

为了跟踪租用的地址,DHCP 服务器保存了一份表格,其中存储不同的地址、地址的到期时间和租用这些地址的客户端的唯一标识符(图 22)。 图 22:DHCP 服务器租用表条目

唯一标识符就是客户端的 MAC 地址。当收到来自客户端的释放消息时,DHCP 服务器会查找是否存在具有匹配地址和 ID 的现有条目,然后删除已存在的条目。如果启用了 DHCP DNS 动态更新,则除了释放 IP 地址之外,DHCP 服务器还会发送 DNS 动态更新,以删除客户端的关联 DNS 记录。

如果我们可以发送包含唯一 ID(MAC 地址)的 DHCP 释放消息,而该 ID 与目标的 ID 相匹配,则 DHCP 服务器会删除此记录,从而让我们能够为自己注册记录—— 要想绕过名称保护,唯一需要的便是受害者的 MAC 地址! (请注意,无需更改我们的实际 MAC——此值将从 DHCP 标头中获取。)

如果我们与目标位于同一个 LAN 中,那么找到其 MAC 地址不费吹灰之力;例如,我们可以通过发送 ARP 请求来找到其 MAC 地址。但是,如果我们与目标不在同一个 LAN 中呢?我们有另一个选择。

暴力破解 DHCID 记录以绕过名称保护

DHCID 记录是在 RFC 4701中定义的,其算法相当简单:

  1. 将以下值连接起来:

    • DHCP HTYPE(硬件类型)。对于以太网,此值为 01。

    • DHCP 客户端 ID 选项

    • 记录 FQDN(DNS 有线格式

  2. 对结果进行 SHA256 加密

  3. 添加 DHCID 数据位(在 Windows 实施中,此值为常量)

  4. 以 Base64 对结果进行编码

图 23 显示了一个 DHCID 计算示例。

图 23 显示了一个 DHCID 计算示例。 图 23:DHCID 计算示例

由于我们知道 FQDN 和数据位是常量,因此唯一的变量是客户端 ID,它也是客户端的 MAC 地址。

DHCID 记录是正常的 DNS 记录,因此任何客户端都可以向 DNS 服务器查询其值。由于我们知道用于计算 DHCID 记录的算法,因此我们可以对所有可能的 MAC 地址进行迭代,计算器 DHCID 值并将每个结果与我们的目标记录进行比较。当我们找到匹配项时,我们便知道找到了正确的 MAC 地址。这让攻击者能够在合理的时间内对 MAC 地址进行暴力破解——使用现代的专用计算机只需要几天时间便能够破解 248 个可能的 MAC 地址。如果只使用通用供应商 ID,我们就可以显著缩短这一时间。此过程的示例如图 24 所示。

 如果只使用通用供应商 ID,我们就可以显著缩短这一时间。此过程的示例如图 24 所示。 图 24:删除受名称保护功能保护的 DNS 记录

所引用的代码 可用于根据指定的参数计算 DHCID 值。

名称保护的副作用缓解措施

DHCP 名称保护适用于托管记录:从本质上说,DHCP 服务器可以保护由它创建的记录不被任意的客户端修改。名称保护与客户端记录无关。

尽管如此,在某些情况下,名称保护仍然可以抵御对客户端记录的攻击。

如果已启用名称保护,则在更新 DNS 记录时,DHCP 服务器会要求提供 DHCID 记录。由于正常的 DNS 客户端不会创建 DHCID 记录,因此客户端记录没有相关的 DHCID 记录。出于此原因,通过 DHCP 服务器进行的任何更新客户端记录的尝试都会失败(图 25)。

任何从 DHCP 服务器更新客户端记录的尝试都会失败(图 25)。 图 25:当 DHCID 记录不存在时 DNS 更新失败

导致此问题的原因在于名称保护的实施方式。如果已启用名称保护,则在 DHCP 服务器发送 DNS 更新时,它会向该请求中添加一个前提条件字段。此字段指定了 DNS 服务器上的一些条件,只有这些条件得到满足时才会进行 DNS 更新。在图 26 中,我们可以看到 DHCP 服务器发送的 DNS 更新包含 DHCID 值的前提条件。

 在图 26 中,我们可以看到 DHCP 服务器发送的 DNS 更新包含 DHCID 值的前提条件。 图 26:DNS 更新的前提条件

这意味着,如果不存在匹配值,更新就会失败。由于客户端记录不应该具有 DHCID 记录,因此如果已启用名称保护,客户端记录就会免受 DHCP DNS 覆盖的影响,攻击者也就没办法绕过它。 应该如此

这并不是名称保护功能的真正作用,更像是它的一个副作用,因为根据定义,名称保护仅用于保护托管记录。尽管如此,由于我们刚才所说明的逻辑,它也可以保护客户端记录。但是,即使是这种意料之外的防御措施,攻击者也可以绕过它们。

要拯救的 DHCP 范围?

DHCP 服务器支持定义多个范围的功能。范围是 DHCP 可以租用的特定子网中定义的一组 IP 地址(图 27)。 

DHCP 服务器支持定义多个范围的功能。范围是 DHCP 可以租用的特定子网中定义的一组 IP 地址(图 27)。 图 27:DHCP 范围的示例

通过划分多个范围,可以更好地管理地址分配,还可以对不同的子网应用不同的策略。名称保护是可应用的策略之一,并且它是在范围级别上启用的,这意味着不同的范围可以具有不同的配置。

正如我们在本博文先前部分中所述,当我们尝试对客户端记录执行 DHCP DNS 覆盖时,我们会失败,因为地址租用来自 具有 名称保护的 DHCP 范围。但是,需要理解一件重要的事情:范围是一个 DHCP 术语。客户端记录不知道范围是什么,也未与任何范围相关联。

由于此原因,如果我们从已禁用名称保护的另一个范围租用了地址,则可以“绕过”此抵御措施。(如何从已禁用名称保护的另一个范围租用地址不在本博文的讨论范围内,但您可以查看 DHCP 中继选项

这意味着,即使服务器上的单个范围已禁用名称保护,攻击者也能够覆盖客户端记录(考虑到先前讨论的错误配置之一)。

DNS 凭据

可以在 DHCP 服务器上配置的另一项设置是 DNS 凭据。通过此设置,我们能够提供网域用户的凭据,并在创建和更新记录时,将此凭据提供给 DHCP 服务器而不是机器帐户使用(图 28)。

通过此设置,我们能够提供网域用户的凭据,并在创建和更新记录时,将此凭据提供给 DHCP 服务器而不是机器帐户使用(图 28)。 图 28:DHCP DNS 凭据配置

我们来回顾一下 DHCP 服务器安装在 DC 上的示例。在更新 DNS 记录时,使用的是 DC 机器帐户,该帐户拥有对区域中所有记录的相关权限。在配置了 DNS 凭据的情况下,可以改为使用一个弱帐户,这样攻击便不再有效。

配置 DNS 凭据很重要,因为它可以缩小 DHCP 服务器所暴露的攻击面。它应当能够抵御我们先前所介绍的极其严重的攻击。

但是,使用此功能时,您需要考虑两个细节:

  • 所配置的凭据必须是一个弱用户。例如,如果我们将其配置为网域管理员,则 DHCP 服务器仍然能够覆盖任意记录。

  • 由 DHCP 服务器创建的 DNS 记录的所有者仍然是同一凭据,并且仍然容易受到 DHCP DNS 覆盖的影响。

DNSUpdateProxy 组

在我们调查 Microsoft 的 DHCP 以及它与 DNS 的交互期间,我们发现了另一项可能被滥用的功能,即 DNSUpdateProxy 组。此组旨在解决托管记录的两个与权限相关的问题:客户端升级后的问题和多 DHCP 服务器问题。

客户端升级后的问题

我们先来思考一下客户端升级后的问题:旧版客户端最初使用 DHCP 服务器来注册 DNS 记录,但随后升级为支持 DNS 动态更新的新版操作系统。该客户端无法直接修改其记录,因为该记录的所有者是创建它的 DHCP 服务器。

为了解决此问题,可以将 DHCP 服务器添加到 DNSUpdateProxy 组中。

此组有两个作用:第一,当其成员创建 DNS 记录时,该记录的 ACL 将不同于正常托管记录—— Authenticated Users 组会获得对该记录的写入权限。这意味着,网域中的任何客户端都可以修改它(图 29)。

首先,当其成员创建 DNS 记录时,此记录的 ACL 与普通托管记录不同——经过身份验证的用户组被授予此记录的写入权限。这意味着,网域中的任何客户端都可以修改它(图 29)。 图 29:DNSUpdateProxy 记录 ACL

第二个作用是“记录接管”功能,第一个修改由某个 DNSUpdateProxy 成员创建的记录的客户端会被授予该记录的所有权,并移除已经过身份验证的用户的写入权限。通过允许客户端在必要时修改并接管它们自己记录,这解决了客户端升级后的问题。

多 DHCP 服务器问题

当需要多台 DHCP 服务器一起工作时,就会出现第二个问题。在此示例中,我们有两个 DHCP 服务器( DHCP1DHCP2),客户端 PC1 通过 DHCP1 注册 DNS 记录。

现在,假设 DHCP1 因为某种原因离线,我们开始使用 DHCP2。此客户端的租约到期,因此它联系 DHCP2 以获取新租约。当 DHCP2 出租新 IP 并尝试修改此客户端的 DNS 记录时,操作失败,因为该记录的所有者是 DHCP1(图 30)。

当需要多台 DHCP 服务器一起工作时,就会出现第二个问题。在此示例中,我们有两台 DHCP 服务器——DHCP1 和 DHCP2,客户端 PC1 通过 DHCP1 注册 DNS 记录 图 30:多台 DHCP 服务器设置示例

此问题仍然可以使用 DNSUpdateProxy 解决,因为此组具有一项附加功能。如果 DNSUpdateProxy 的某个成员尝试修改所有者是另一个成员的记录,则由于存在 ACL,更新将成功完成, 但这次 ACL 和所有权未发生更改。 这让多个服务器能够“共同拥有”记录。

安全风险和错误

到目前为止,您可能已了解 DNSUpdateProxy 组会带来安全风险:由此组中的成员创建的所有记录都可以被任何已经过身份验证的用户“窃取”。这不是漏洞,它只是对功能设计的滥用。Microsoft 已确认此风险。

除了此风险之外,我们还发现了另一个问题,该问题源自于似乎是 DNSUpdateProxy 功能实现中的错误。当此组中的成员创建 自己的 DNS 记录时,该记录会与同样容易受到影响的 ACL 一同创建,已经过身份验证的用户对其拥有写入权限。

图 31 显示了一个示例。我们的 DHCP 服务器 dhcp1.aka.test 记录最初拥有安全的 ACL。

图 31 显示了一个示例。DHCP 服务器“dhcp1.aka.test”的记录最初具有安全 ACL。 图 31:DHCP 服务器初始 ACL

我们可以看到该机器帐户拥有对它的相关权限,并且找不到 Authenticated Users 组。现在,我们将该服务器添加到 DNSUpdateProxy 组中并触发重新创建 DNS 记录。发生这种情况的原因有很多,例如服务器名称变更。重新创建 DNS 记录后,我们发现了新的 ACL(图 32)。

发生这种情况的原因有很多,例如服务器名称变更。重新创建 DNS 记录后,我们发现了新的 ACL(图 32)。 图 32:DHCP 服务器易受攻击的 ACL

我们看到网域用户现在拥有对新 DNS 记录的写入权限。这明显不是该功能的预期用途,由服务器创建的托管记录应该拥有经过修改的 ACL,但服务器自己的客户端记录不应该受到影响。

抵御 DHCP DNS 攻击

由很多与 DHCP DNS 动态更新相关的风险。我们来总结一下所有可能的不同服务器配置,并了解如何抵御先前介绍的攻击。

我们将谈到两种类型的记录,即由 DHCP 服务器创建的托管记录和由 Windows 客户端直接创建的客户端记录。

总结如下:

  • 如果您不需要 DHCP DNS 动态更新,请将其禁用

  • 如果您将弱用户配置为 DNS 凭据,则客户端记录应当是安全的

  • 无论采用什么配置,都无法保护托管记录免受欺骗攻击;在可能的情况下,将静态 DNS 记录 用于敏感的非 Windows 主机

  • 请勿使用 DNSUpdateProxy;改为在所有 DHCP 服务器中使用相同的 DNS 凭据

DNS 凭据

这是抵御针对客户端记录的 DHCP DNS 覆盖的最佳方法。使用高强度密码配置专用于此用途的弱用户。 如果您在 DC 上运行 DHCP 服务器,这一点至关重要。 此设置并非用于阻止对托管记录的 DHCP DNS 覆盖。

名称保护

从理论上来说,名称保护应该保护托管记录,但实际上攻击者可以很轻松地绕过它。但仍然应当启用此功能,以增加覆盖的难度。

虽然名称保护不适用于保护客户端记录,但如果对服务器的所有范围都启用了此功能,则仍然可以抵御覆盖攻击。

在 Microsoft DHCP 上配置名称保护时, 由两种方法来应用它:在服务器级别或在范围级别。有人可能认为,在服务器级别启用了名称保护就意味着在范围级别启用了名称保护,对吧?然而,事实并非如此。在服务器级别启用名称保护只能确保对服务器上创建的 范围启用该设置,但不会对现有的范围启用该设置。必须确认已在服务器上每个范围的范围级别上启用了名称保护。

DNSUpdateProxy

您不应该使用此组。它是一项安全风险,因为其成员创建的所有记录都容易被覆盖。

如果您有多个 DHCP 服务器并且希望它们一起工作,则应当改为使用 DNS 凭据。只需在所有 DHCP 服务器上配置相同的 DNS 凭据,这将允许它们相互编辑记录。

只有在您使用 Windows NT 4.0 客户端(或更低版本)并计划很快升级的情况下,DNSUpdateProxy 才有用。如果您有任何年代久远的客户端,那么您所面临的问题远比 DNSUpdateProxy 严重。

如果出于某种原因您必须使用 DNSUpdateProxy,我们建议您为每个组成员创建一条静态 DNS 记录。静态记录的所有者是其创建帐户,这应该不是不同服务器的机器帐户。这将阻止服务器创建它自己的具有不安全权限的记录。

DHCP DNS 欺骗

几乎没有方法可以阻止未经身份验证的攻击者创建不存在的 DNS 记录。唯一方法是在所有 DHCP 服务器上禁用 DHCP DNS 动态更新。通常,如果您的环境中不需要 DHCP DNS 动态更新功能,禁用此功能可能是个好主意。这将消除一些风险并帮助缩小攻击面。

利用 Invoke-DHCPCheckup 检测错误配置

为了帮助您遍历大量可能的 DHCP 配置,我们发布了一款名为 Invoke-DHCPCheckup 的 PowerShell 工具,用于确定与 DHCP DNS 动态更新相关的风险(图 33)。

为了帮助您遍历各种可能的 DHCP 配置,我们发布了一款名为“Invoke-DHCPCheckup”的 PowerShell 工具,用于识别与 DHCP DNS 动态更新相关的风险(图 33)。 图 33:Invoke-DHCPCheckup 输出示例

该攻击可以识别以下错误配置:

DNS 凭据

  • DNS 凭据未配置

  • 所配置的 DNS 凭据属于强用户

名称保护

  • 未对范围启用名称保护

  • 未对新范围默认启用名称保护

DNSUpdateProxy

  • 显示组成员 

  • 指定成员是否为 DHCP 服务器

弱记录 ACL

  • 所有者是 DHCP 服务器的列表记录(托管记录)

  • 可以被已经过身份验证的用户覆盖的列表记录

此攻击依赖于 DHCP 服务器管理 API 并需要强用户才能运行,因此该攻击主要面向蓝队。

总结

我们已将所有发现结果报告给 Microsoft,后者回应称上述所有问题要么是设计问题,要么未严重到实施修复的程度。

我们不太认同此说法。我们所强调的攻击影响可能非常严重——任由攻击者覆盖 DNS 记录而不进行任何身份验证,将使攻击者在网域中的主机上轻易获得“中间机”的位置。这很容易导致敏感信息和凭据泄露,还可以让攻击者实施中继攻击,从而入侵 AD 网域并升级特权。我们在本博文中分享的统计数据表明,对于很多数据中心网络来说此威胁是一个重大威胁。

由于 Microsoft 未计划修复这些问题,因此我们强烈建议防御者使用 Invoke-DHCPCheckup 来扫描自己的环境,尝试找到我们所强调的存在风险的配置。剧透告警——如果不更改默认配置,您很容易受到攻击。

关注最新动态

在后续博文中,我们将发布 DDSpoof (DHCP DNS 欺骗),该工具用于实施我们在本文中所述的全部攻击。我们将展示未经身份验证的攻击者如何执行以下操作:从 DHCP 服务器收集必要的数据、识别容易受影响的 DNS 记录、覆盖它们以及使用该能力入侵 AD 网域。



Ori David

寫於

Ori David

December 07, 2023

Ori David

寫於

Ori David

Ori David is a Security Researcher at Akamai. His research is focused on offensive security, malware analysis, and threat hunting.