利用链整理
- URLDNS
- 限制:无
- source
- java.util.HashMap
- CommonCollections1
- 说明
- Java 8u71之后的高版本修复了AnnotationInvocationHandler
- 限制
- <Java 8u71
- commons-collections:3.1
- source
- sun.reflect.annotation.AnnotationInvocationHandler
- LazyMap.get()
- 说明
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | Gadget chain: ObjectInputStream.readObject() AnnotationInvocationHandler.readObject() Map(Proxy).entrySet() AnnotationInvocationHandler.invoke() LazyMap.get() ChainedTransformer.transform() ConstantTransformer.transform() InvokerTransformer.transform() Method.invoke() Class.getMethod() InvokerTransformer.transform() Method.invoke() Runtime.getRuntime() InvokerTransformer.transform() Method.invoke() Runtime.exec() |
- CommonsCollections6
- 说明
- CC1高版本无法使用,AnnotationInvocationHandler无法再调用LazyMap.get(),CC6通过org.apache.commons.collections.keyvalue.TiedMapEntry实现LazyMap.get()调用,从而绕过限制。
- 限制
- commons-collections:<=3.2.1
- source
- java.util.HashSet
- LazyMap.get()
- java.util.HashSet
- 说明
1 2 3 4 5 6 7 8 9 10 11 12 | java.io.ObjectInputStream.readObject() java.util.HashSet.readObject() java.util.HashMap.put() java.util.HashMap.hash() org.apache.commons.collections.keyvalue.TiedMapEntry.hashCode() org.apache.commons.collections.keyvalue.TiedMapEntry.getValue() org.apache.commons.collections.map.LazyMap.get() org.apache.commons.collections.functors.ChainedTransformer.transform() org.apache.commons.collections.functors.InvokerTransformer.transform() java.lang.reflect.Method.invoke() java.lang.Runtime.exec() |
- CommonsCollections3
- 说明
- 如SerialKiller等工具添加了反序列化黑名单,最初的黑名单过滤了CC1中的InvokerTransformer,CC3中使用InstantiateTransformer替换,绕过黑名单限制,其他构造和CC1基本一样。
- CC6是基于CC1改的,所以可以基于CC3增加一个CC6的新利用链
- 限制
- <Java 8u71
- commons-collections:<=3.2.1
- source
- sun.reflect.annotation.AnnotationInvocationHandler
- LazyMap.get()
- 说明
- CommonsCollections2
- 说明
- CC2使用和之前利用链不同的commons-collections4版本,可以根据新版本调整CC1/3/6,但CC2找了只有该版本有的新利用链。
- 利用链中的关键类org.apache.commons.collections4.comparators.TransformingComparator在老版本是没实现Serializable
- 限制
- commons-collections4:4.0
- source
- java.util.PriorityQueue
- TransformingComparator.compare()
- java.util.PriorityQueue
- 说明
1 2 3 4 5 6 7 8 9 | Gadget chain: ObjectInputStream.readObject() PriorityQueue.readObject() ... TransformingComparator.compare() InvokerTransformer.transform() Method.invoke() Runtime.exec() |
- CommonsCollections4
- 说明
- 这里CC4是基于CC2改的,将InvokerTransformer替换成InstantiateTransformer,这个操作可以类比CC3基于CC1的修改
- 限制
- commons-collections4:4.0
- source
- java.util.PriorityQueue
- TransformingComparator.compare()
- java.util.PriorityQueue
- 说明
- CommonsCollections5
- 说明
- source选择了BadAttributeValueExpException,后半部分和CC1是一样的
- 限制
- This only works in JDK 8u76 and WITHOUT a security manager
- commons-collections:<=3.2.1
- source
- javax.management.BadAttributeValueExpException
- LazyMap.get()
- javax.management.BadAttributeValueExpException
- 说明
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | Gadget chain: ObjectInputStream.readObject() BadAttributeValueExpException.readObject() TiedMapEntry.toString() LazyMap.get() ChainedTransformer.transform() ConstantTransformer.transform() InvokerTransformer.transform() Method.invoke() Class.getMethod() InvokerTransformer.transform() Method.invoke() Runtime.getRuntime() InvokerTransformer.transform() Method.invoke() Runtime.exec() |
- CommonsBeanutils1
- 说明
- CC2和CC4中找到4.0版本中的TransformingComparator#compare来构造利用链,而CB1中使用org.apache.commons.beanutils.BeanComparator#compare来触发
- 限制
- commons-beanutils:commons-beanutils:1.9.2
- commons-collections:commons-collections:3.1
- commons-logging:commons-logging:1.2
- source
- java.util.PriorityQueue
- org.apache.commons.beanutils.BeanComparator#compare
- org.apache.commons.collections.comparators.ComparableComparator
- org.apache.commons.beanutils.BeanComparator#compare
- java.util.PriorityQueue
- 说明
- CommonsBeanutils2
- 说明
- commons-beanutils版本换成1.8.2而已
- 限制
- commons-beanutils:commons-beanutils:1.8.2
- commons-collections:commons-collections:3.1
- commons-logging:commons-logging:1.2
- source
- java.util.PriorityQueue
- org.apache.commons.beanutils.BeanComparator#compare
- org.apache.commons.collections.comparators.ComparableComparator
- org.apache.commons.beanutils.BeanComparator#compare
- java.util.PriorityQueue
- 说明
- CommonsBeanutilsNoCC
- 说明
- 基于CB链改造,原来的是CB链是需要依赖commons-collections:commons-collections:3.1中的ComparableComparator,这里找到jdk自带的java.lang.CaseInsensitiveComparator替换,增强的该链的兼容性。
- 限制
- commons-beanutils:commons-beanutils:1.8.2或1.9.2
- commons-logging:commons-logging:1.2
- source
- java.util.PriorityQueue
- org.apache.commons.beanutils.BeanComparator#compare
- java.lang.CaseInsensitiveComparator
- org.apache.commons.beanutils.BeanComparator#compare
- java.util.PriorityQueue
- 说明
- CommonsCollections10
- 说明
- CC10和CC6基本一样,只是在Transformer构造上有区别,CC10减少的利用链长度,直接调用TemplatesImpl,不使用Transformer[],而是直接将InvokerTransformer塞到LazyMap里,其实没啥区别。
- 限制
- commons-collections:<=3.2.1
- source
- java.util.HashSet
- LazyMap.get()
- java.util.HashSet
- 说明
1 2 3 4 5 6 7 8 9 10 11 12 13 | Gadget chain: java.io.ObjectInputStream.readObject() java.util.HashSet.readObject() java.util.HashMap.put() java.util.HashMap.hash() org.apache.commons.collections.keyvalue.TiedMapEntry.hashCode() org.apache.commons.collections.keyvalue.TiedMapEntry.getValue() org.apache.commons.collections.map.LazyMap.get() org.apache.commons.collections.functors.InvokerTransformer.transform() java.lang.reflect.Method.invoke() ... templates gadgets ... java.lang.Runtime.exec() |
- CommonsCollectionsK1/K2
- 说明
- 这两条链,其实整合了C1-C7,source从HasMap开始,和CC6很像,简化了很多细节,K1/K2可以说基本一样,只是适用版本不同而已。
- 限制
- K1 <=commons-collections3.2.1
- K2 commons-collections4.0
- source
- java.util.HasMap
- 说明
- JDK7U21
- 说明
- 该利用链无需第三方依赖即可利用,修复是在AnnotationInvocationHandler#readObject中,对非AnnotationType的this.type属性直接抛出异常中断反序列化,而我们用的是TemplateImpl。
- 限制
- jdk <=7u21
- jdk <= 6u45(jdk6最后一个公开版本)
- source
- java.util.HashSet
- 说明
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | LinkedHashSet.readObject() LinkedHashSet.add() ... TemplatesImpl.hashCode() (X) LinkedHashSet.add() ... Proxy(Templates).hashCode() (X) AnnotationInvocationHandler.invoke() (X) AnnotationInvocationHandler.hashCodeImpl() (X) String.hashCode() (0) AnnotationInvocationHandler.memberValueHashCode() (X) TemplatesImpl.hashCode() (X) Proxy(Templates).equals() AnnotationInvocationHandler.invoke() AnnotationInvocationHandler.equalsImpl() Method.invoke() ... TemplatesImpl.getOutputProperties() TemplatesImpl.newTransformer() TemplatesImpl.getTransletInstance() TemplatesImpl.defineTransletClasses() ClassLoader.defineClass() Class.newInstance() ... MaliciousClass.<clinit>() ... Runtime.exec() |
- JDK8U20
- 说明
- 这个利用链就是JDK7U21补丁的绕过,补丁在AnnotationInvocationHandler#readObject判断类型不对就抛出异常中断反序列化,java.beans.beancontext.BeanContextSupport在反序列化时,readChildren调用被封装在try catch里,避免异常中断,只要把JDK7U21利用链的对象封装到这里面,即可避免异常,从而成功利用。
- 这里gadget必须在jdk7以上环境编译
- 限制
- JDK <= 8U20
- source
- java.beans.beancontext.BeanContextSupport
- jdk7u21
- java.beans.beancontext.BeanContextSupport
- 说明
- 类加载
- URLClassLoader
- ClassLoader
- #defineClass因为是私有方法,只能反射调用
- TemplatesImpl
- defineClass(),在ysoserial里用到最多的类加载方式
- BCEL ClassLoader
- com.sun.org.apache.bcel
- JDK自带,来自Apache Xalan库
- Java 8u251后被移除
总结
CommonsCollections1,3,5,6,7,10 支持commons-collections<=3.2.1
CommonsCollections9 只适用于3.2.1
CommonsCollections2,4,8,基于CommonsCollections:4.0
CommonsCollections11 适用于CommonsCollections:3.1-3.2.1
CommonsCollectionsK1 支持commons-collections<=3.2.1
CommonsCollectionsK2 支持commons-collections:4.0
CommonsBeanutils1 支持 commons-beanutils:1.9.2+commons-collections:3.1
CommonsBeanutils2 支持 commons-beanutils:1.8.2+commons-collections:3.1
CommonsBeanutilsNoCC1 支持 commons-beanutils:1.9.2
CommonsBeanutilsNoCC2 支持 commons-beanutils:1.8.2
jdk7u21 支持jdk7u21和jdk6u45以下版本
jdk8u20支持jdk8u20以下版本,但不支持jdk6
网上还有其他利用链,如CC12基于CC6改造,调用js引擎执行代码,CC11基于CC2+CC6改造。
推荐利用链
其实CommonsCollectionsK1和CommonsCollectionsK2就包含这些了,无非是黑名单需要绕过
CommonsCollections:3.x:CC6和CC10是一条链,都很通用,并且也可以改造成CommonsCollections:4.0
commons-collections:4.0: 使用CC2或CC4
CommonsBeanutils:CommonsBeanutilsNoCC1和CommonsBeanutilsNoCC2
废弃
最后,据不完全统计推荐打CC的时候,
建议本地使用JDK7 commons-collections4-4.0 分别用CC4、CC3生成两个版本
建议本地使用JDK7 commons-collections3.1 用CC10或者CC11生成payload 3.* 都可以打
参考
https://mp.weixin.qq.com/s/oEtgJHWXB5lEJinWDOtKcw Ysoserial Part 2 —— CC 1-12 再排列组合一下就可以有CC N了
https://mp.weixin.qq.com/s/EDYSUZ6cPJSe3OMX5JZl8w Ysoserial Part 3 —— CB 、7u21、8u20 & 结合Weblogic绕过
https://xz.aliyun.com/t/9765 用一个 case 去理解 jdk8u20 原生反序列化漏洞
Java安全漫谈-系列