.NET高级代码审计(第九课) BinaryFormatter反序列化漏洞

阅读量    37893 |

分享到: QQ空间 新浪微博 微信 QQ facebook twitter

 

作者:Ivan1ee@360云影实验室

0x00 前言

BinaryFormatter和SoapFormatter两个类之间的区别在于数据流的格式不同,其他的功能上两者差不多,BinaryFormatter位于命名空间 System.Runtime.Serialization.Formatters.Binary它是直接用二进制方式把对象进行序列化,优点是速度较快,在不同版本的.NET平台里都可以兼容。但是使用反序列化不受信任的二进制文件会导致反序列化漏洞从而实现远程RCE攻击,本文笔者从原理和代码审计的视角做了相关介绍和复现。

 

0x01 BinaryFormatter序列化

使用BinaryFormatter类序列化的过程中,用[Serializable]声明这个类是可以被序列化的,当然有些不想被序列化的元素可以用[NoSerialized]属性来规避。下面通过一个实例来说明问题,首先定义TestClass对象

定义了三个成员,并实现了一个静态方法ClassMethod启动进程。 序列化通过创建对象实例分别给成员赋值

常规下使用Serialize得到序列化后的二进制文件内容打开后显示的数据格式如下

 

0x02 BinaryFormatter反序列化

2.1、反序列化用法

反序列过程是将二进制数据转换为对象,通过创建一个新对象的方式调用Deserialize多个重载方法实现的,查看定义可以看出和SoapFormatter格式化器一样实现了IRemotingFormatter、IFormatter接口

我们得到系统提供的四个不同的反序列方法,分别是Deserialize、DeserializeMethodResponse、UnsafeDeserialize、UnsafeDeserializeMethodResponse。笔者通过创建新对象的方式调用Deserialize方法实现的具体实现代码可参考以下

反序列化后得到TestClass类的成员Name的值。

2.2、攻击向量—ActivitySurrogateSelector

由于上一篇中已经介绍了漏洞的原理,所以本篇就不再冗余的叙述,没有看的朋友请参考《.NET高级代码审计(第八课) SoapFormatter反序列化漏洞》,两者之间唯一的区别是用了BinaryFormatter类序列化数据,同样也是通过重写ISerializationSurrogate 调用自定义代码,笔者这里依旧用计算器做演示,生成的二进制文件打开后如下图

按照惯例用BinaryFormatter类的Deserialize方法反序列化

计算器弹出,但同时也抛出了异常,这在WEB服务情况下会返回500错误。

2.3、攻击向量—WindowsIdentity

有关WindowsIdentity原理没有看的朋友请参考《.NET高级代码审计(第二课) Json.Net反序列化漏洞》,因为WindowsIdentity最终是解析Base64编码后的数据,所以这里将Serializer后的二进制文件反序列化后弹出计算器

 

0x03 代码审计视角

3.1、UnsafeDeserialize

从代码审计的角度找到漏洞的EntryPoint,相比Deserialize,UnsafeDeserialize提供了更好的性能,这个方法需要传入两个必选参数,第二个参数可以为null,这种方式不算很常见的,需要了解一下,下面是不安全的代码:

攻击者只需要控制传入字符串参数path便可轻松实现反序列化漏洞攻击。

3.2、UnsafeDeserializeMethodResponse

相比DeserializeMethodResponse,UnsafeDeserializeMethodResponse性能上更加出色,这个方法需要传入三个必选参数,第二和第三个参数都可为null,这种方式也不算很常见,只需要了解一下,下面是不安全的代码:

3.3、Deserialize

Deserialize方法很常见,开发者通常用这个方法反序列化,此方法有两个重载,下面是不安全的代码

3.4、DeserializeMethodResponse

相比Deserialize,DeserializeMethodResponse可对远程方法响应提供的Stream流进行反序列化,这个方法需要传入三个必选参数,第二和第三个参数都可为null,这种方式也不算很常见,只需要了解一下,下面是不安全的代码:

最后用这个方法弹出计算器,附上动图

 

0x04 总结

实际开发中BinaryFormatter 类从.NET Framework 2.0开始,官方推荐使用BinaryFormatter来替代SoapFormatter,特点是BinaryFormatter能更好的支持泛型等数据,而在反序列化二进制文件时要注意数据本身的安全性,否则就会产生反序列化漏洞。最后.NET反序列化系列课程笔者会同步到 https://github.com/Ivan1ee/https://ivan1ee.gitbook.io/ ,后续笔者将陆续推出高质量的.NET反序列化漏洞文章,欢迎大伙持续关注,交流,更多的.NET安全和技巧可关注实验室公众号。

分享到: QQ空间 新浪微博 微信 QQ facebook twitter
|推荐阅读
|发表评论
|评论列表
加载更多