.NET高级代码审计(第12课)反序列化Gadget之详解ObjectDataProvider
0X01 背景
有国外研发者在微软官方Github上提出废除ObjectDataProvider的建议,大家在微软社区讨论的非常热烈,提出问题者的出发点依旧是存在巨大的安全隐患,但截止目前在.NET Core3.1版本依然可用。不出意外的话?辩论将会继续持续下去,不妨碍我们先分析一波原理??
建议没有前置知识的同学先看一看之前的课程《.NET高级代码审计(第一课)XmlSerializer反序列化漏洞》,接着再来细品 ysoserial 给出的XmlSerializer反序列化漏洞攻击载荷,大伙可能会有疑问这段XAML代码为什么会以这样的形式存在?究竟背后的原因是怎样的,带着这些问题我们一步步的来剖析解密。
cmd
/c calc
]]>
0X02 数据源入门
WPF (全称:Windows Presentation Foundation) 是用于替代Windows Form来创建Windows客户端应用程序,WPF开发过程中主要有以下几种数据绑定方法,这些对象可以视为数据源绑定到控件
名称 | 类型 |
ADO.NET | DataTable |
XML | XmlDataProvider |
Element | ElementName |
Object | ObjectDataProvider |
前两个XML数据源和数据库对象数据源这里不详细展开,重点关注元素数据源和对象数据源 , 首先看元素数据源使用场景,下面代码示例使用 xmlns:local ="clr-namespace:ObjectDataProvider" 绑定当前运行的APP程序的命名空间,注意这里的 namespace ObjectDataProvider不是类,只是笔者创建项目的命名空间名称,有关更多的XAML知识笔者单独详细介绍,这里不做展开,例如笔者在后端.cs文件中创建Employee类定义了姓名、年龄、性别
在WPF中所有的控件都有一个共同的属性DataContext,便于将同一个对象多个属性绑定到不同的元素上。例如下XAML代码
0X03 ObjectDataProvider用法
上面小节介绍了后端类和前端XAML简单的配合使用,接下来讲解反序列化漏洞里的核心Gadget:ObjectDataProvider,顾名思义就是把一个非静态类实例化后的对象作为数据源提供给绑定,大概是这样的:ObjectDataProvider对象的ObjectInstance属性是类的实例化对象(obj),MethodName属性为obj的方法,其中方法中还可以含有参数MethodParamers。基本用法如下代码启动计算器
ObjectDataProvider obj = new ObjectDataProvider();
obj.MethodParameters.Add("calc");
obj.MethodName = "Start";
obj.ObjectInstance = new System.Diagnostics.Process();
但是在实际研发更多使用在XAML文件中,微软官方给出文档说ObjectDataProvider可以在XAML使用并创建对象数据源
ObjectDataProvider enables you to create your object in XAML and make it available as a binding source. It provides the following properties that enable you to execute a query on your object and bind to the results.
如下代码
上图中笔者在后端C#代码里定义DataAccess类,类中定义GetEmp()用来补位性别信息,再将补全的数据返回。举这个案例笔者想表达出ObjectDataProvider在实际开发中典型的应用,帮助更好说明它的使用场景,另外ObjectDataProvider 提供的ConstructorParameters 属性支持对类的构造方法初始化传值,如下代码 在XAML中对后端QueryData类构造方法中的Application属性赋值,启动记事本
notepad
通过上述实际案例的讲解,想必读者朋友都能对ysoserial生成的攻击载荷有更深的认知,类比看可用 Window.Resource 或者比窗口级别更上层的 Application.Resource 替代载荷里提供的ResourceDictionary。接下来我们再看一看ResourceDictionary是干什么的?
0X04 ResourceDictionary资源集合
其实每个控件都有Resource属性,但通常都是定义再窗口级别上,例如Window.Resource,Resource属性存储了一个资源字典集合,资源集合里可以放置任意类型的对象,为了增加对资源文件的可维护性,WPF提供了ResourceDictionary对资源进行分类和汇总,实际开发中为了方便多个项目共同使用一个字典而打造的资源集合,如图添加资源字典
calc
资源中也可引入XAML名称空间,例如上述代码配置Process类为了实例化的对象,调用Start方法启动计算器。另外可使用 MergedDictionaries属性指定外部的 Resource文件合并嵌入,只需在文件中添加如下内容
分析下来资源字典
"calc"
0X05 结语
ObjectDataProvider常用于WPF项目,大伙遇到Windows桌面应用时代码审计的重点关注XAML是否可写,若可读可写就能实现命令执行。说了这么多我们有必要回过头来看看XAML语法,请大伙继续关注下一节《.NET高级代码审计(第13课) 反序列化Gadget之详解XAML》,文章涉及的PDF和Demo已打包发布在星球,扫码左侧二维码进入星球,扫码右侧二维码关注dotNet安全矩阵公众号,欢迎对.NET安全关注和关心的同学加入我们,在这里能遇到有情有义的小伙伴,大家聚在一起做一件有意义的事。本文首发于dotNet安全矩阵公众号:https://mp.weixin.qq.com/s/sHKR0zlW2CsphGAmv3_KVA