boxmoe_header_banner_img

梦中的登神殿,天才的乱葬岗

加载中

文章导读

Java安全开发基础&反射机制&攻击链&类对象&成员变量方法&构造方法_new


avatar
RootReapers 2026年2月12日 96

Java反射:

Java提供了一套反射API,该api由Class类与Java.lang.reflect类库组成,该类库包含了Field,method,Construct等类

对成员变量,成员方法和构造方法的信息进行的编程操作可以理解为反射机制


为什么用反射:

可以动态加载类(需要时再加载类)

而不是编译前加载


**从官方定义中就能找到其存在的价值,运行时获得程序/程序集中每一个类型的成员和成员信息,从而动态创建/修改/调用/获取其属性,而不需要事先知道运行的对象是谁
**重点:运行时,而不是编译时(不改变原有代码逻辑,自行运行时的时候动态创建和编译即可)



安全应用场景:

构造利用链,触发RCE

反序列化链构造

动态获取或执行任意类中的属性/方法

动态代理的底层原理时反射机制

rmi反序列化也涉及到反射操作


反射演示

package org.example.xiaodi_javasec.day03;

public class ReflectDemo {
    public String name="root";
    public int age = 20;
    private String gender = "man";//不是gay
    protected String job = "sec";

    public ReflectDemo() {
        System.out.println("对象被无参创建");
    }

    public ReflectDemo(String name) {
        this.name = name;
        System.out.println("有参数"+name);
    }

    public ReflectDemo(int age, String name) {
        this.age = age;
        this.name = name;
        System.out.println("有参数"+name+"&"+age);
    }

    public void info(String name, int age, String gender, String job) {
        this.name = name;
        this.age = age;
        this.gender = gender;
        this.job = job;
    }
}


这是一个很简单的类

info是自定义的函数

ReflectDemo是构造方法


通过forName获取类



通过内置的.class获取类


可以看到,输出的结果都是一样的



根据现有对象获取类


可以看到,三种方式的输出结果都是一样的


package org.example.xiaodi_javasec.day03;

public class Reflect {
    public static void main(String[] args) throws ClassNotFoundException {
        Class aclass = Class.forName("org.example.xiaodi_javasec.day03.ReflectDemo");//通过forName获取类
        System.out.println(aclass);

        Class bclass = ReflectDemo.class;
        System.out.println(bclass);

        ReflectDemo RD = new ReflectDemo();
        Class cclass = RD.getClass();
        System.out.println(cclass);
    }
}

通过类加载器获取

package org.example.xiaodi_javasec.day03;

public class Reflect {
    public static void main(String[] args) throws ClassNotFoundException {
        Class aclass = Class.forName("org.example.xiaodi_javasec.day03.ReflectDemo");//通过forName获取类
        System.out.println(aclass);

        Class bclass = ReflectDemo.class;
        System.out.println(bclass);

        ReflectDemo RD = new ReflectDemo();
        Class cclass = RD.getClass();
        System.out.println(cclass);

        ClassLoader CL = ClassLoader.getSystemClassLoader();
        Class dclass = CL.loadClass("org.example.xiaodi_javasec.day03.ReflectDemo");
        System.out.println(dclass);
    }
}

通过反射获取成员变量

package org.example.xiaodi_javasec.day03;

import java.lang.reflect.Field;

public class Reflect {
    public static void main(String[] args) throws ClassNotFoundException {
        Class aclass = Class.forName("org.example.xiaodi_javasec.day03.ReflectDemo");//通过forName获取类
        System.out.println(aclass);

        Class bclass = ReflectDemo.class;
        System.out.println(bclass);

        ReflectDemo RD = new ReflectDemo();
        Class cclass = RD.getClass();
        System.out.println(cclass);

        ClassLoader CL = ClassLoader.getSystemClassLoader();
        Class dclass = CL.loadClass("org.example.xiaodi_javasec.day03.ReflectDemo");
        System.out.println(dclass);
        
        Field[] fields = aclass.getFields();
        for (Field field : fields) {
            System.out.println(field);
        }
    }
}

获取到类后,通过内置的getFields方法,获取类的所有公共成员变量,以数组形式返回

通过for循环进行遍历输出


如果需要获取全部成员变量(包括private和protected)

使用getDeclaredFields()即可


getField加上参数,例如

**getField(“name”)
**表示获取指定的公共成员变量对象


同理getDeclaredFields加上参数表示

表示获取指定的成员变量对象


这只是获取类的成员变量名


Field类还可以进行赋值

void set(object obj,Object value)

第一个参数是对象名,第二个是要赋的值


Object get(Object obj)

获取值


ReflectDemo RF = new ReflectDemo();
        Field field2 = aclass.getField("age");
        Object a = field2.get(RF);
        System.out.println(a);

创建一个对象RF

然后通过Field取得它的成员变量age

再通过一个Object类的对象a接收它

然后输出a


修改值,修改完记得重新读取

package org.example.xiaodi_javasec.day03;

import java.lang.reflect.Field;

public class Reflect {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException {
        Class aclass = Class.forName("org.example.xiaodi_javasec.day03.ReflectDemo");//通过forName获取类
        System.out.println(aclass);

        Class bclass = ReflectDemo.class;
        System.out.println(bclass);

        ReflectDemo RD = new ReflectDemo();
        Class cclass = RD.getClass();
        System.out.println(cclass);

        ClassLoader CL = ClassLoader.getSystemClassLoader();
        Class dclass = CL.loadClass("org.example.xiaodi_javasec.day03.ReflectDemo");
        System.out.println(dclass);

        Field[] fields = aclass.getDeclaredFields();
        for (Field field : fields) {
            System.out.println(field);
        }
        Field field = aclass.getField("name");
        Field field_1=aclass.getDeclaredField("gender");
        System.out.println(field_1);
        System.out.println(field);

        ReflectDemo RF = new ReflectDemo();
        Field field2 = aclass.getField("age");
        Object a = field2.get(RF);

        System.out.println(a);
        field2.set(RF,18);
        Object b = field2.get(RF);
        System.out.println(b);
    }
}


反射获取构造方法


Constructor<?>[] constructors= aclass.getConstructors();
for (Constructor<?> constructor : constructors) {
    System.out.println(constructor);
}
Constructor<?>[] constructor_all= aclass.getDeclaredConstructors();
for (Constructor<?> constructor : constructor_all) {
    System.out.println(constructor);
}

用法和Field类相似


package org.example.xiaodi_javasec.day03;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;

public class Reflect {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException, NoSuchMethodException {
        Class aclass = Class.forName("org.example.xiaodi_javasec.day03.ReflectDemo");//通过forName获取类
        System.out.println(aclass);

        Class bclass = ReflectDemo.class;
        System.out.println(bclass);

        ReflectDemo RD = new ReflectDemo();
        Class cclass = RD.getClass();
        System.out.println(cclass);

        ClassLoader CL = ClassLoader.getSystemClassLoader();
        Class dclass = CL.loadClass("org.example.xiaodi_javasec.day03.ReflectDemo");
        System.out.println(dclass);

        Field[] fields = aclass.getDeclaredFields();
        for (Field field : fields) {
            System.out.println(field);
        }
        Field field = aclass.getField("name");
        Field field_1=aclass.getDeclaredField("gender");
        System.out.println(field_1);
        System.out.println(field);

        ReflectDemo RF = new ReflectDemo();
        Field field2 = aclass.getField("age");
        Object a = field2.get(RF);

        System.out.println(a);
        field2.set(RF,18);
        Object b = field2.get(RF);
        System.out.println(b);

        //获取所有构造方法
        Constructor<?>[] constructors= aclass.getConstructors();
        for (Constructor<?> constructor : constructors) {
            System.out.println(constructor);
        }
        Constructor<?>[] constructor_all= aclass.getDeclaredConstructors();
        for (Constructor<?> constructor : constructor_all) {
            System.out.println(constructor);
        }
        //获取指定参数类型的构造方法
        Constructor constructors1= aclass.getConstructor(String.class);
        System.out.println(constructors1);


    }
}


construct类除了可以获取构造方法

还可以通过调用构造方法创建对象

T newinstance(Object… initargs):根据指定的构造方法创建对象

setAccessible(boolean flag):设置为true,表示取消访问权限检查


Constructor constructors1= aclass.getConstructor(String.class);
        System.out.println(constructors1);
        constructors1.setAccessible(true);//如果构造方法是私有,则需要加上这个,取消访问检查
        ReflectDemo RD1 = (ReflectDemo) constructors1.newInstance("root");

反射获取成员方法

//获取&调用成员方法
Method[] methods=aclass.getMethods();//获取所有成员方法,包括继承的
for (Method method : methods) {
    System.out.println(method);
}
Method[] methods=aclass.getDeclaredMethods();//获取所有成员方法,不包括继承的
for (Method method : methods) {
    System.out.println(method);
}
Method methods=aclass.getMethod('');



通过invoke调用

Method method=aclass.getMethod("info",String.class,int.class,String.class, String.class);
System.out.println(method);

//调用成员方法
method.invoke(RF,"root123",123,"no_gay","no_gay");



反射与安全挂钩

窝趣,弹计算器了,有黑客?

这是一个Java内置类:运行时类

它不能被new,因为它的构造器是私有的

但是可以通过getRuntime获取当前的实例



exec():老朋友了,看到它就能想到命令执行

在Java中,它也是用来执行命令的

exec(“calc”)

执行calc命令(弹出计算器)


package org.example.xiaodi_javasec.day03;

import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import static java.lang.Class.forName;

public class exp {
    public static void main(String[] args) throws IOException, ClassNotFoundException, NoSuchMethodException, IllegalAccessException, NoSuchFieldException, InvocationTargetException, InstantiationException {
        Class runtime = forName("java.lang.Runtime");
        Constructor constructor = runtime.getDeclaredConstructor();
        constructor.setAccessible(true);
        Runtime runtime_instance = (Runtime)constructor.newInstance();
        Method get_exec= runtime.getMethod("exec", String.class);
        get_exec.invoke(runtime_instance,"calc");

    }
}

可以直接利用反射调用exec命令实现rce


总结一下,因为边听边写笔记确实有点混乱

forname获取类:

Class reflect = Class.forname("org.example.xiaodi_javasec.day03.ReflectDemo")

ClassLoader类加载器获取类:

ClassLoader CL = ClassLoader.getSystemClassLoader();
Class dclass CL.loadClass("org.example.xiaodi_javasec.day03.ReflectDemo");

通过getclass函数获取到类

ReflectDemo RD = new ReflectDemo();
Class cclass = RD.getClass();

通过现有对象获取对应类

Class bclass = ReflectDemo.class;

以上方式均可获取到类


获取其成员变量以及方法

可以使用Field类

类名.getFields:获取所有公共(pbulic)成员变量

类名.getDeclaredFields:获取所有成员变量,包括私有

它们以数组形式返回

因此需要定义Field[] 数组类型去接收


类名.getField(成员变量名)

获取指定成员变量(public)


类名.getDeclaredField(成员变量名)

获取指定成员变量


Method[] methods = 类名…getMethods()

获取所有成员方法,包括继承的


Method[] methods = 类名.getDeclaredMethods()

获取所有成员方法,不包括继承的



Method method =class_reflect.getMethod("info", String.class,int.class,String.class, String.class)
method.invoke(newinstance,"root123",123,"no_gay","no_gay");

指定参数类型获取并且调用成员方法



Constructor[] Constructors = 类名.getConstructors()

获取公有构造方法


Constructor[] Constructors = 类名.getDeclaredConstructors()

获取所有构造方法


Constructor constructor = 类名.getConstructor()

获取指定构造方法


package org.example.xiaodi_javasec.day03;

import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import static java.lang.Class.forName;

public class exp {
    public static void main(String[] args) throws IOException, ClassNotFoundException, NoSuchMethodException, IllegalAccessException, NoSuchFieldException, InvocationTargetException, InstantiationException {
        Class class_reflect = forName("org.example.xiaodi_javasec.day03.ReflectDemo");
        //获取类
        Field[] class_reflect_Attributes = class_reflect.getDeclaredFields();//获取所有成员变量
        for (Field classReflectAttribute : class_reflect_Attributes) {
            System.out.println(classReflectAttribute);
        }//遍历输出
        Field Attribute = class_reflect.getDeclaredField("age");//指定获取age成员变量
        ReflectDemo instance_demo = new ReflectDemo();
        Object get_Attribute = Attribute.get(instance_demo);//使用get_Attribute接收获取的age值,并且指定对象
        System.out.println(get_Attribute);
        Attribute.set(instance_demo,19);
        System.out.println(instance_demo.age);//输出19,被set修改了
        //获取&设置&输出成员变量
        System.out.println("获取&设置&输出成员变量");

        Constructor[] class_reflect_constructor = class_reflect.getDeclaredConstructors();
        for (Constructor class_reflect_constructors : class_reflect_constructor) {
            System.out.println(class_reflect_constructors);
        }
        Constructor class_reflect_constructor_alone = class_reflect.getDeclaredConstructor(String.class);
        System.out.println(class_reflect_constructor_alone);
        class_reflect_constructor_alone.setAccessible(true);
        ReflectDemo newinstance = (ReflectDemo) class_reflect_constructor_alone.newInstance("roottoor");
        System.out.println(newinstance.name);
        System.out.println("获取&调用构造方法");

        Method[] methods=class_reflect.getMethods();//获取所有成员方法,包括继承的
        for (Method method : methods) {
            System.out.println(method);
        }
        Method[] methods_Declared =class_reflect.getDeclaredMethods();//获取所有成员方法,不包括继承的
        for (Method method : methods_Declared) {
            System.out.println(method);
        }
        Method method =class_reflect.getMethod("info", String.class,int.class,String.class, String.class);//指定参数类型获取成员方法
        System.out.println(method);
        method.invoke(newinstance,"root123",123,"no_gay","no_gay");
        System.out.println("获取&调用成员方法");
    }
}








评论(0)

查看评论列表

暂无评论


发表评论

表情 颜文字
插入代码