LosFormatter一般也是用于序列化和反序列化Web窗体页的视图状态(ViewState),如果要把ViewState 通过数据库或其他持久化设备来维持,则需要采用特定的 LosFormatter 类来序列化/反序列化。它封装在System.Web.dll中,位于命名空间System.Web.UI下,微软官方的阐述是有限的对象序列化(LOS)格式专门为高度精简的ASCII格式序列化,此类支持序列化的任何对象图。但是使用反序列化不受信任的二进制文件会导致反序列化漏洞从而实现远程RCE攻击,本文笔者从原理和代码审计的视角做了相关介绍和复现。
LosFormatter类通常用于对ViewState页面状态视图的序列化,看下面实例来说明问题,首先定义TestClass对象
定义了三个成员,并实现了一个静态方法ClassMethod启动进程。 序列化通过创建对象实例分别给成员赋值
常规下使用Serialize得到序列化后的文件内容是Base64编码的
反序列过程是将Base64编码数据转换为对象,通过创建一个新对象的方式调用Deserialize方法实现的,查看定义如下
笔者通过创建新对象的方式调用Deserialize方法实现的具体实现代码可参考以下
反序列化后得到TestClass类的成员Name的值。
由于之前已经介绍了漏洞的原理,所以本篇就不再冗余的叙述,没有看的朋友请参考《.NET高级代码审计(第八课) SoapFormatter反序列化漏洞》,不同之处是用了LosFormatter类序列化数据,同样也是通过重写ISerializationSurrogate 调用自定义代码得到序列化后的数据
按照惯例用LosFormatter类的Deserialize方法反序列化就可以成功触发计算器。
由于笔者的windows主机打过了CVE-2017-8565(Windows PowerShell远程代码执行漏洞)的补丁,利用不成功,所以在这里不做深入探讨,有兴趣的朋友可以自行研究。有关于补丁的详细信息参考:
由于之前已经介绍了漏洞的原理,所以本篇就不再冗余的叙述,没有看的朋友请参考《.NET高级代码审计(第七课)NetDataContractSerializer反序列化漏洞》
从代码审计的角度找到漏洞的EntryPoint,Deserialize有两个重载分别可反序列化Stream和字符串数据,其中字符串可以是原始的Raw也可以是文档中说的Base64字符串,两者在实际的反序列化都可以成功。
下面是不安全的代码:
攻击者只需要控制传入字符串参数Content便可轻松实现反序列化漏洞攻击,完整的Poc如下
最后附上动态图效果
实际开发中LosFormatter 通常用在处理ViewState状态视图,同ObjectStateFormatter一样在反序列化二进制文件时要注意数据本身的安全性,否则就会产生反序列化漏洞。最后.NET反序列化系列课程笔者会同步到 https://github.com/Ivan1ee/ 、https://ivan1ee.gitbook.io/ ,更多的.NET安全和技巧可关注笔者的github。
本文作者:Ivan1ee
本文为安全脉搏专栏作者发布,转载请注明:https://www.secpulse.com/archives/104641.html