怎样简单使用java序列回显学习

java反序列化回显

在很多不出网的情况下,一种是写webshell(内存嘛),另一种就是回显,本文先学习回显,回显的主要方式有一下几种。

  1. defineClass
  2. RMI绑定实例
  3. URLClassLoader抛出异常
  4. 中间件
  5. 写文件css、js
  6. dnslog

前面有多多少了解过ClassLoader本篇花费一节仔细学习一下

1、前置知识

classloader顾名思义,即是类加载。虚拟机把描述类的数据从class字节码文件加载到内存,并对数据进行检验、转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这就是虚拟机的类加载机

1.1、ClassLoader加载过程

主要是三个阶段

第一个阶段是加载,把.class文件加载到内存,并为它创建一个java.lang.Class对象

第二个阶段是连接,连接包括三阶段

验证:确保加载的类信息符合JVM规范,无安全方面的问题。准备:为类的静态Field分配内存,并设置初始值,变量的初始值,如:int=0。解析:将类的二进制数据中的符号引用替换成直接引用。

第三阶段是初始化

1、优先对该类的父类进行初始化,然后对static修饰的变量和代码块进行初始化

1.2、classloader双亲委托机制

当一个类加载的过程中,它首先不会去加载,而是委托给自己的父类去加载,父类又委托给自己的父类。因此所有的类加载都会委托给顶层的父类,即Bootstrap Classloader进行加载,然后父类自己无法完成这个加载请求,子加载器才会尝试自己去加载

1.启动类加载器(Bootstrap Classloader)负责将<JAVA_HOME>/lib目录下并且被虚拟机识别的类库加载到虚拟机内存中。我们常用基础库,例如java.util. ,java.io. ,java.lang.**等等都是由根加载器加载

2.扩展类加载器(Extention Classloader)负责加载JVM扩展类,比如swing系列、内置的js引擎、xml解析器等,这些类库以javax开头,它们的jar包位于<JAVA_HOME>/lib/ext目录中

3.应用程序加载器(Application Classloader)也叫系统类加载器,它负责加载用户路径(ClassPath)上所指定的类库。我们自己编写的代码以及使用的第三方的jar包都是由它来加载的

4.自定义加载器(Custom Classloader)通常是我们为了某些特殊目的实现的自定义加载器

1.3、ClassLoader类 核心方法

1.loadClass(String className),根据名字加载一个类。
2.defineClass(String name, byte[] b, int off, int len),将一个字节流定义为一个类。
3.findClass(String name),查找一个类。
4.findLoadedClass(String name),在已加载的类中,查找一个类。

1.4、自定义Classloader

当加载一个类时,会首先从已经加载的类里面去查找这个类。如果类未加载,且如果父加载器不为空,则调用父加载器的loadClass方法进行加载,如果父加载器为空,则调用BootStrap class loader加载。如果依然没有加载到类,则调用findClass方法。而findClass方法是需要子类重写的。所以我们只需要继承classLoader重写findClass方法就可以实现自定义ClassLoader

1、继承classLoader
2、重写findClass()方法
3、在findClass()中调用defineClass

编写测试类

package com.akkacloud.demo;import java.io.*;
import java.util.Arrays;public class test {public void testclassloder() {System.out.println("test classloader");}}

编译成class文件

编写自己的classLoder

package com.akkacloud.demo;import java.io.*;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;public class myClassloader extends ClassLoader{private static String ClassName = "com.akkacloud.demo.test";//获取class文件,转换成byteprivate static byte[] getbyte() throws IOException {InputStream is = new FileInputStream(new File("/Users/akka/Downloads/deserialzeEcho/src/main/java/com/akkacloud/demo/test.class"));ByteArrayOutputStream outputStream = new ByteArrayOutputStream();byte[] bytes = new byte[1024];int temp;while ((temp = is.read(bytes)) != -1) {outputStream.write(bytes, 0, temp);}//转换后的byte[]byte[] finalBytes = outputStream.toByteArray();return finalBytes;}@Overrideprotected Class<?> findClass(String name) throws ClassNotFoundException {//如果类名为我们定的类if(name==ClassName){try {//从字节中获取一个类return defineClass(ClassName, getbyte(),0,getbyte().length);} catch (IOException e) {e.printStackTrace();}}return super.findClass(name);}public static void main(String[] args) throws ClassNotFoundException {//新建自定义的类加载器myClassloader myClassloader = new myClassloader();Class<?> aClass = myClassloader.loadClass(ClassName);try {//反射调用类的方法Object o = aClass.newInstance();Method declaredMethod = aClass.getMethod("testclassloder", null);declaredMethod.invoke(o, null);} catch (InstantiationException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();} catch (NoSuchMethodException e) {e.printStackTrace();} catch (InvocationTargetException e) {e.printStackTrace();}}
}

2、defineClass异常回显

首先新建恶意异常回显类,并且编译成class文件

package com.akkacloud.demo;import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;public class Echo {public Echo(String cmd) throws Exception {ProcessBuilder processBuilder = new ProcessBuilder(new String[]{cmd});Process start = processBuilder.start();InputStream inputStream = start.getInputStream();InputStreamReader inputStreamReader = new InputStreamReader(inputStream);BufferedReader bufferedReader = new BufferedReader(inputStreamReader);StringBuffer stringBuffer = new StringBuffer();String line =null;while ((line = bufferedReader.readLine()) != null) {stringBuffer.append(line).append("\n");}throw new Exception(stringBuffer.toString());}
}

新建自己的classLoder

package com.akkacloud.demo;import java.io.*;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;public class myClassloader extends ClassLoader{private static String ClassName = "com.akkacloud.demo.Echo";//获取class文件,转换成byteprivate static byte[] getbyte() throws IOException {InputStream is = new FileInput