小白学源码审计-7-.NET反序列化漏洞

原创 时间 2017-09-15  慕小白 神月资讯

本文是ASP.NET反序列化漏洞的相关介绍。在PHP反序列化漏洞文章已经简单介绍过了序列化与反序列化的基本概念,最近抽空学习了一下.Net反序列化,于是简单总结一下学习到知识,首先简单介绍一下什么是序列化:

0x01 前言

序列化是将对象处理为字节流的方式以便通过数据库、文件、网络方式传递与保存对象等。其主要目的是保存对象的状态保证数据易于存储和传输,以便可以在需要时重新创建对象。序列化的反过程称为反序列化,目的是将流恢复为对象。

                           

微信图片_20170915162420.jpg

0x02 序列化与反序列化

.NET提供了多种反序列化方法,本文简单介绍一下XML序列化。

XML序列化

使用该序列化用到的类为System.Xml.Serialization.XmlSerializer。该反序列化过程可以注意的特点如下:

  1. 反序列化过程会调用反序列化类的构造器。

  2. 反序列化类为成员赋值时会调用setter方法,因此setter可以作为利用链的入口。

  3. 反序列化过程只能控制公共成员。

  4. 使用System.Xml.Serialization.XmlSerializer进行序列化的类不需要声明Serializable标识,因此可以利用的Gadget范围就变大了。

0x03 Gadget

Gadget,顾名思义就是用来协助我们从调用setter方法到代码执行的工具类。

System.Windows.Data.ObjectDataProvider

要实现任意代码执行,主要依靠的就是该类。该类中的三个成员(MethodNameObjectTypeObjectInstance)在调用setter方法时,会判断MethodName方法参数是否足够,足够则执行该方法。

通过这个类可以实现:

  1. 调用非默认构造方法。

  2. 所有不带参数的公共实例方法。

  3. 所有带可控参数的公共方法(包括静态、实例)。

比如执行以下代码:

微信图片_20170915162444.jpg

执行后,即调用了Evil类中EvilMethod方法,参数为par

这样,利用链第一步可以调用某类中某成员setter方法,通过使用ObjectDataProvider这个Gadget即转变为可调用某类中的方法。

0x04 缺陷代码示例

为了方便理解,编写了一个常见的简化例子。

程序员使用XmlSerializer进行反序列化,反序列化的类型与数据用户可控。以下是代码,应该非常容易理解,用于接收用户提交的参数为xml、反序列化类型参数为type,使用该两者进行反序列化。

微信图片_20170915162457.jpg

我们的目的是通过各种类构造利用链最终实现在反序列化过程调用Process.Start(“calc”),即弹出计算器,利用链并不是直接通过ObjectDataProvider直接调用Process类的Start方法即可完成,而需要调用XamlReaderParse方法,间接调用Process类的Start方法,以下是最终payload

提交的XML参数值:

微信图片_20170915162507.jpg

提交的Type参数值:

微信图片_20170915162548.jpg

直接提交,即可弹出计算器。

微信图片_20170915162552.jpg

可以看到,使用XmlSerializer进行反序列化时,类型用户可控即可直接实现代码执行。

例子:DotNetNuke (CVE-2017-9822),该CMScookie接收序列化的信息,反序列化的类型用户可控,与上述例子想当接近。

参考链接:

https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-JSON-Attacks-wp.pdf#page=33

0x05 防护建议

  1. 使用XmlSerializer进行反序列化时,预先定义可反序列化的类型,不可以接收用户传入的类型进行反序列化。

微信图片_20170915162603.jpg


<<上一篇下一篇>>