0x01.环境准备:

Apache Commons Collections 3.1版本,下载链接参考:

jd jui地址(将jar包转化为java源码文件):

https://github.com/java-https://www.secfree.com/a/231.html/jd-gui/releases

配置项目中的jdk版本:

https://blog.csdn.net/qq_22076345/article/details/82392236

设置class字节码输出路径

https://blog.csdn.net/zZ_life/article/details/51318306

为项目添加jar包

https://www.iteye.com/blog/zyjustin9-2172445

java object array(对象数组):

object obj[]=new object[5];

创建了一个Object数组,长度为5,这5个元素的值都是null,然后把创建好的数组实例的引用赋给obj变量。如果需要为这些元素分配具体的对象,则需要分别指定或用{}符号进行初始化

https://juejin.im/post/5a6ade5c518825733e60acb8 arrays工具类对数组进行操作

 

 

0x02.环境测试:

复制代码
import java.io.IOException; import java.lang.reflect.InvocationTargetException; import org.apache.commons.collections.Transformer; import org.apache.commons.collections.functors.InvokerTransformer; public class fanshe {     public static void main(String[] args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException, ClassNotFoundException, IOException {         //函数名字,传参类型,参数值        Transformer transformer = new InvokerTransformer("append", new Class[]{String.class}, new Object[]{"by SecFree"});         Object newobject = transformer.transform(new StringBuffer("hi "));         System.out.println(newobject);          Runtime r = (Runtime)Class.forName("java.lang.Runtime").getMethod("getRuntime", new java.lang.Class[]{}).invoke(null, new Object[]{});         System.out.println(new java.io.BufferedReader(new java.io.InputStreamReader(r.exec("whoami").getInputStream())).readLine());     } }
复制代码

从以上这段最简单的测试代码开始进行分析,

Transformer transformer = new InvokerTransformer("append", new Class[]{String.class}, new Object[]{"by SecFree"});

首先实例化了InvokerTransformer的对象,传入了要执行的方法名,参数类型,以及参数值,在传入值和类型时,要与java类中定义的变量的类型相一致

 这里定义的入口参数也可以看出所需要的类型,这里参数类型为class类型的数组,接下来第二行

Object newobject = transformer.transform(new StringBuffer("hi"));

此时调用了transformer类的transform方法,传入了一个StringBuffer的一个匿名对象,其中transform函数的定义如下,这个函数是Object类型的,入口参数也为object类型,

 此时如果input不为空,则会调用getclass方法得到当前对象的类对象,接下来通过调用getmethod方法,调用该类对象中的方法,其中传入的参数为两个,第一个为需要调用的

类中方法的方法名,第二个参数为调用的该方法的参数类型,此时getmethod的返回值为Method类型的对象,此时便可以通过调用method的invoke方法来实现我们想调用的方法的执行

比如此时使用反射机制完成对stringbuffer类的append方法的调用,从上图也可以看到入口参数类型为string,append方法实际上将传入append的字符串拼接到当前stringbuffer字符串的后面,然后返回当前字符串。

0x03.漏洞原理分析:

感觉这篇文章把这个漏洞的原因讲的非常详细,https://xz.aliyun.com/t/136

Apache Commons Collections 是一个扩展了Java标准库里的Collection结构的第三方基础库

org.apache.commons.collections提供一个类包来扩展和增加标准的Java的col