一,Java-反射
1,反射的寄义:
反射的意思就是,在代码运行的时候,还能动态的获得和修改成员变量,操纵成员方法和构造方法。而不是得将程序停掉,再来改源代码里面的东西。对成员变量,成员方法和构造方法的信息进行的编程操纵可以明白为反射机制。
2,反射的意义:
在运行时获得程序或程序集中每一个类型的成员和成员的信息,从而动态的创建、修改、调用、获取其属性,而不需要事先知道运行的对象是谁。划重点:在运行时而不是编译时。(不改变原有代码逻辑,自行运行的时候动态创建和编译即可)
3,安全应用场景:
(1)构造利用链,触发命令执行
(2)反序列化中的利用链构造
4,Java-反射-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();
- ClassLoader clsload=ClassLoader.getSystemClassLoader();
- Class aClass2=clsload.loadClass("com.example.reflectdemo.User")
复制代码 反射实验:创建一个User类,包含成员变量和成员方法,构造方法,便于获取反射所对应需要
User.java文件- package com.example;
-
- public class User {
- //成员变量
- public String name="xiaodi";
- public int age = 31;
- private String gender="man";
- protected String job="sec";
-
- //构造方法
- public User(){
- //System.out.println("无参数");
- }
-
- public User(String name){
- System.out.println("我的名字"+name);
- }
-
- private User(String name,int age){
- System.out.println(name);
- System.out.println(age);
- }
-
- //成员方法
- public void userinfo(String name,int age,String gender,String job){
- this.job=job;
- this.age=age;
- this.name = name;
- this.gender=gender;
- }
-
- protected void users(String name,String gender){
- this.name = name;
- this.gender=gender;
- System.out.println("users成员方法:"+name);
- System.out.println("users成员方法:"+gender);
- }
-
- }
复制代码 GetClass.java文件- package com.example;
-
- public class GetClass {
- public static void main(String[] args) throws ClassNotFoundException {
- //1、根据全限定类名:Class.forName("全路径类名")
- Class aClass = Class.forName("com.example.User");
- System.out.println(aClass);
-
- //2、根据类名:类名.class
- Class userClass = User.class;
- System.out.println(userClass);
-
- //3、根据对象:对象.getClass()
- User user= new User();
- Class aClass1 = user.getClass();
- System.out.println(aClass1);
-
- //4、通过类加载器获得Class对象://ClassLoader.getSystemClassLoader().loadClass("全路径类名");
- ClassLoader clsload=ClassLoader.getSystemClassLoader();
- Class aClass2 = clsload.loadClass("com.example.User");
- System.out.println(aClass2);
-
-
- }
- }
复制代码 5,Java-反射-Field成员变量类获取
- //Class aClass = Class.forName("com.example.reflectdemo.User");
- //获取公共成员变量对象
- // Field[] fields=aClass.getFields();
- // for(Field f:fields){
- // System.out.println(f);
- // }
- //获取所有成员变量对象
- // Field[] fields=aClass.getDeclaredFields();
- // for(Field f:fields){
- // System.out.println(f);
- // }
- //获取公共,私有单个成员变量对象
- // Field field=aClass.getField("age");
- // Field field=aClass.getDeclaredField("gender");
- // System.out.println(field);
- //城边变量值获取和赋值
- // User u = new User();
- // Field field=aClass.getField("age");
- // field.set(u,30);
- // Object a=field.get(u);
- // System.out.println(a);
复制代码 GetField.java- package com.example;
-
- import java.lang.reflect.Field;
-
- public class GetField {
- public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException {
- Class aClass = Class.forName("com.example.User");
-
- //获取公共的成员变量
- // Field[] fields = aClass.getFields();
- // for(Field fd:fields){
- // System.out.println(fd);
- // }
-
- //获取所有的成员变量
- // Field[] fields = aClass.getDeclaredFields();
- // for(Field fd:fields){
- // System.out.println(fd);
- // }
-
-
- //获取单个的公共成员变量
- Field name = aClass.getField("name");
- System.out.println(name);
-
- //获取单个的成员变量
- Field gender = aClass.getDeclaredField("gender");
- System.out.println(gender);
-
- //获取公共的成员变量age的值
- User u = new User();
- Field field=aClass.getField("age");
-
- //取值
- Object a=field.get(u);
- System.out.println(a);
-
- //赋值
- field.set(u,32);
- Object aa=field.get(u);
- System.out.println(aa);
-
- }
- }
复制代码 二,Java-反射-Constructor构造方法类获取
- //Class aClass = Class.forName("com.example.reflectdemo.User");
- //返回所有公共构造方法对象的数组
- // Constructor[] constructors = aClass.getConstructors();
- // for(Constructor con:constructors){
- // System.out.println(con);
- // }
- //返回所有构造方法对象的数组
- // Constructor[] constructors = aClass.getDeclaredConstructors();
- // for(Constructor con:constructors){
- // System.out.println(con);
- // }
- //返回单个公共构造方法对象
- // Constructor con1=aClass.getConstructor();
- // Constructor con1=aClass.getConstructor(String.class);
- // System.out.println(con1);
- //返回单个构造方法对象
- // Constructor con2=aClass.getDeclaredConstructor(int.class);
- //Constructor con2=aClass.getDeclaredConstructor(String.class,int.class, String.class);
- // System.out.println(con2);
- // Constructor con2=aClass.getDeclaredConstructor(int.class);
- // con2.setAccessible(true);
- // User uu=(User) con2.newInstance("xiaodi",30,"man");
- // System.out.println(uu);
复制代码 GetConstructor.java- package com.example;
-
- import java.lang.reflect.Constructor;
- import java.lang.reflect.InvocationTargetException;
-
- public class GetConstructor {
- public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
- Class aClass = Class.forName("com.example.User");
-
- //获取公共的构造方法
- // Constructor[] constructors = aClass.getConstructors();
- // for (Constructor con:constructors){
- // System.out.println(con);
- // }
-
- //获取所有的构造方法
- // Constructor[] constructors = aClass.getDeclaredConstructors();
- // for (Constructor con:constructors){
- // System.out.println(con);
- // }
-
- //获取单个的公共的构造方法
- // Constructor constructor = aClass.getConstructor(String.class);
- // System.out.println(constructor);
- //
- // //获取单个的构造方法
- // Constructor con1 = aClass.getDeclaredConstructor(String.class,int.class);
- // System.out.println(con1);
-
-
- //对构造方法进行操作(两个参数string,int)
- // Constructor con2=aClass.getDeclaredConstructor(String.class,int.class);
- // //临时开启对私有的访问
- // con2.setAccessible(true);
- // User uu=(User) con2.newInstance("xiaodigaygay",40);
- // System.out.println(uu);
-
- //对构造方法进行执行(1个参数strin)
- Constructor con2=aClass.getConstructor(String.class);
- con2.newInstance("xiaodigaygay");
-
- }
- }
复制代码 三,Java-反射-Method成员方法类获取
- //Class aClass = Class.forName("com.example.reflectdemo.User");
- //返回所有公共成员方法对象的数组,包括继承的
- // Method[] methods = aClass.getMethods();
- // for (Method me:methods){
- // System.out.println(me);
- // }
- //返回所有成员方法对象的数组,不包括继承的
- // Method[] methods = aClass.getDeclaredMethods();
- // for (Method me:methods){
- // System.out.println(me);
- // }
- //返回单个公共成员方法对象
- // Method methods = aClass.getMethod("getName");
- // System.out.println(methods);
- // Method methods = aClass.getMethod("setName", String.class);
- // System.out.println(methods);
- //返回单个成员方法对象
- // Method methods = aClass.getDeclaredMethod("UserInfo", String.class, int.class, String.class);
- // System.out.println(methods);
- //运行方法invoke
- // Method methods = aClass.getDeclaredMethod("UserInfo", String.class, int.class, String.class);
- // User u = new User();
- // //私有需要开启临时
- // methods.setAccessible(true);
- // methods.invoke(u,"xiaodi",18,"man");
复制代码 GetMethod.java- package com.example;
-
- import java.lang.reflect.Field;
- import java.lang.reflect.InvocationTargetException;
- import java.lang.reflect.Method;
-
- public class GetMethod {
- public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
- Class aClass = Class.forName("com.example.User");
- //获取包括继承的公共成员方法
- // Method[] methods = aClass.getMethods();
- // for(Method me:methods){
- // System.out.println(me);
- // }
-
- //获取不包括继承的所有成员方法
- // Method[] methods = aClass.getDeclaredMethods();
- // for(Method me:methods){
- // System.out.println(me);
- // }
-
- //获取单个的成员方法
- // Method users = aClass.getDeclaredMethod("users", String.class,String.class);
- // System.out.println(users);
-
-
- // 对成员方法进行执行
- // invoke() 方法用于调用指定对象的方法,并传递相应的参数。
- User u = new User();
- Method users = aClass.getDeclaredMethod("users", String.class,String.class);
- users.invoke(u,"xiaodigay","gay1");
-
-
- }
- }
复制代码 四,Java-反射-不安全命令执行&反序列化链构造
- 1 、反射实现 - 命令执行
- -原型:
- Runtime.getRuntime().exec("calc");
- -反射:
- Class aClass = Class.forName("java.lang.Runtime");
- Method[] methods = aClass.getMethods();
- for (Method me:methods){
- System.out.println(me);
- }
- Method exec = aClass.getMethod("exec", String.class);
- Method getRuntimeMethod = aClass.getMethod("getRuntime");
- Object runtime = getRuntimeMethod.invoke(aClass);
- exec.invoke(runtime, "calc.exe");
- Class c1= Class.forName("java.lang.Runtime");
- Constructor m = c1.getDeclaredConstructor();
- m.setAccessible(true);
- c1.getMethod("exec", String.class).invoke(m.newInstance(), "calc");
- 2、不安全的反射对象
- 指应用程序使用具有反射功能的外部输入来选择要使用的类或代码,
- 可能被攻击者利用而输入或选择不正确的类。绕过身份验证或访问控制检查
- 参考分析:https://zhuanlan.zhihu.com/p/165273855
- 利用结合:https://xz.aliyun.com/t/7031(反序列化利用链)
复制代码 GetRunExec.java- package com.example;
-
- import java.io.IOException;
- import java.lang.reflect.Constructor;
- import java.lang.reflect.InvocationTargetException;
- import java.lang.reflect.Method;
-
- public class GetRunExec {
- public static void main(String[] args) throws IOException, ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
- //原生调用 JDK自带的rt.jar
- // Runtime.getRuntime().exec("calc");
-
-
- //如果是第三方的jar包
- //通过 Class.forName("java.lang.Runtime") 方法获取了 java.lang.Runtime 类的 Class 对象,并将其赋值给 aClass。
- 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");
- }
- }
-
复制代码 文章参考https://blog.csdn.net/qq_61553520/article/details/136611937?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522baec5cd87d3bc16a3b87a813b077294a%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=baec5cd87d3bc16a3b87a813b077294a&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2blogfirst_rank_ecpm_v1~rank_v31_ecpm-1-136611937-null-null.nonecase&utm_term=34&spm=1018.2226.3001.4450
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |