1.前言
水点二次反序列化链的分析,.NET里的二次反序列化链绝大部分都比较简单,很容易就能跟完,适合新手师傅入门学习。Y4er师傅是把下面一些链子和ObjectStateFormatter绑起来一块介绍的,这个我打算留到后面分析ViewState反序列化的时候在细看,审计里还是关注ObjectStateFormatter类的Deserialize()传参是否可控就行。
2.ToolboxItemContainer链
也即ysoserial.net里的这个gadget
看看这个链又是什么情况,这个链子的sink点主要是在ToolboxItemContainer类的内部类ToolboxItemSerializer
这个类的反序列化构造方法,从info里获取AssemblyName变量和Stream变量,随后调用BinaryFormatter类的Deserialize进行反序列化操作,内容我们可控(array)
也就是说这是一个和DataSet链差不多的二次反序列化链,还是可以借助 TextFormattingRunProperties 去打
主要是将SetType设置为ToolboxItemSerializer内部类,info里的Stream变量设置为 TextFormattingRunProperties 链子的payload即可
具体代码可以参考
https://xz.aliyun.com/t/9594
或者ysoserial.net的实现,在Dataset的基础上魔改其实就可以了
3.RolePrincipal链
也即这个链
这个链子的命名是真抽象,我一开始以为它只和RolePrincipal类有关,然而实际上这个链子是RolePrincipal的父类ClaimsPrincipal的链子
其反序列化构造方法把info传入本类的Deserialize()方法,该方法会对info里的变量做遍历,当有一个变量叫做
System.Security.ClaimsPrincipal.Identities
的时候,会获取其值并传入DeserializeIdentities方法
跟进这个方法也是能看到一个显而易见的binaryformatter反序列化点
链子搓起来也简单,给info里加一个
System.Security.ClaimsPrincipal.Identities
值为base64编码后的 TextFormattingRunProperties 链内容即可
4.WindowsPrincipal链
介绍这个之前还是来介绍一下.NET Formatter反序列化的一些特性,和JAVA那边还是挺像的。简单来说在java那边readObject()方法的调用有个特性,比如说我一个A类里有一个属性test,属性类型为B类。而B类也实现了readObject(),那么在对A进行反序列化,重建test属性的时候,会触发B类的readObject(),在.NET这边也是一样,把readObject()换成反序列化构造方法即可:
如图,A类里有一个BProperty属性,为B类对象。而B类实现了反序列化构造函数,尝试对A类进行序列化与反序列化
此时B类的反序列化构造方法触发,对于JAVA比较熟悉的师傅对这个肯定没啥疑问。
有了这个前置知识点就可以来看看WindowsPrincipal链。WindowsPrincipal类里有一个m_identity属性,类型为WindowsIdentity
而WindowsIdentity我们并不陌生,在前面的文章里我们已经介绍过,这个类的反序列化构造函数实际上调用其父类的反序列化构造函数,而其父类的反序列化构造函数又有二次反序列化点。
所以我们把这个字段赋值为一个恶意的WindowsIdentiity对象就行。这里我们又可以学到一个思路,就是就算一个普通的类的反序列化构造方法以及其它相关方法里没有敏感操作。但是当这个类中有一个属性,属性类型是另一个敏感类,而敏感类的反序列化构造方法中存在敏感操作时,我们依然可以用这个普通的类去延续链子。
5.参考
https://xz.aliyun.com/t/9598