ReadElementContentAsBase64()
ApplyTransforms()
DeflateCookieTransform
ProtectedDataCookieTransform
如果我们在前文提到的ApplyTransforms()方法下一个断点,可以看到这里会进行一个解密操作,依次调用DeflateCookieTransform和ProtectedDataCookieTransform的Decode()方法进行解密
现在就可以拼凑出payload的生成流程,把BinaryFormatter的payload依次调用DeflateCookieTransform和ProtectedDataCookieTransform的Encode()方法进行加密,然后再调用一次base64编码。把最终的结果放在<Cookie>节点内。这里来看看ysoserial.net的实现方法:
注意Cookie节点,其值来源于:
也就是我们前面说的流程,这里测试一下,可以成功实现命令执行
不过这里其实有个问题,插件的源码里也写明白了,这个反序列化点在实战里是基本没有利用空间的:
这是因为ProtectedDataCookieTransform依赖DPAPI进行加密解密操作,当能接触到这玩意的时候,基本都进入后渗透流程了,确实基本没有必要再利用这个点
不过,后续我基于这个反序列化点又找了一个有点相似的反序列化点,利用的可能性要大上不少,我还把它做成了一个新的ysoserial.net插件,留到下一篇文章来细说。
2.TransactionManagerReenlist
这个安全问题源于下面这个方法
TransactionManager.Reenlist()
接受一个Guid类型的数据,一个byte[]类型的数据,还需要传入一个实现了IEnlistmentNotification接口的对象
这个方法一上来先是把recoveryInformation形参传入BinaryReader(),那接下来要干啥不用我多说了吧,不过在后面是要从序列化数据中读取一些信息的,所以不能用原始的BinaryFormatter payload,这也是这个插件要实现的功能
再往后看,这里发现序列化数据进入ReenlistTransaction()方法
跟进ReenlistTransaction()方法
数据又进入
oletxResourceManager.Reenlist()
继续跟进
典中典的BinaryFormatter反序列化点,因此我们来看看ysoserial.net是如何生成序列化payload的,其实只需要简单的修饰一下原始payload就行:
主要是为了满足上面提到的这块的判断:
还是比较易懂的,这里就不多介绍了,简单测试一下:
实战中可以多关注是否有TransactionManager.Reenlist()方法的调用,若有,其第二个形参是否可控,若可控则可以实现RCE