Java是编译型语言,所有的Java代码都需要被编译成字节码来让JVM执行。Java类初始化时会调用 java.lang.ClassLoader 加载类字节码,ClassLoader会调用defineClass方法来创建一个 java.lang.Class 类实例。
ClassLoader类是一个抽象类,并不能直接拿来用,jdk中有几个具体实现类,比如
DefiningClassLoader
BCEL ClassLoader
GroovyClassLoader
URLClassLoader
Jython中PythonInterpreter的org.python.core.BytecodeLoader
自己实现ClassLoader
等等
本文主要讲解三种
URLClassLoader
BytecodeLoader
自己定义ClassLoader去从字节码中加载类
一、URLClassLoader
package org.chabug.loader;
import java.net.URL;
import java.net.URLClassLoader;
public class URLClassLoaderDemo {
public static void main(String[] args) throws Exception {
// URL url = new URL("https://baidu.com/cmd.jar"); // 也可以加载远程jar
URL url = new URL("file:///d:/calc.jar");
// 创建URLClassLoader对象,并加载远程jar包
URLClassLoader ucl = new URLClassLoader(new URL[]{url});
// 通过URLClassLoader加载jar包
Class<?> aClass = ucl.loadClass("org.chabug.demo.Calc");
aClass.newInstance();
}
}
jar包制作命令为
jar cvf calc.jar Calc.class
恶意代码直接写在static代码块中,新建类实例newInstance()时会自动执行。
成功弹出计算器
二、BytecodeLoader
package org.chabug.loader;
import org.python.util.PythonInterpreter;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
public class BytecodeLoaderLoader {
public static void main(String[] args) throws Exception {
String className = "org.chabug.demo.Calc";
byte[] bytes = getBytesByFile("E:\\code\\java\\JavaSerialize\\target\\classes\\org\\chabug\\demo\\Calc.class");
String classBytes = "";
for (byte b : bytes) {
classBytes += String.format("%s%s", b, ",");
}
String s = String.format("from org.python.core import BytecodeLoader;\n" +
"from jarray import array\n" +
"myList = [%s]\n" +
"bb = array( myList, 'b')\n" +
"BytecodeLoader.makeClass(\"%s\",None,bb).getConstructor([]).newInstance([]);", classBytes, className);
PythonInterpreter instance = PythonInterpreter.class.getConstructor(null).newInstance();
instance.exec(s);
}
public static byte[] getBytesByFile(String pathStr) {
File file = new File(pathStr);
try {
FileInputStream fis = new FileInputStream(file);
ByteArrayOutputStream bos = new ByteArrayOutputStream(1000);
byte[] b = new byte[1000];
int n;
while ((n = fis.read(b)) != -1) {
bos.write(b, 0, n);
}
fis.close();
byte[] data = bos.toByteArray();
bos.close();
return data;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
package org.chabug.loader;
import static org.chabug.loader.BytecodeLoaderLoader.getBytesByFile;
public class MyLoader extends ClassLoader {
public static String className = "org.chabug.demo.Calc";
public static byte[] bytes = getBytesByFile("E:\\code\\java\\JavaSerialize\\target\\classes\\org\\chabug\\demo\\Calc.class");
public static void main(String[] args) throws Exception {
new MyLoader().loadClass(className).newInstance();
}
@Override
public Class<?> findClass(String name) throws ClassNotFoundException {
// 只处理TestHelloWorld类
if (name.equals(className)) {
// 调用JVM的native方法定义TestHelloWorld类
return defineClass(className, bytes, 0, bytes.length);
}
return super.findClass(name);
}
}
四、原文链接
https://github.com/Y4er/WebLogic-Shiro-shell
五、相关推荐
JNDI-Injection-Exploit-Plus
工具地址:
https://github.com/cckuailong/JNDI-Injection-Exploit-Plus
往期回顾: