1.ClaimsPrincipal
也即这条链子
问题出在这个
OnDeserializedMethod
方法,有
[OnDeserialized]
特性,反序列化过程中会触发
这里把
m_serializedClaimsIdentities
传入
DeserializeIdentities()
方法,触发BinaryFormatter反序列化
2.DataSetOldBehaviour
一个和DataSet有关的链子,在学习这个链子之前,我们先小小的复习一下DataSet链,我们之前分析过,DataSet链的构造函数会调用到
DeserializeDataSet()
我们当时是跟进
DeserializeDataSetSchema()
方法,里面有个binaryformatter反序列化
然而另一个
DeserializeDataSetData()
我们没有分析
注意到这个ReadXml()方法的调用,这里从info中取出XmlDiffGram变量的值并最终传入ReadXml()方法,这里后续的调用栈比较复杂,我们可以下一个Deserialize函数断点:
这里会在XmlSerializer()的Deserialize()方法断住,也就是说ReadXml()里面其实是有
XmlSerializer().Deserialize()
反序列化漏洞点的
调用堆栈如下:
所以可以把XmlSerializer的payload放到info的XmlDiffGram变量中去,就是DataSetOldBehaviour链子了。
然后DataSetOldBehaviourFromFile就相当于是一个更自由的gadget,允许用户加载自定义的cs或者dll文件,本质上也还是DataSetOldBehaviour链子
3.GenericPrincipal
这个类继承了ClaimsPrincipal,并且没有实现OnDeserializedMethod
刚好我们前面介绍过ClaimsPrincipal实现了OnDeserializedMethod,So,GenericPrincipal反序列化过程中触发这个方法,这里会对
m_serializedClaimsIdentities
进行BinaryFormatter反序列化
4.ResourceSet链
这个反序列化链子也很有意思,因为涉及到用HashTable做中转。这个要说回TypeConfuseDelegate。以前做这个链子的时候都是用的SortedSet,但是其实还可以再封装一层,封装到HashTable的键中。然后对HashTable进行反序列化的过程中,对HashTable里的键名or键值也会进行反序列化,就可以触发SortedSet的OnDeserialization走完RCE
补充完这个信息,我们再来看ResourceSet链就非常好理解了
注意ResourceSet的Table属性,刚好就是Hashtable类型,在反序列化还原ResourceSet的同时也会触发Hashtable的反序列化,进而走通整个链子
所以我们来写写链子,这个ResourceSet的构造函数要传一个*.resource文件进行初始化,不知道对内容和格式有啥要求,而且这个Table是protected。总之这俩我都是反射获取的。另外这里纠正自己一直以来的一个坏习惯,从PHP和JAVA那边转过来之后,一直习惯把面向对象里的变量统一称为属性(
.NET这边,有get或set,并且Dnspy显示蓝绿色的才是属性,其余紫色的没有get或set都叫字段就行,之前其实也知道这一点,不过说顺口了一直没改。这里还是规范一下比较好,不然想让GPT帮忙生成一些反射取值改值的代码的时候总是会出现一些奇奇怪怪的问题,有时候还得自己debug,因为反射获取字段:
FieldInfo tableField = resourceSetType.GetField("table", BindingFlags.NonPublic | BindingFlags.Instance);
和反射获取属性:
PropertyInfo tableProperty = resourceSetType.GetProperty("table", BindingFlags.NonPublic | BindingFlags.Instance);
是不一样的写法,还是要注意(
总之,我们来试试搓一下ResourceSet链
运行,成功RCE
5.XamlAssemblyLoadFromFile链
其实就是利用Xaml去调用CreateInstance等一系列方法,去进行任意代码执行,用户只需要传入想执行的cs文件和dll即可,算是自由度更高的TypeConfuseDelegate链
6.总结
至此,我们就学习完了ysoserial.net中除了TypeConfuseDelegateMono链以外的所有反序列化链和大部分反序列化点
PS:本来还想说学完了所有反序列化点,不过这两天又细看了一下ysoserial.net,发现还有一些点:
MessagePackTypeless >= 2.3.75
MessagePackTypelessLz4 >= 2.3.75
SharpSerializerBinary
SharpSerializerXml
YamlDotNet
看来还能出几期,并且ysoserial.net的各种plugins也值得学习分析一下,回头再看吧,.NET内存马相关的文章也写了几期,感兴趣的读者可以多关注本系列