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