Commons-Collections3原理分析
CC3 官方描述为 CC1 的变种,其中能看到 CC1 和 CC2 的部分影子,但是部分技术细节并不相同。
在 CC1 中,使用了 AnnotationInvocationHandler 对 LazyMap 进行代理,在反序列化时触发 LazyMap 的 get 方法,并对 LazyMap 装饰 Transformer 触发漏洞。
在 CC2 中,使用 TemplatesImpl 的 newTransformer 方法触发实例化恶意类触发漏洞,方法的调用则是使用了 InvokerTransformer 调用。
而在 CC3 中,使用了 CC1 的 LazyMap 和 CC3 的 TemplatesImpl,中间寻找了其他的触发 newTransformer 的实现方式。
没有使⽤到InvokerTransformer,因为在SerialKiller这个Java反序列化过滤器中,将InvokerTransformer加入了黑名单,CC3就是为了绕过这一限制。
前置知识
TrAXFilter
在 SAX API 中提供了一个过滤器接口 org.xml.sax.XMLFilter,XMLFilterImpl 是对它的缺省实现,使用过滤器进行应用程序开发时,只要继承 XMLFilterImpl,就可以方便的实现自己的功能。com.sun.org.apache.xalan.internal.xsltc.trax.TrAXFilter 是对 XMLFilterImpl 的实现,在其基础上扩展了 Templates/TransformerImpl/TransformerHandlerImpl 属性,
TrAXFilter 在实例化时接收 Templates 对象,并调用其 newTransformer 方法,这就可以触发我们的 TemplatesImpl 的攻击 payload 了,而不需要像CC2那样使用InvokerTransformer手工newTransformer。
InstantiateTransformer
接下来的重点就是需要我们实例化这个 TrAXFilter,实例化我们当然可以使用 InvokerTransformer 拿到 Constructor 再 newInstance,但是同样地可以直接使用另外一个 Transformer:org.apache.commons.collections.functors.InstantiateTransformer。
Commons Collections 提供了 InstantiateTransformer 用来通过反射创建类的实例,可以看到 transform() 方法通过 getConstructor 获取构造方法,并通过 newInstance 创建类实例。
反射需要的 iParamTypes 参数类型、iArgs 参数值,在 InstantiateTransformer 初始化时赋值。
POC
通过代理readObject触发它的invoke,调用LazyMap的get,再调用chainedTransformer,实现通过InstantiateTransformer对TrAXFilter进行实例化,实例化的参数类型是Templates.class,参数是templatesImpl。TrAXFilter实例化时调用newTransformer 方法,这就可以触发我们的 TemplatesImpl 的攻击 payload 了
POC部分和CC1差不多了,使用LazyMap对hashMap进行包装;实例化AnnotationInvocationHandler,并对其进行代理;通过实例化参数为代理的InvocationHandler,对代理进行包装。
最后序列化。
1 | public class CC3 { |

总结
利用说明:
这里讲过了
1 | Gadget 总结: |
1 | 调用链展示: |
依赖版本
commons-collections : 3.1~3.2.1
jdk < 8u21
