作者:雨夜
0x00前言
微软公布了一个反序列化代码执行漏洞,CVE-2021-42321,经过身份认证的攻击者可以通过EWS接口将payload写入UserConfiguration中,并通过GetClientAccessToken触发payload从而在目标服务器上执行代码。本篇通过对POC的跟踪分析漏洞的利用过程。
漏洞影响:
Microsoft Exchange Server 2019 CU10/CU11
Microsoft Exchange Server 2016 CU21/CU22
分析环境:
Server 2016
Exchange 2016 CU21 (由CU15升级到CU21)
0x01补丁查看
https://www.catalog.update.microsoft.com/Search.aspx?q=exchange%202016%20cu21
KB5007012 是在10月份发布的,通过两个补丁的对比查看修改了哪些文件。
使用Telerik 对比KB5007409、KB5007012 的不同,一共有几百个不同的DLL文件,为了快速找到漏洞点,搜索反序列化的关键字
Microsoft.Exchange.Compliance.dll中发现删除了几个class,
可以看到 TypedBinaryFormatter、TypedSerializationFormatter、TypedSoapFormatter这几个class里有反序列化的操作,同时在最新补丁中被删除。
0x02漏洞分析
网上已有payload,我们就利用payload分析漏洞的整个利用过程
dnSpy设置断点,附加到进程 w3wp.exe的MSExchangeServicesAppPool 中(如果不知道是哪个进程,可以将所有的w3wp.exe进程全部附加进去)
使用ysoserial构造反序列化数据,gadget 使用 TypeConfuseDelegate
运行payload,断点停住
调用堆栈如下:
漏洞调用链
进入LoadMasterTable,解析UserConfiguration 的信息(UserConfiguration可以通过EWS接口操作)
通过 参数 configName,configType,folderId获取对应配置信息
参数值如下
接着进入Microsoft.Exchange.Data.ApplicationLogic.Extension.OrgExtensionSerializer 类中对userConfiguration进行反序列化操作
Microsoft.Exchange.Data.ApplicationLogic.Extension.OrgExtensionSerializer
首先将配置信息实例化成一个 stream对像,
Microsoft.Exchange.Data.ApplicationLogic.Extension.OrgExtensionSerializer
其中formatter是IClientExtensionCollectionFormatter的实例化对象,
调用IClientExtensionCollectionFormatter.Deserialize函数
Microsoft.Exchange.Data.ApplicationLogic.Extension.ClientExtensionCollectionFormatter
接着将steam内容传入TypeBinaryFormatte.DeserializeObject中,执行反序列化
Microsoft.Exchange.Compliance.Serialization.Formatters.TypedBinaryFormatter
调用 TypeBinaryFormatter类的Deserialize 方法,创建一个ChainedSerializationBinder对象
Microsoft.Exchange.Diagnostics.ExchangeBinaryFormatterFactory
传入allowList参数是一个白名单列表,内容如下:
白名单中允许使用System.DelegateSerializetionHolder
ChainedSerializationBinder实现方法如下
Microsoft.Exchange.Diagnostics.ChainedSerializationBinder
其中定义了一个gadget黑名单列表,包含了常用的gadget
但由于开发者的失误,导致其中一个gadget黑名单没有生效,正确的写法是System.Security.Claims.ClaimsPrincipal ,所以我们可以利用这个gadget进行反序列化攻击。
objectReader初始化后,调用ObjectReade.Deserialize方法
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
接着会有一个白名单和黑名单的验证,如果不合法直接抛出异常
Microsoft.Exchange.Diagnostics. ChainedSerializationBinder
验证通过后,经过一系列操作进入System.Collections.Generic.SortedSet.OnDeserialization中,获取array的值并进行Add操作
System.Collections.Generic.SortedSet.OnDeserialization
在Add函数里,会对array中的两个元素进行Compare(System.Collections.Generic.ComparisonComparer)操作
Compare的过程中会调用System.Diagnostics.Process创建进程,从而执行命令。
payload分析:
利用EWS(Exchange Web Service微软提供的一个访问Exchange资源的接口)写入用户配置信息,写入的时候将payload写进去;写入前需要先将旧的配置信息删掉,删除的时候需要传入参数folderId的值; 这个值可以通过 GetFolder 获取 ;最后利用GetClientAccessToken 触发反序列化
1) GetFolder
2) DeleteUserConfiguration
3) CreateUserConfiguration(写入生成的序列化数据)
从官方文档可知 UserConfigurationType有5中类型,由于反序列化数据是流式的,所以使用BinaryData。
运行结果如下:
注:另一个gadget,System.Security.Claims.ClaimsPrincipal经过测试也是可用的。
0x03解决方案
微软已经针对该漏洞发布了补丁,补丁链接:https://www.microsoft.com/en-us/download/details.aspx?id=103645
0x04参考链接:
https://gist.github.com/testanull/0188c1ae847f37a70fe536123d14f398
https://docs.microsoft.com/zh-cn/exchange/client-developer/web-service-reference/userconfiguration
微信公众号搜索“云影实验室”。
顺便插下招聘广告,安全研究员2名和安全开发工程师1名,有意者可以私信公众号。
发表评论
您还未登录,请先登录。
登录