一 前言
漏洞复现是在exchange server 2010 SP2中复现的,复现过程中,发现原作者给出获取用户SID的方法,在2010版本中并没有相关操作选项,所以作者给出的POC也就无法使用。不过后来在Github中找到一个POC。在该POC中,使用了一种反向委托的方法来获取用户SID,并利用这个POC成功复现了漏洞。
二 背景介绍
Microsoft Exchange Server 是个消息与协作系统。Exchange Server可以被用来构架应用于企业、学校的邮件系统或免费邮件系统。它还是一个协作平台。你可以在此基础上开发工作流,知识管理系统,Web系统或者是其他消息系统,是一个全面的Internet协作应用服务器,适合有各种协作需求的用户使用。
2.1 漏洞描述
在Microsoft Exchange Server中存在一个特权提升漏洞,该漏洞允许任何经过身份验证的用户冒充Exchange Server上的其他任意用户。漏洞产生的原因是由于在Exchange Server中使用NTLM身份验证时存在特定缺陷,服务器产生的NTLM响应可以反射回攻击者服务器,导致攻击者可以验证任意的EWS(Exchange Web服务)请求。
2.2 受影响的系统版本
Exchange Server 2010
Exchange Server 2013
Exchange Server 2016
2.3 漏洞编号
CVE-2018-8581
三、测试环境
Windows 2008 R2
Exchange Server 2010 SP2
四、漏洞复现
首先进行脚本参数配置。
在填好相关参数时,运行脚本。
然后再打开web界面执行相关操作。
输入目标(Administrator)邮箱后确定。
最终就成功代理了目标(Administrator)邮箱。
在代理成功后,可以接收目标邮箱的邮件收取,也可以对其邮件进行查看、删除等操作。
现在用mailtest2用户向目标(Administrator)邮箱发送一封邮件。
可以看到,代理用户成功接收到了由mailtest2用户向目标(Administrator)邮箱新发来的邮件。
如果想移除委托关系,可以将脚本中的FLAG改为0后运行。
Remove后再查看委托用户的邮箱。
五 漏洞利用流程及原理分析
为了能够让大家在分析漏洞时能够更加流畅,这里先介绍几个概念。
1、什么是SID?
SID全称为:Security Identifiers,是微软从Server2000时代引入的一个概念:安全标识符。在MicrosoftOS系统中(Server2000以上级别)工作组环境下:计算机、组、用户都会有自己的SID号,这些信息是存储在用户计算机本地注册表中的。这些SID号是根据其对象类型的不同随机生成的,具有一定的命名规则。简单来说,SID其实就是对象身份的象征。
2、什么是EWS?
EWS是微软实现的一种客户端和服务器之间的交换信息的协议。Exchange Server提供了包括从电子邮件、会议安排、团体日程管理、任务管理、文档管理、实时会议和工作流等丰富的协作应用。
3、NTLM认证概念、NTLM认证流程以及NTLM认证消息结构。
3.1 什么是NTLM认证?
NTLM认证简单来说就是一种在不直接提供密码的情况下,客户端间接向服务器证明知道用户的密码,从而达到认证目的的一种方法。
3.2 NTLM认证流程
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编码的。
举个例子:
概念介绍完,接下来开始分析漏洞利用流程及原理,通过POC来看,漏洞利用执行过程可分为四大步骤。
图一:总流程图
第一步:获取用户SID
获取用户SID的目的是为了后续构造SOAP头来冒充用户。
<t:EmailAddress>是攻击者邮箱地址,这里可以理解成委托方。
<t:PrimarySmtpAddress>是受害者邮箱地址,可以理解成被委托方。
该脚本是通过反向委托的方式来获取目标邮箱用户SID。通过向服务器发送一个将CONTROLLED_EMAIL 委托给 TARGET_MAIL的请求包,服务器就会返回TARGET_MAIL用户SID。
上图是代码执行流程,看代码可以发现,这部分有多次add和remove委托的行为。之所以这样重复请求,是为了防止发生意外错误。
上面说到Exchange Server添加委托操作的时候,服务器会返回被委托方(Target)的SID,但是当添加委托时,返回的数据包中如果包含ErrorDelegateAlreadyExists字符时,说明已经存在委托行为。
这时就需要先remove掉委托关系,然后再add,这样才能获取到用户SID。
第二步:请求推送订阅
推送订阅目的是将NTLM响应返回给攻击者服务器。
这部分是漏洞点所在,包括两个漏洞–SSRF和NTLM身份验证缺陷。
SSRF漏洞:攻击者可以使用一个已认证的邮箱账号发EWS发送推送订阅请求。(图中/EWS/Exchange.asmx是EWS请求的地址)。推送订阅时,Exchange允许用户自己指定URL,所以攻击者可以将这一URL改为自己的服务器地址。上图的EVIL_HTTPSERVER_URL就是攻击者自己的服务器。当这个推送订阅请求包发送到服务器时,服务器就会向攻击者指定的URL发送请求。
其中<t:URL>是SSRF的核心,跟踪一下服务器处理流程。
根据请求的Exchange.asmx文件以及请求内容,找一下Exchange Server的处理函数。
可以看到该类其中有一个关键的数据成员Url,下面跟踪一下该成员函数,看看哪里使用了该成员函数。
可以看到该Url被保存到PushSubScription的clientUrl中了。
跟踪发现该变量仅有三处使用。
主要的一处便是通过Http协议进行Notification消息发送的过程。
NTLM身份验证缺陷:在发送请求时,Exchange Server使用的是CredentialCache.DefaultCredentials进行连接:
并且CredentialCache.DefaultCredentials是以NT AUTHORITY\SYSTEM权限运行,这就会导致Exchange Server将服务器生成的NTLM响应发送到攻击者的服务器。Exchange Server默认情况下还设置了以下注册表项:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\DisableLoopbackCheck = 1
这就导致攻击者可以使用返回NTLM响应进行HTTP身份验证,从而可以验证任意EWS请求。
第三步:构造攻击数据包
由于CredentialCache.DefaultCredentials是以NT AUTHORITY\SYSTEM权限运行,所以攻击者可以与TokenSerializationRight进行“特权”会话,然后利用SOAP头部模拟任何想要伪装的用户。
使用一开始获取到的用户SID来构造SOAP头冒充受害者用户。
SOAP Body处构造的是委托请求的包,作用是目标邮箱的inbox收件箱将会委托于攻击者,这样就可以查看并修改目标邮箱的邮件。
第四步:NTLM认证及攻击
这里攻击者利用Python HTTPServer搭建一个简单的web服务器来作为自己的服务器,这个服务器其实是起到一个代理(中转)的作用。因为在NTLM认证证程中,它监听并响应着Exchange Server订阅功能发来的请求(请求中包含NTLM值),同时利用得到的NTLM响应值请求EWS,在这个过程中,它其实充当着就是一种像中间代理人一样的身份。我们可以把这个攻击者服务器称作代理服务器。
下面以Wireshark通信流量包来详细分析下NTLM的整个认证及攻击流程,大家可对照总流程(图一)的第四步骤来分析。
首先,攻击者在推送订阅后,Exchange Server的订阅功能会向代理服务器发送POST请求。
然后代理服务器会返回一个包含WWW-Authenticate:NTLM的header头并返回401状态(未认证)。
Exchange Server收到后,就会发送一个Negotiate 协商消息开始NTLM验证。
然后代理服务器会用这个Negotiate协商消息并带上relay_body(攻击包)去请求EWS。
接着,EWS就会返回Challenge挑战消息,然后代理服务器会将这个Challenge挑战消息响应回Exchange Server的订阅功能。
Exchange Server的订阅功能接收到后,就会对其加密,返回Authenticate认证消息给代理服务器。
然后,代理服务器返回了401状态。其实这个返回什么并不重要,因为我们目的是获取Authenticate认证消息。
最后代理服务器就会用这个获取到的Authenticate认证消息并带上relay_body(攻击包)去请求EWS,从而成功验证并完成攻击。
六 修复建议
手工修复:
删除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累计更新中,将不会再默认启动这一注册表项。
七 参考链接
https://github.com/WyAtu/CVE-2018-8581/
http://blog.51cto.com/popeyeywy/333556