这是 Exchange 反序列化漏洞分析系列的第一篇。这篇文章先来分析一下 CVE-2021-42321,为下一篇 CVE-2022-23277 做铺垫。
2021.10.16-10.17,天府杯上爆出漏洞 CVE-2021-42321。2021.11.8,微软发布 KB5007409 修复该漏洞。之后,安全研究人员通过 diff 2021.10.11 的 KB5007012 和 2021.11.8 的 KB5007409 两个补丁分析出 CVE-2021-42321 exp,确定该漏洞为反序列化漏洞。
Exchange Server 2016 CU22 <= Oct21SU 15.1.2375.12 15.01.2375.012
Exchange Server 2016 CU21 <= Oct21SU 15.1.2308.15 15.01.2308.015
Exchange Server 2019 CU11 <= Oct21SU 15.2.986.9 15.02.0986.009
Exchange Server 2019 CU10 <= Oct21SU 15.2.922.14 15.02.0922.014
CU21/CU22 是 Exchange 2016 当时最新的两个累积更新版本,增加了一些新功能,正是这些功能引入了新的反序列化触发点,导致漏洞产生。也正是因为如此,CVE-2021-42321 只影响这四个特定的版本。
1.普通用户权限2./ews
可用
`ysoserial.exe -g TypeConfuseDelegate -f BinaryFormatter -c calc -t -o base64``ysoserial.exe -g ClaimsPrincipal -f BinaryFormatter -c calc -t -o base64`
两条链都行,生成的数据替换 CVE-2021-42321中的 gadgetData。
从 Exchange 某个版本开始(2016 CU16?),微软加入了 ChainedSerializationBinder
类作为过滤器来过滤恶意反序列化类,其内置了一些黑名单,并通过 ValidateTypeToDeserialize(type)
函数在反序列化时检查目标反序列化类是否合法。要使用 ChainedSerializationBinder
,只需在创建 Formatter
时,将其 Binder
属性设为 ChainedSerializationBinder
即可。
众所周知,黑名单过滤可能会存在被绕过的风险,有趣的是,CVE-2021-42321 并非直接针对黑名单的巧妙绕过,而是利用了 Exchange 开发者的两个低级失误:
1. 初始化 Formatter
的 Binder
属性时,将一个恶意类置入了白名单,导致内置的黑名单过滤失效。
2. ChainedSerializationBinder
黑名单中某个类拼写错误,导致内置的黑名单过滤失效。
上面介绍了恶意链的存在,但 Exchange 中更难确定的是如何找到反序列化的触发点。这需要站在更高一层的视角审视漏洞,脱离代码、熟悉架构、理解业务,才更容易发掘出正常功能点中产生反序列化的点。CVE-2021-42321 通过 userConfiguration
触发反序列化,其格式为标准的 .Net 二进制序列化数据。用户可以控制自己的 UserConfiguration
,且需通过 /ews
接口设置 UserConfiguration
,因此才有上述两个条件。
下面来看两个开发失误导致两条 Gadgets 链产生的具体细节。
在 ChainedSerializationBinder.ValidateTypeToDeserialize(Type typeToDeserialize)
处下断点,打 Poc,堆栈如下:
关键点在 ClientExtensionCollectionFormatter.Deserialize()
,它通过 TypedBinaryFormatter.DeserializeObject(serializationStream, ClientExtensionCollectionFormatter.TypeBinder)
来反序列化数据:
DeserializeObject()
在反序列化前需要先 CreateBinaryFormatter()
创建 BinaryFormatter
并设置 ChainedSerializationBinder
:
问题在于设置 Formatter
的 Binder
时,传入了 TypedBinaryFormatter.allowedTypes
作为白名单,该白名单包含了 System.DelegateSerializationHolder
:
System.DelegateSerializationHolder
本来位于黑名单 ChainedSerializationBinder.GlobalDisallowedTypesForDeserialization
列表中,由于同时被加入了白名单,导致可以利用该类构造 Gadgets 链,完成 RCE。
这条链就很离谱了,开发人员把类名写错了,System.Security.ClaimsPrincipal
的正确写法应该是 System.Security.Claims.ClaimsPrincipal
:
对于前者,ClientExtensionCollectionFormatter.Deserialize()
改为使用 ExchangeBinaryFormatterFactory.CreateBinaryFormatter()
创建 Formatter
再反序列化数据,并且其 allowedTypes
设为空,而不是直接使用 TypedBinaryFormatter
,甚至直接删除了 TypedBinaryFormatter
类。
对于后者,直接改为正确的类名。
CVE-2021-42321 是由于开发者失误,导致产生了两条可以绕过黑名单的反序列化链,漏洞的难点在于如何寻找反序列化的触发点。
虽然该漏洞被修复了,但黑名单过滤的方式总会存在被绕过的可能。毕竟,由于反序列化漏洞的高度灵活性,其能够造成的危害不仅是 RCE,也可以是 XXE,配合上中继,在 Windows 环境下可能发挥意想不到的效果。
https://github.com/DarkSprings/CVE-2021-42321
https://gist.github.com/testanull/0188c1ae847f37a70fe536123d14f398
https://cxsecurity.com/issue/WLB-2022030008
【最新漏洞预警】CVE-2021-42321-天府杯Exchange 反序列化漏洞分析
Some notes about Microsoft Exchange Deserialization RCE (CVE-2021–42321): https://peterjson.medium.com/some-notes-about-microsoft-exchange-deserialization-rce-cve-2021-42321-110d04e8852
Microsoft Exchange 11 月补丁分析: https://blog.khonggianmang.vn/phan-tich-ban-va-thang-11-cua-microsoft-exchange/