CommonsCollections1反序列化漏洞点研究

CommonsCollections1反序列化漏洞点

Ysoserial中Payload CommonsCollections1反序列化漏洞点仍然是commons-collections-3.1版本包中的InvokerTransformer类(org.apache.commons.collections.functors.InvokerTransformer)的transform方法,并且在LazyMap(org.apache.commons.collections.map.LazyMap)的get方法中调用了Transformer(org.apache.commons.collections.Transformer)的transform方法,最终即可调用InvokerTransformer的transform方法触发漏洞:


而get方法可通过sun.reflect.annotation.AnnotationInvocationHandler做动态代理时的invoke方法调用,只需要把memberValue属性设置为LazyMap即可:


触发漏洞的入口为sun.reflect.annotation.AnnotationInvocationHandler的readObject方法,从payload的getObject方法也可以看出这一点,最终返回的就是AnnotationInvocationHandler(Gadgets.createMemoizedInvocationHandler函数返回的):


再仔细观察该payload,在createMemoizedInvocationHandler函数中调用了AnnotationInvocationHandler的newInstance方法,将mapProxy设置成了其memberValues属性:



在CommonsCollections1.java中可以看出给最终返回的AnnotationInvocationHandler设置的memberValues属性的mapProxy实际上是通过Gadgets.createMemoitizedProxy函数创建出来的一个动态代理,而该动态代理又是一个AnnotationInvocationHandler:

反序列化入口是AnnotationInvocationHandler的readObject方法,在执行this.memberValues.entrySet函数时即触发AnnotationInvocationHandler的invoke方法:


再继续看payload,payload把LazyMap的factory属性设置为了ChainedTransformer:


ChainedTransformer中存在一个iTransformers属性包含一个Transformers数组,payload依次设置为以下五个:


然后在执行transform函数时就会依次调用这五个transformer的transform函数,从而利用反射执行Runtime.exec函数:

因此整个漏洞触发的调用栈为:

AnnotationInvocationHandler.readObject

 AnnotationInvocationHandler.invoke

LazyMap.get

  ChainedTransformer.transform

    InvokerTransformer.transform

      Runtime.exec

版本影响及修补手段

查阅文档发现在CommonsCollections的3.2.2和4.1版本中因为ysoserial的CommonsCollections1和CommonsCollections2的两个漏洞禁止了不安全类的反序列化(不安全类不再实现Serializable接口),比如上面的InvokerTransformer:


因此3.2.2版本就会导致CommonsCollections1的payload失效,而经过实验3.2.1、3.2、3.1版本都是有效的,并不是ysoserial介绍说明的该payload仅支持3.1版本:


对于有效jdk的版本,ysoserial在代码中要求jdk版本<=1.8u71:


但是实际测试时发现1.8u71是会报错的,最多支持到1.8u66

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容