.NET高级代码审计(第九课) BinaryFormatter反序列化漏洞
原文来自安全客,作者:Ivan1ee@360云影实验室
原文链接:https://www.anquanke.com/post/id/176519
相关阅读:
- 《.NET 高级代码审计(第一课)XmlSerializer 反序列化漏洞》
- 《.NET 高级代码审计(第二课) Json.Net 反序列化漏洞》
- 《.NET高级代码审计(第三课)Fastjson反序列化漏洞》
- JavaScriptSerializer 反序列化漏洞》">《.NET高级代码审计(第四课) JavaScriptSerializer 反序列化漏洞》
- 《.NET高级代码审计(第五课) .NET Remoting反序列化漏洞》
- 《.NET高级代码审计(第六课) DataContractSerializer反序列化漏洞》
- 《.NET高级代码审计(第七课) NetDataContractSerializer反序列化漏洞》
- 《.NET高级代码审计(第八课)SoapFormatter反序列化漏洞》
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安全和技巧可关注实验室公众号。
本文经安全客授权发布,转载请联系安全客平台。
以上是 .NET高级代码审计(第九课) BinaryFormatter反序列化漏洞 的全部内容, 来源链接: utcz.com/p/199307.html