环境1
首先是我们要注意java的版本需要是 ,因为一些漏洞后续被修复了
环境2
因为一些源码是class文件,工具会帮我们自动反编译的,但是我们都知道,这个东西反编译出来的,肯定不方便阅读,所以为了方便我们后续的调试,我们这里将openjdk的源码下过来,把我们需要导入到jdk中
这里我们解压以后来到src\share\classes下面,将sun文件包括里面的内容复制到jdk的src目录中。
这里我们来到jdk的目录中,先把src.zip解压,然后将sun粘贴到src目录里面
然后我们来到idea,打开目录结构
这里点开SDK,选择我们需要的jdk,然后选择源路径,把src文件夹添加进去
环境3
这里我们新建项目选择maven
然后再pom.xmli添加
<dependencies>
<!-- https://mvnrepository.com/artifact/commons-collections/commons-collections -->
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>3.2.1</version>
</dependency>
</dependencies>
下面看过来,这里我们右键pom.xml -> maven然后按下面的来
然后我们就可以看到这里多了一个target目录,然后下面下载了依赖
链子分析
利用第一阶段
首先入门点在这里,org.apache.commons.collections.Transformer类中,就是在这里面
这里他是一个class文件,但是我们知道反编译class文件出来的代码是不好分析,右上角那里可以帮我们把源代码下载过来。
至于为什么使用Transformer接口,这里我们可以看到下面,这里我们可以理解成一个转换对象的地点,我们传进去的对象都会被转换后在返回,而且它可以接受任何对象。
这里我们选中Transformer,使用快捷键ctrl+alt+b,我们就可以快速查看使用了Transformer接口的类,因为我们知道InvokerTransformer是下一个节点,这里我们直接来到那里
这里我们来到InvokerTransformer类中的transform方法,这里我们可以知道,他是利用了反射,下面我们分析一下
input是我们传入的对象
Class cls = input.getClass(); 通过input对象获取字节码文件
//获取input对象中的iMethodName(iParamTypes)方法
//注意:java中方法是可以重名的,只要参数数量不一样就可以
Method method = cls.getMethod(iMethodName, iParamTypes);
//调用了iMethodName方法,参数的值是iArgs
method.invoke(input, iArgs);
然后找到参数的值的位置,这里参数的值,我们可以new的对象的时候附带进去,发现参数值,没有任何过滤,证明我们可以进行恶意代码了。
这里我们可以看看基础恶意代码执行
//但是我们不能以这种方法来进行恶意代码执行,我们这里将他转成反射的形式
Runtime.getRuntime().exec("notepad"); //使用exec方法打开记事本
这里是反射形式的,这里可以看到上面和上面InvokerTransformer类中的transform方法的形式是一样的呢,所以我们按这样将数据传入到里面
// 获取当前运行时对象
Runtime r = Runtime.getRuntime();
// 通过对象获得字节码文件
Class c = r.getClass();
// 获取Class对象中名为"exec",参数为String类型的public方法
Method execm = c.getMethod("