作者:天融信阿尔法实验室
公众号:天融信阿尔法实验室

0x00前言

近日,Microsoft公告中披露了一则关于Exchange Server的任意用户伪造漏洞,天融信阿尔法实验室对此漏洞进行了复现及分析。漏洞复现是在Exchange server 2010 SP2中进行的,复现过程中,发现原作者给出获取用户SID的方法,在2010版本中并没有相关操作选项,所以作者给出的POC也就无法使用。不过后来在Github中找到一个POC。在该POC中,使用了一种反向委托的方法来获取用户SID,并利用这个POC成功复现了漏洞。

0x01背景介绍

Microsoft Exchange Server 是个消息与协作系统。Exchange Server可以被用来构架应用于企业、学校的邮件系统或免费邮件系统。它还是一个协作平台。你可以在此基础上开发工作流,知识管理系统,Web系统或者是其他消息系统,是一个全面的Internet协作应用服务器,适合有各种协作需求的用户使用。

1.1漏洞描述

在Microsoft Exchange Server中存在一个特权提升漏洞,该漏洞允许任何经过身份验证的用户冒充Exchange Server上的其他任意用户。漏洞产生的原因是由于在Exchange Server中使用NTLM身份验证时存在特定缺陷,服务器产生的NTLM响应可以反射回攻击者服务器,导致攻击者可以验证任意的EWS(Exchange Web服务)请求。

1.2受影响的系统版本

Exchange Server 2010 

Exchange Server 2013 

Exchange Server 2016 

1.3漏洞编号

CVE-2018-8581

0x02测试环境

Windows 2008 R2

Exchange Server 2010 SP2

0x03漏洞复现

首先进行脚本参数配置。

640

在填好相关参数时,运行脚本。

640-1

然后再打开web界面执行相关操作。

640-4

输入目标(Administrator)邮箱后确定。

640(3)

最终就成功代理了目标(Administrator)邮箱。

在代理成功后,可以接收目标邮箱的邮件收取,也可以对其邮件进行查看、删除等操作。

现在用mailtest2用户向目标(Administrator)邮箱发送一封邮件。

640(4)

640(5)

可以看到,代理用户成功接收到了由mailtest2用户向目标(Administrator)邮箱新发来的邮件。

如果想移除委托关系,可以将脚本中的FLAG改为0后运行。

640

640(6)

Remove后再查看委托用户的邮箱。

640(1)

0x04漏洞利用流程及原理分析

为了能够让大家在分析漏洞时能够更加流畅,这里先介绍几个概念。

1、什么是SID?

SID全称为:Security Identifiers,是微软从Server2000时代引入的一个概念:安全标识符。在MicrosoftOS系统中(Server2000以上级别)工作组环境下:计算机、组、用户都会有自己的SID号,这些信息是存储在用户计算机本地注册表中的。这些SID号是根据其对象类型的不同随机生成的,具有一定的命名规则。简单来说,SID其实就是对象身份的象征。

2、什么是EWS?

EWS是微软实现的一种客户端和服务器之间的交换信息的协议。Exchange Server提供了包括从电子邮件、会议安排、团体日程管理、任务管理、文档管理、实时会议和工作流等丰富的协作应用。

2、NTLM认证概念、NTLM认证流程以及NTLM认证消息结构。

3.1什么是NTLM认证?

NTLM认证简单来说就是一种在不直接提供密码的情况下,客户端间接向服务器证明知道用户的密码,从而达到认证目的的一种方法。

3.2 NTLM认证流程

640(7)

3.2.1 客户端如果试图访问服务器资源,首先会向服务器发送协商消息。在发送的请求中会包含一个以明文表示的用户名。

3.2.2 服务器接收到请求后会生成一个16byte的随机数,并返回给客户端。这个随机数被称为Challenge或者Nonce。

3.2.3 客户端在接收到服务器返回的Challenge后,会使用当前登录用户的密码哈希值对其加密,生成Authenticate认证消息,然后将Authenticate发送给服务器。

3.2.4 服务器接收到客户端发送回来的Authenticate后,会向DC(Domain)发送针对客户端的验证请求。该请求主要包含以下三方面的内容:客户端用户名,客户端Authenticate和原始的Challenge。

3.2.5 DC根据用户名获取该帐号的密码哈希值,对原始的Challenge进行加密。如果加密后的Challenge和服务器发送的一致,则意味着用户拥有正确的密码,验证通过,否则验证失败。DC将验证结果发给服务器,并最终反馈给客户端。

3.3 NTLM 认证消息的结构

Negotiate协商消息、Challenge挑战消息和Authenticate认证消息,他们的结构很相似:NTLMSSPXXXXXXXXXX。其中NTLMSSP表示是NTLM验证的请求。但是在实际中,NTLMSSPXXXXXXXXXX是经过base64编码的。

举个例子:

640(2)

概念介绍完,接下来开始分析漏洞利用流程及原理,通过POC来看,漏洞利用执行过程可分为四大步骤。

图一:总流程图

第一步:获取用户SID

获取用户SID的目的是为了后续构造SOAP头来冒充用户。

640(9)

是攻击者邮箱地址,这里可以理解成委托方。

是受害者邮箱地址,可以理解成被委托方。

该脚本是通过反向委托的方式来获取目标邮箱用户SID。通过向服务器发送一个将CONTROLLED_EMAIL 委托给 TARGET_MAIL的请求包,服务器就会返回TARGET_MAIL用户SID。

640(10)

640(11)

640(12)

上图是代码执行流程,看代码可以发现,这部分有多次add和remove委托的行为。之所以这样重复请求,是为了防止发生意外错误。

上面说到Exchange Server添加委托操作的时候,服务器会返回被委托方(Target)的SID,但是当添加委托时,返回的数据包中如果包含ErrorDelegateAlreadyExists字符时,说明已经存在委托行为。

640(13)

这时就需要先remove掉委托关系,然后再add,这样才能获取到用户SID。

第二步:请求推送订阅。

640(14)

640-3

640(4)

640(15)

推送订阅目的是将NTLM响应返回给攻击者服务器。

这部分是漏洞点所在,包括两个漏洞--SSRF和NTLM身份验证缺陷。

SSRF漏洞:攻击者可以使用一个已认证的邮箱账号发EWS发送推送订阅请求。(图中/EWS/Exchange.asmx是EWS请求的地址)。推送订阅时,Exchange允许用户自己指定URL,所以攻击者可以将这一URL改为自己的服务器地址。上图的EVIL_HTTPSERVER_URL就是攻击者自己的服务器。当这个推送订阅请求包发送到服务器时,服务器就会向攻击者指定的URL发送请求。

640(5)

其中是SSRF的核心,跟踪一下服务器处理流程。

根据请求的Exchange.asmx文件以及请求内容,找一下Exchange Server的处理函数。

640(6)

640(16)

可以看到该类其中有一个关键的数据成员Url,下面跟踪一下该成员函数,看看哪里使用了该成员函数。

640(17)

640 (18)

可以看到该Url被保存到PushSubScriptionclientUrl中了。

跟踪发现该变量仅有三处使用。

640(19)

主要的一处便是通过Http协议进行Notification消息发送的过程。

640(20)

640(21)

NTLM身份验证缺陷:在发送请求时,Exchange Server使用的是CredentialCache.DefaultCredentials进行连接:

640(22)

并且CredentialCache.DefaultCredentials是以NT AUTHORITY\SYSTEM权限运行,这就会导致Exchange Server将服务器生成的NTLM响应发送到攻击者的服务器。Exchange Server默认情况下还设置了以下注册表项:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\DisableLoopbackCheck = 1

640(23)

这就导致攻击者可以使用返回NTLM响应进行HTTP身份验证,从而可以验证任意EWS请求。

第三步:构造攻击数据包

640(24)

由于CredentialCache.DefaultCredentials是以NT AUTHORITY\SYSTEM权限运行,所以攻击者可以与TokenSerializationRight进行“特权”会话,然后利用SOAP头部模拟任何想要伪装的用户。

使用一开始获取到的用户SID来构造SOAP头冒充受害者用户。

SOAP Body处构造的是委托请求的包,作用是目标邮箱的inbox收件箱将会委托于攻击者,这样就可以查看并修改目标邮箱的邮件。

第四步:NTLM认证及攻击

640(25)

640(26)

这里攻击者利用Python HTTPServer搭建一个简单的web服务器来作为自己的服务器,这个服务器其实是起到一个代理(中转)的作用。因为在NTLM认证证程中,它监听并响应着Exchange Server订阅功能发来的请求(请求中包含NTLM值),同时利用得到的NTLM响应值请求EWS,在这个过程中,它其实充当着就是一种像中间代理人一样的身份。我们可以把这个攻击者服务器称作代理服务器。

下面以Wireshark通信流量包来详细分析下NTLM的整个认证及攻击流程,大家可对照总流程(图一)的第四步骤来分析。

首先,攻击者在推送订阅后,Exchange Server的订阅功能会向代理服务器发送POST请求。

640(27)

然后代理服务器会返回一个包含WWW-Authenticate:NTLM的header头并返回401状态(未认证)。

640(7)

640(28)

Exchange Server收到后,就会发送一个Negotiate 协商消息开始NTLM验证。

640(29)

然后代理服务器会用这个Negotiate协商消息并带上relay_body(攻击包)去请求EWS。

640(30)

640(31)

接着,EWS就会返回Challenge挑战消息,然后代理服务器会将这个Challenge挑战消息响应回Exchange Server的订阅功能。

640(32)

Exchange Server的订阅功能接收到后,就会对其加密,返回Authenticate认证消息给代理服务器。

640(33)

640(34)

然后,代理服务器返回了401状态。其实这个返回什么并不重要,因为我们目的是获取Authenticate认证消息。

最后代理服务器就会用这个获取到的Authenticate认证消息并带上relay_body(攻击包)去请求EWS,从而成功验证并完成攻击。

640(8)

640(9)

0x05漏洞修复

手工修复:

删除HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\DisableLoopbackCheck键值

在管理员权限的命令行窗口中,输入如下命令:

reg delete HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa /v DisableLoopbackCHECK /f

在删除键值后,无需重新启动操作系统,也无需重新启动Exchange Server。

官方补丁:

Microsoft在2018年11月发布了补丁,但该补丁仅对该漏洞进行了缓解,并没有进行严格意义上的修复。不过Microsoft发布的公告指出,在此后Exchange累计更新中,将不会再默认启动这一注册表项。

0x06参考链接

  1. https://www.zerodayinitiative.com/blog/2018/12/19/an-insincere-form-of-flattery-impersonating-users-on-microsoft-exchange
  2. https://github.com/WyAtu/CVE-2018-8581/
  3. http://blog.51cto.com/popeyeywy/333556
  4. https://www.cnblogs.com/shuidao/p/3634637.html
  5. https://www.cnblogs.com/artech/archive/2011/01/25/NTLM.html

Paper 本文由 Seebug Paper 发布,如需转载请注明来源。本文地址:https://paper.seebug.org/804/