构造链
概述
Commons Collections 3.2.2的改动
Commons Collections4 4.1的改动
4.1⾥,这⼏个危险Transformer类不再实现 Serializable 接⼝,也就是说,他们⼏个彻底⽆法序列化和反序列化了
CommonCollections1链
适用环境
commons-collections3.1-3.2.1
jdk1.7.1以下
TransformedMap_readObject触发
大体思路
- AnnotationInvocationHandler#readObject()
- TransformedMap#put()
- transformerChain#transform()
- ConstantTransformer#transform() InvokerTransformer#transform()
细节问题在p神的《java安全漫谈》-10会详细解释
- 参考链接:
- https://blog.csdn.net/qq_35733751/article/details/118387718
- p神的《java安全漫谈》-9,10
LazyMap_invoke触发
大体思路
AnnotationInvocationHandler实现了InvocationHandler接口,这在动态代理中相当于是重写了invoke()函数去解决下面问题
当通过代理类的对象调用方法a时,如何动态的去调用被代理类中的同名方法a?
AnnotationInvocationHandler#readObject()
当readObject()使用代理类执行任何方法时会跳转到第2步
AnnotationInvocationHandler#invoke()
LazyMap#get()
transformerChain#transform()
ConstantTransformer#transform() InvokerTransformer#transform()
- 参考链接
- https://blog.csdn.net/qq_35733751/article/details/118462281
- p神的《java安全漫谈》-11
invoke是动态代理定位方法的函数。当通过代理类对象调用方法时,会自动的调用invoke函数进而调用被代理类中同名的方法
高版本jdk如何触发链
跳转到cc6链
CC2链
适用环境
commons-collections4 4.0
TestPriorityQueueTransformingComparator
大体思路
java.util.PriorityQueue#readObject()
PriorityQueue#heapify()
PriorityQueue#siftDown()
PriorityQueue#siftDownUsingComparator()
这个函数里调用了comparator.compare()
org.apache.commons.collections4.comparators.TransformingComparator#compare()
transformerChain#transform()
ConstantTransformer#transform() InvokerTransformer#transform()
-
参考链接
-
p神的《java安全漫谈》-16
关于PriorityQueue队列的文章:https://songly.blog.csdn.net/article/details/119008552
CC3链
适用环境
commons-collections3.1-3.2.1
jdk1.7.1以下
-
关于字节码需要注意:
这个字节码对应的类是 com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet 的子类
TemplatesImpl与InvokerTransformer
大体思路
在cc1链基础上借助TemplatesImpl::newTransformer()和ConstantTransformer构造⼀个执⾏任意字节码的链
AnnotationInvocationHandler#readObject()
TransformedMap#put()
其实这一步也可以使用LazyMap#get()那条链
transformerChain#transform()
ConstantTransformer#transform() InvokerTransformer#transform()
这一步是获得TemplatesImpl对象,并调用TemplatesImpl.newTransformer()函数
- 参考链接:
- p神的《java安全漫谈》-14
TrAXFilter与InstantiateTransformer
大体思路
在cc1链基础上借助TrAXFilter和InstantiateTransformer调用TemplatesImpl::newTransformer()构造⼀个执⾏任意字节码的链
AnnotationInvocationHandler#readObject()
TransformedMap#put()
其实这一步也可以使用LazyMap#get()那条链
transformerChain#transform()
ConstantTransformer#transform() InstantiateTransformer#transform()
这一步是获得TrAXFilter对象,并调用TrAXFilter的构造函数,进而执行了(TransformerImpl) templates.newTransformer()
- 参考链接:
- p神的《java安全漫谈》-14
- https://songly.blog.csdn.net/article/details/118943156
高版本jdk如何触发链
- 参考cc1链如何改进成cc6链
CC4链
适用环境
commons-collections4 4.0
其实commons-collections依赖的其它链还可以继续用,只需把报错修改一下
CC6链
大体思路
java.util.HashMap#readObject()
HashMap#hash(key)
key是Map对象
TiedMapEntry#hashCode()
TiedMapEntry#getValue()
这一步执行了
LazyMap#get(key)
transformerChain#transform()
ConstantTransformer#transform() InvokerTransformer#transform()
参考链接
- p神的《java安全漫谈》-12
CommonsBeanutils1链
适用环境
CommonsBeanutils 1.9.3
TestPriorityQueueBeanComparator
大体思路
java.util.PriorityQueue#readObject()
PriorityQueue#heapify()
PriorityQueue#siftDown()
PriorityQueue#siftDownUsingComparator()
这个函数里调用了comparator.compare()
BeanComparator#compare()
PropertyUtils.getProperty( o1, property ) 这段代码,当o1是一个 TemplatesImpl 对象,而 property 的值为 outputProperties 时,将会自动调用getter,也就是TemplatesImpl#getOutputProperties() 方法
TemplatesImpl#getOutputProperties()
参考链接
- p神的《java安全漫谈》-17
Shiro利用链
TestTiedMapInvokerTransformer
大体思路
可以结合代码中的注释看
- java.util.HashMap#readObject()
- HashMap#hash(key)
- TiedMapEntry#hashCode()
- TiedMapEntry#getValue()
- LazyMap#get()
- InvokerTransformer#transform()
参考链接
- p神的《java安全漫谈》-15
无依赖的Shiro反序列化利用链
参考链接
- p神的《java安全漫谈》-17