Java反射机制&类对象&成员方法&构造方法&攻击链
目录
0x00 前言
希望和各位大佬一起学习,如果文章内容有错请多多指正,谢谢!?
个人博客链接:CH4SER的个人BLOG – Welcome To Ch4ser's Blog
0x01 Java 反射介绍
1、什么是 Java 反射
参考:JAVA安全基础(二)-- 反射机制 - 先知社区 (aliyun.com)
Java 反射是一种强大的机制,它可以在运行时动态地获取和操作类的信息。通过反射,我们可以实现一些动态的功能,并且可以更灵活地使用和扩展已有的类。片面的来讲,对成员变量,成员方法和构造方法的信息进行的编程操作可以理解为反射机制。
?
- Java 提供了一套反射API,该 API 由 Class 类与 java.lang.reflect 类库组成,该类库包含了Field、Method、Constructor等类
- 对成员变量,成员方法和构造方法的信息进行的编程操作可以理解为反射机制
- Java 反射是一种机制,它允许我们在运行时(非编译时)动态地获取一个类的信息并操作它。通过反射,我们可以在不知道类的具体细节的情况下,获取类的成员变量、成员方法和构造方法,并且可以在运行时动态地创建对象、调用方法、访问属性等操作。
- 在 Java 中,每个类在编译后都会生成一个对应的 .class 文件。当我们使用 Java 编译器(javac)编译一个类文件时,会生成一个 .class 文件,并且 JVM 会自动加载这个 .class 文件到内存中。同时,JVM 会为每个类创建一个 Class 对象,这个 Class 对象包含了类的所有信息,包括成员变量、成员方法和构造方法等。
- 通过反射,我们可以获取一个类的 Class 对象,然后使用 Class 对象中提供的方法来获取类的成员变量、成员方法和构造方法等信息。例如,我们可以通过 Class 对象的getField 方法来获取类的公共成员变量,通过 getMethod 方法来获取类的公共成员方法,通过 getConstructor 方法来获取类的公共构造方法等。
- 通过获取类的成员变量、成员方法和构造方法等信息,我们可以在运行时动态地创建对象、调用方法、访问属性等操作。这使得我们能够更灵活地使用和扩展已有的类,实现一些动态的功能。
因此,Java 的反射机制与我们之前了解的 Java 运行体系没有太大区别。唯一的区别是在我们生成 .class 文件的同时,也会创建一个 Class 对象。Class 对象是所有类的类,而所有的类本身则是 Class 对象的实例。因此,反射机制并不复杂,它的核心就是获取一个类的 Class 对象,然后使用 Class 对象提供的方法来获取成员变量、成员方法和构造方法等信息,进而动态地获取一个类的属性、变量、构造方法等,并进行操作。简而言之,反射机制就是通过获取 Class 对象来实现动态获取和操作类的信息。
2、为什么要用到反射
能够在运行时获得程序或程序集中每一个类型的成员和成员的信息,从而动态的创建、修改、调用、获取其属性,而不需要事先知道运行的对象的具体细节。
划重点:在运行时而不是编译时。(不改变原有代码逻辑,运行的时候动态创建和编译即可)
这里补充一下 Java 的编译机制:
- 静态编译:在编译时确定好类型,绑定对象
- 动态编译:在运行时确定好类型,绑定对象
3、反射在安全的应用场景
- 造利用链,触发命令执行
- 反序列化中的利用链构造
- 动态获取或执行任意类中的属性或方法
- 动态代理的底层原理是反射技术
- rmi 反序列化也涉及到反射操作
0x02 利用反射获取 Class 对象类
首先创建一个 User 类,有成员变量、构造方法、成员方法,如下:
?
然后,获取 Class 对象,有以下这四种方法:
//1、根据类名:类名.class
Class userClass = User.class;
//2、根据对象:对象.getClass()
User user = new User();
Class aClass = user.getClass();
//3、根据全限定类名:Class.forName("全路径类名")
Class aClass1 = Class.forName("com.example.reflectdemo.User");
//4、通过类加载器获得Class对象://ClassLoader.getSystemClassLoader().loadClass("全路径类名");
ClassLoader clsload=ClassLoader.getSystemClassLoader();
Class aClass2 = clsload.loadClass("com.example.reflectdemo.User");
?
0x03 利用反射获取 Field 成员变量类
1、Class类中用于获取成员变量的方法
Field[] getFields(): 返回所有公共成员变量对象的数组(即所有public)
Field[] getDeclaredFields(): 返回所有成员变量对象的数组(即所有public、protected、private)
Field getField(String name): 返回单个公共成员变量对象(即单个public)
Field getDeclaredField(String name): 返回单个成员变量对象(即单个public、protected、private)
2、成员变量赋值和获取值方法
void set(Object obj, Object value): 赋值
Object get(Object obj): 获取值
?
0x04 利用反射获取 Method 成员方法类
1、Class类中用于获取成员方法的方法
Method[] getMethods(): 返回所有公共成员方法对象的数组,包括继承的
Method[] getDeclaredMethods(): 返回所有成员方法对象的数组,不包括继承的
Method getMethod(String name, Class<?>...parameterTypes): 返回单个公共成员方法对象
Method getDeclaredMethod(String name, Class<?>...parameterTypes): 返回单个成员方法对象
2、Method类中用于创建对象的方法
Object invoke(Object obj, Object...args): 运行方法
参数一:用obj对象调用该方法
参数二:调用方法的传递的参数(如果没有就不写)
返回值:方法的返回值(如果没有就不写)
?
0x05 利用反射获取 Constructor 构造方法类
1、Class类中用于获取构造方法的方法
Constructor<?>[] getConstructors(): 返回所有公共构造方法对象的数组
Constructor<?>[] getDeclaredConstructors(): 返回所有构造方法对象的数组
Constructor<T> getConstructor(Class<?>... parameterTypes): 返回单个公共构造方法对象
Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes): 返回单个构造方法对象
2、Constructor类中用于创建对象的方法
T newInstance(Object... initargs): 根据指定的构造方法创建对象
setAccessible(boolean flag): 设置为true,表示取消访问检查
?
0x06 Java-反射-不安全命令执行&反序列化链构造
1、举例-反射实现命令执行
-原型:
Runtime.getRuntime().exec("calc");
-反射:
//方法1:
Class aClass = Class.forName("java.lang.Runtime");
//获取所有公共包括继承的成员方法
Method[] methods = aClass.getMethods();
for (Method me:methods){
System.out.println(me);
}
//获取exec成员方法
Method exec = aClass.getMethod("exec", String.class);
//获取getRuntime成员方法
Method getRuntimeMethod = aClass.getMethod("getRuntime");
//执行
Object runtime = getRuntimeMethod.invoke(aClass);
exec.invoke(runtime, "calc.exe");
//方法2:
Class c1= Class.forName("java.lang.Runtime");
Constructor m = c1.getDeclaredConstructor();
m.setAccessible(true);
c1.getMethod("exec", String.class).invoke(m.newInstance(), "calc");
2、不安全的反射对象
指应用程序使用具有反射功能的外部输入来选择要使用的类或代码,可能被攻击者利用而输入或选择不正确的类,绕过身份验证或访问控制检查。
参考分析:悟空云课堂 | 第七期:不安全的反射漏洞 - 知乎 (zhihu.com)
利用结合:JAVA反序列化 - Commons-Collections组件 - 先知社区 (aliyun.com)
个人理解,Java反射和Java反序列漏洞息息相关,很多反序列化payload的构造(比如ysoserial里的)都是基于反射的。
比如项目里加载了某些jar包的类,可以利用反射来构造并调用这些类的方法,比如上面弹出计算器的例子。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!