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

admin 2022年10月9日12:39:04评论358 views字数 4359阅读14分31秒阅读模式

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

引言

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

影响范围

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

大约是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();

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

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

反序列化触发点

C:Program FilesMicrosoftExchange ServerV15BinMicrosoft.Exchange.Compliance.dll中的Microsoft.Exchange.Compliance.Serialization.Formatters.TypedBinaryFormatter的DeserializeObject方法:

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

传入SerializationBinder实例但没有被使用

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

通过CreateBinaryFormatter生成BinaryFormatter对象:

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

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

此时传入的参数为:

strictMode = false

allowList = "System.DelegateSerializationHolder"

allowedGenerics = null

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

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

进入ValidateTypeToDeserialize函数

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

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

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

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

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

此时flag=this.strictMode为false:

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

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

触发反序列化

寻找使用DeserializeObject函数的地方:

DotNet安全-CVE-2021-42321漏洞复现ClientExtensionCollectionFormatter没找到相关的调用,查看继承的接口在哪里实现:
DotNet安全-CVE-2021-42321漏洞复现

发现TryDeserialize方法:

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

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

Microsoft.Exchange.Data.Storage.UserConfiguration:

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

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

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

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

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

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

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

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

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

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

Gadgates

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

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

Bypass Windows Definder

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

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

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

测试

ysoserial.exe -g TypeConfuseDelegate -f BinaryFormatter -o base64 -c "1" -t
DotNet安全-CVE-2021-42321漏洞复现

成功生成文件

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

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

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

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

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

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

修复

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

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

此处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


原文始发于微信公众号(7bits安全团队):DotNet安全-CVE-2021-42321漏洞复现

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2022年10月9日12:39:04
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   DotNet安全-CVE-2021-42321漏洞复现https://cn-sec.com/archives/1338736.html

发表评论

匿名网友 填写信息