Skip to content

Latest commit

 

History

History

Jdk

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 

JDK

jdk>12不能反射修改下面class的成员。 image 思路是通过unsafe api去修改Reflection类的成员,赋值为null.

import sun.misc.Unsafe;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.util.HashMap;

public class bypass {
    private static Unsafe getUnsafe() {
        Unsafe unsafe = null;
        try {
            Field field = Unsafe.class.getDeclaredField("theUnsafe");
            field.setAccessible(true);
            unsafe = (Unsafe) field.get(null);
        } catch (Exception e) {
            throw new AssertionError(e);
        }
        return unsafe;
    }
    public static byte[] readInputStream(InputStream inputStream) {
        byte[] temp = new byte[4096];
        int readOneNum = 0;
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        try {
            while ((readOneNum = inputStream.read(temp)) != -1) {
                bos.write(temp, 0, readOneNum);
            }
            inputStream.close();
        }catch (Exception e){
        }
        return bos.toByteArray();
    }

    public void bypassReflectionFilter()throws Exception{
        Unsafe unsafe = getUnsafe();
        Class reflectionClass=Class.forName("jdk.internal.reflect.Reflection");
        byte[] classBuffer = readInputStream(reflectionClass.getResourceAsStream("Reflection.class"));
        //定义一个类,但不让类加载器知道它。
        Class reflectionAnonymousClass = unsafe.defineAnonymousClass(reflectionClass,classBuffer,null);

        Field fieldFilterMapField=reflectionAnonymousClass.getDeclaredField("fieldFilterMap");
        //不需要
        //Field methodFilterMapField=reflectionAnonymousClass.getDeclaredField("methodFilterMap");

        if(fieldFilterMapField.getType().isAssignableFrom(HashMap.class)){
            unsafe.putObject(reflectionClass,unsafe.staticFieldOffset(fieldFilterMapField),new HashMap());
        }
        //if(methodFilterMapField.getType().isAssignableFrom(HashMap.class)){
        //  unsafe.putObject(reflectionClass,unsafe.staticFieldOffset(methodFilterMapField),new HashMap());
        //}
    }
    public static void main(String[] args) throws Exception{
        //绕过Java 反射过滤获取ClassLoader私有字段
        //ClassLoader.class.getDeclaredField("parent");//在之前反射会报错
        new bypass().bypassReflectionFilter();
        ClassLoader.class.getDeclaredField("parent");//在之后反射可以bypass
    }
}

参考:https://github.com/BeichenDream/Kcon2021Code/blob/master/bypassJdk/JdkSecurityBypass.java

jdk>16

jdk17 bypass module

https://www.bennyhuo.com/2021/10/02/Java17-Updates-06-internals/

https://github.com/BeichenDream/Kcon2021Code/blob/master/bypassJdk/JdkSecurityBypass.java

在jdk17使用反序列化的时候发现要报错

InvokerTransformer: The method 'newTransformer' on 'class com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl' cannot be accessed

image

限制了

image

限制了的类https://cr.openjdk.java.net/~mr/jigsaw/jdk8-packages-strongly-encapsulated

需要bypass

按照提案的说明,被严格限制的这些内部 API 包括:
        
java.* 包下面的部分非 public 类、方法、属性,例如 Classloader 当中的 defineClass 等等。
sun.* 下的所有类及其成员都是内部 API。
绝大多数 com.sun.* 、 jdk.* 、org.* 包下面的类及其成员也是内部 API。

code

import sun.misc.Unsafe;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;

/**
 * https://cr.openjdk.java.net/~mr/jigsaw/jdk8-packages-strongly-encapsulated
 */
public class BypassModule {
    public static void main(String[] args) throws Exception {
        final ArrayList<Class> classes = new ArrayList<>();
        classes.add(Class.forName("java.lang.reflect.Field"));
        classes.add(Class.forName("java.lang.reflect.Method"));
        Class aClass = Class.forName("com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl");
        classes.add(aClass);
        new BypassModule().bypassModule(classes);
        aClass.newInstance();
    }

    public void bypassModule(ArrayList<Class> classes){
        try {
            Unsafe unsafe = getUnsafe();
            Class currentClass = this.getClass();
            try {
                Method getModuleMethod = getMethod(Class.class, "getModule", new Class[0]);
                if (getModuleMethod != null) {
                    for (Class aClass : classes) {
                        Object targetModule = getModuleMethod.invoke(aClass, new Object[]{});
                        unsafe.getAndSetObject(currentClass, unsafe.objectFieldOffset(Class.class.getDeclaredField("module")), targetModule);
                    }
                }
            }catch (Exception e) {
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    private static Method getMethod(Class clazz,String methodName,Class[] params) {
        Method method = null;
        while (clazz!=null){
            try {
                method = clazz.getDeclaredMethod(methodName,params);
                break;
            }catch (NoSuchMethodException e){
                clazz = clazz.getSuperclass();
            }
        }
        return method;
    }

    private static Unsafe getUnsafe() {
        Unsafe unsafe = null;
        try {
            Field field = Unsafe.class.getDeclaredField("theUnsafe");
            field.setAccessible(true);
            unsafe = (Unsafe) field.get(null);
        } catch (Exception e) {
            throw new AssertionError(e);
        }
        return unsafe;
    }
}