ProxyLogon 漏洞分析

简介

ProxyLogon 是Orange披露的Exchange Server的RCE漏洞。它包含两个漏洞CVE-2021-26855(SSRF)和CVE-2021-27065(任意文件写入)。由于这个漏洞不需要认证,所以危害性极大。

漏洞效果:RCE -> SYSTEM权限

漏洞产品:Exchange Server

复现环境

笔者这里搭建了ExchangeServer 2016 CU12进行漏洞复现。操作系统为Windows Server 2016。

影响范围

影响范围过于大,总的来说是没有低于Mar21SU(2021年3月) patch的都会受影响。详细列表的可以查看 MSRC官网

Exchange Server介绍

架构介绍

据Orange博客里介绍,Exchange Server经历了几个大版本的改变,架构也改变了多次。2016/2019的架构基本一致,本文简单来分析一下2016/2019的架构

Exchange 2016/2019主要包含两个部分(Mailbox Rule和Edge Transport Role)。其中Edge Transport Role主要和外网收发邮件有关,不是本文分析的重点。本文主要关注MailBox Role。MailBox Rule也包含两部分: Client access services(以下简称CAS)和Backend Services(以下简称Backend)。其中CAS负责处理用户侧的协议,包括HTTP/POP3/IMAP4/SMTP。后端实现真正的业务逻辑。

这里HTTP协议的前端和后端都部署在了IIS上面。他们分别监听在不同的端口。CAS监听在80和443端口,BackEnd监听在81和444端口。他们都是可以外网访问到的。但是Backend会进行权限检查,只会处理Exchange Server的机器账号的请求。

HTTP Proxy相当于一个反向代理。

漏洞原理

SSRF(CVE-2021-26855)

这里从HTTP请求的开始进行分析。CAS模块的反向代理是ProxyModuleProxyModule选择哪一个handler进行处理的函数是OnPostAuthorizeInternal。httphandler的选择是通过SelectHandlerForUnauthenticatedRequestSelectHandlerForAuthenticatedRequest进行。httphandler选择完成之后就会调用Run方法进行真正的处理。

我们首先看怎么选择的Handler。SelectHandlerForUnauthenticatedRequest函数中是一系列的if条件判断。首先判断的是HttpProxyGlobals.ProtocolType的值,在ecp进程中,该值为ProtocolType.Ecp。这个值是通过配置文件静态设置的,不可以根据http请求改变。在Ecp请求中,主要有3类,出现漏洞的是BEResourceRequestHandler。

BEResourceRequestHandler会调用CanHandle函数判断这个handler能否处理这个请求。一共有两个判断。首先判断BEResource的Cookie值是否设置。

然后调用IsResourceRequest函数判断请求的路径是否属于资源类。例如.js,.jpg,.png等等。如果这两个条件都满足就返回true。

确定了httphandler之后,CAS会调用BeginProxyRequest函数进行反向代理。代理的地址通过GetTargetBackEndServerUrl得到。Host直接从AnchoredRoutingTarget.BackEndServer.Fqdn赋值。

AnchoredRoutingTarget.BackEndServer是通过调用虚函数ResolveAnchorMailbox实现的。ResolveAnchorMailbox方法在BEResourceRequestHandler类中也定义了。如果BEResourceCookie存在的话,就调用BackEndServer.FromString创建一个BackEndServer实例。

FromString方法对input字符串以字符“~”进行分割,然后传入BackEndServer的构造函数。
分隔的两部分直接赋值给了FqdnVersion

最后调用CreateServerRequest创建反向HTTP链接。

PrepareServerRequest还会生成一个机器账户的kerberos ticket,放在HTTP的AuthorizationHeader头中。BackEnd会检测HTTP请求的权限,只有机器账户发出的HTTP请求才会得到处理。

到这就实现了一个SSRF漏洞。造成这个漏洞的根因在于可以通过控制Cookie里的BEResource字段控制反向代理的Host地址。

任意文件写入(CVE-2021-27065)

这里直接放出现问题的地方: 在WriteFileActivity类中可以直接把inputvariable的值写入OutputFileNameVariable制定的文件中。由于没有对文件路径进行检查,故存在任意文件写的漏洞。

下面我们来看如何触发这里。

/ecp/VDirMgmt下可以设置ExternalURL,内容可以用户控制

然后使用reset oab功能可以指定备份的路径。如下,这里指定备份在了C盘的aaa文件里。

点击reset之后,可以看到aaa文件被创建成功。

这里可以选择在exchange server的web目录创建一个webshell。
external URL就会作为文件的一部分内容写进去。

至于为啥调用reset oab这个功能就会触发WriteFileActivity。笔者找到了如下的线索:ecp/DDI目录下有非常多的xaml文件。这应该是通过.NET的Workflow框架实现的功能。xaml文件定义了workflow的每一个步骤。其中ResetResetOABVirtualDirectory.xaml文件就定义了为实现reset oab功能所需要的activities。其中第二步就是调用了WriteFileActivity

利用效果

运行exploit后执行whoami命令,可以看到输出了nt authority\system

引用