长亭百川云 - 文章详情

DotNet安全-CVE-2021-42321漏洞复现

7bits安全团队

110

2024-07-13

DotNet安全-CVE-2021-42321漏洞复现

引言

该漏洞主要是由于开发者使用SerializationBinder后的逻辑判断有问题,同时配合exchange不那么严格的反序列化黑名单,造成了认证后的RCE。

影响范围

大约是21年下半年更新的exchange2016及2019。

基础知识

了解SerializationBinder:

using System;  
using System.Collections.Generic;  
using System.Linq;  
using System.Text;  
using System.Threading.Tasks;  
using System.IO;  
using System.Runtime.Serialization;  
using System.Runtime.Serialization.Formatters.Binary;  
   
   
namespace deserialDemo  
{  
    class Program  
    {  
        static void Main(string[] args)  
        {  
            BinaryFormatter binaryFormatter = new BinaryFormatter();  
            MemoryStream memoryStream = new MemoryStream();  
            RCE calc = new RCE("calc");  
            binaryFormatter.Serialize(memoryStream, calc);  
   
            memoryStream.Position = 0;  
            binaryFormatter.Binder = new MyBinder();  
            object v = binaryFormatter.Deserialize(memoryStream);  
            Console.WriteLine(v);  
            Console.ReadKey();  
   
        }  
    }  
    [Serializable]  
    class RCE  
    {  
        public string cmd;  
   
        public RCE(string cmd)  
        {  
            this.cmd = cmd;  
        }  
   
        public override string ToString()  
        {  
            return $"exec cmd:{cmd}";  
        }  
    }  
    class MyBinder : SerializationBinder  
    {  
        public override Type BindToType(string assemblyName, string typeName)  
        {  
            Console.WriteLine($"assemblyName:{assemblyName},typeName:{typeName}.");  
            Type typeToDeserialize = Type.GetType(String.Format("{0}, {1}", typeName, assemblyName));  
   
            if (typeToDeserialize.Equals(typeof(RCE)))  
            {  
                Console.WriteLine("can't deseriliza rce class.");  
                throw new Exception("error");  
            }  
            return typeToDeserialize;  
        }  
    }  
}

在MyBinder 里实现具体逻辑,判断即将要被反序列化的类的Type-typeToDeserialize是否等于typeof(RCE)。

在反序列化之前,设置binaryFormatter.Binder = new MyBinder();

尝试反序列化,被阻止,弹出异常:

反序列化触发点

C:\Program Files\Microsoft\Exchange Server\V15\Bin\Microsoft.Exchange.Compliance.dll中的Microsoft.Exchange.Compliance.Serialization.Formatters.TypedBinaryFormatter的DeserializeObject方法:

传入SerializationBinder实例但没有被使用

通过CreateBinaryFormatter生成BinaryFormatter对象:

其中初始化的时候指定了Binder,为ChainedSerializationBinder函数的结果:

此时传入的参数为:

strictMode = false

allowList = "System.DelegateSerializationHolder"

allowedGenerics = null

ChainedSerializationBinder重写了父类SerializationBinder的BindToType和BindToName方法

进入ValidateTypeToDeserialize函数

!this.strictMode=true 此时默认情况为真。

this.allowedTypesForDeserialization.Contains(text) 此时allowedTypesForDeserialization是我们传入的"System.DelegateSerializationHolder",text为即将被反序列化的类的类名。

ChainedSerializationBinder.GlobalDisallowedTypesForDeserialization为反序列化的黑名单:

此时flag=this.strictMode为false:

此时抛出的BlockedDeserializationException 异常会被捕获,因为flag=false,整个ChainedSerializationBinder不会抛出异常。因此可以造成不在黑名单中的任意类的反序列化。如果进入InvalidOperationException就会直接进入异常,不会进入反序列化的逻辑。

触发反序列化

寻找使用DeserializeObject函数的地方:

ClientExtensionCollectionFormatter没找到相关的调用,查看继承的接口在哪里实现:

发现TryDeserialize方法:

发现来自UserConfiguration,在exchange2010的反序列化漏洞中通过ews设置账户属性进行触发。这里我们只要找到一个属性可以设置为binary的地方就可能触发。

Microsoft.Exchange.Data.Storage.UserConfiguration:

可以看到UserConfiguration的类型有xml形式:

接下来就是怎么通过ews设置用户设置,主要是如何传递二进制的问题,网上已经有人审计的ews找到了解决办法,在我们前面的文章也提及过如何找到xml对应的类:

设置完反序列化之后需要触发:

通过获取用户ExtesionDataList触发,通过ews调用此接口:

至此我们获得了完整的利用链。

Gadgates

TypeConfusedDelegate、ClaimsPrincipal及ActivitySurrogateSelector ,这三个链没有在这个版本exchange的黑名单中。ActivitySurrogateSelector 可以直接执行dll文件,但在exchange上会报错。

关于反序列化链的研究以后的文章再详细分析。

Bypass Windows Definder

实际在利用的过程中遇到的500错误,之前朋友在利用的时候遇到过,应该是w3wp进程启动进程被Definder拦截了。这样的话只要修改ysoserial的代码功能为写文件即可利用。

关于如何绕过definder阻止启动新进程的方式,以后会有相关的文章专题。

测试

ysoserial.exe -g TypeConfuseDelegate -f BinaryFormatter -o base64 -c "1" -t

成功生成文件

前面修改了以下poc xml中的ExtensionMasterTable就发现漏洞不能顺利触发,能创建配置但调用会失败。

在最终利用的地方Microsoft.Exchange.Data.ApplicationLogic.Extension.OrgExtensionSerializer的TryDeserialize函数中,要被反序列化的实例userConfiguration的configName为ExtensionMasterTable:

反序列化触发已经限制死了配置名为ExtensionMasterTable的配置。

修复

  KB5007409得到修复,最终反序列化的地方:

此处this.formatter为IClientExtesionCollectionFormatter的实现,仅剩Microsoft.Exchange.Data.ApplicationLogic.Extension.ClientExtensionCollectionFormatter.Deserialize(Stream) : Collection

POC及修改过的ysoseial.net

https://github.com/DarkSprings/CVE-2021-42321 https://github.com/7BitsTeam/exch\_CVE-2021-42321

参考:

https://peterjson.medium.com/some-notes-about-microsoft-exchange-deserialization-rce-cve-2021-42321-110d04e8852

相关推荐
关注或联系我们
添加百川云公众号,移动管理云安全产品
咨询热线:
4000-327-707
百川公众号
百川公众号
百川云客服
百川云客服

Copyright ©2024 北京长亭科技有限公司
icon
京ICP备 2024055124号-2