安全开发 JavaEE && 反射机制 && 对象 成员变量 构造方法 成员方法 && 攻击链

前言

概念介绍

接口 : java接口就是协议 像我们的 usb接口 就是为了统一外部硬件的调用规格

api :简单说就是java应用程序的调用 不同的api绑定的是不同的应用程序

反射机制 : Java的反射机制 简单的来说就是 我们调用第三方的jar库或者jdk自带的类时我们可以调用其中的方法和修改一些变量属性 (简单说就是 调用)

编译机制 :

静态编译 : 在编译时确定好类型,绑定对象。

动态编译 : 在运行时确定类型,绑定对象。

反射的应用场景就是在 动态编译 我们调用其他的类的时候 不改变原有的逻辑 变量值 在运行的时候 进行新的属性的赋值修改 从而让调用符合我们的需求

安全场景 :

java反序列化

构造利用链触发 rce

动态的获取或者执行 任意类的属性和方法

反射获取成员变量

先创建项目

复制代码
创建一个 Admin 类
package com.example.reflectdemo;

public class Admin {
    //成员变量
    public String name="xiaodi";
    public  String password="xiaodisec";

    //不同修饰符
    private int age=18;

    //成员方法 Method  成员方法 : 就是你自己写的 方法(当然这个方法你是可以绑定api 然后发给别人 别人是直接可以调用你的这个应用程序的)
    // 有参数的
    //还有就是成员方法必须是有返回值的 我们使用 void 就是
    public void echoname(String name){
        this.name=name;
        System.out.println(name);
    }

    //无参数的
    public void shuchu(){
        System.out.println("输出");
    }

    //不同修饰符的
    private void siyou(){
        System.out.println("我是私有变量");
    }

//    构造方法  Constructor  : 他是指的是我们创建的名字是和我们的主类是相同的  所以这个和成员方法的区别就是名称
    public void Admin(String name,String password){
        this.name=name;
        this.password=password;
        System.out.println(name);
        System.out.println(password);
    }
    //不同修饰符号
    private void Admin(){
        System.out.println("私有的Constructor");
    }


}

然后创建一个

开始获取成员变量

获取之前呢 我们需要先获取 这个程序的类

反射获取类名

复制代码
        //根据路径获取
        Class class1=Class.forName("com.example.reflectdemo.User");
        System.out.println(class1);

上边这个的原理就是根据 forname 根据引用路径获取

复制代码
 //根据对象获取
        User  users=new User();
        Class class3=users.getClass();
        System.out.println(class3);

这个是根据新创建了一个对象然后根据对象 获取类 再输出

复制代码
        //根据名字获取
        Class aclasss=User.class;
        System.out.println(aclasss);
        //这个的原理就是根据类的名字直接获取 这个类

反射成员变量并赋值

先获取所有的成员变量 获取成员的变量用到了 Filed

复制代码
     //获取成员变量之前先获取他的  类
        User user1 = new User();
        Class class1 = user1.getClass();
        System.out.println(class1.getName());

        // 获取所有的  类
        Field[] fields = class1.getDeclaredFields();// []  表示以数组的形式进行存储
        for (Field field : fields) {
            System.out.println(field.getName());
        }

这个

复制代码
getDeclaredFields();   加Declaredfields();  就是表示 所以的变量不分修饰符   如果没有这个De 的话我们是无权获取的

// 获取单个的变量

复制代码
     //获取单个公共变量
        Field fd=class1.getField("name");
        System.out.println(fd.getName());

如果使用上边的代码获取 私有的变量时

加上

复制代码
Declared

就可以了

给与变量赋值 这个就是反射的应用 表示我们对变量进行第三方引用(api调用)的时候 会出现 我们给变量初始化上我们想要的值

获取构造方法

复制代码
        //获取类
        User u=new User();
        Class c=u.getClass();

        //获取全部的构造方法
        Constructor[] constructors=c.getDeclaredConstructors();
        System.out.println(constructors);

        for (Constructor cons:constructors) {//利用数组的遍历 使用
            System.out.println(cons);

发现特点就是 构造方法的名字虽然是一样的但是他传入的参数是不同的 这个是可以判断他的用法的

复制代码
        // 获取单个  公共属性的构造方法
        Constructor c1=c.getConstructor(String.class);
        System.out.println(c1);
复制代码
        // 获取单个全部属性的构造方法
        Constructor c1=c.getDeclaredConstructor(String.class,int.class);
        System.out.println(c1);

获取成员方法 和 成员方法的调用

先说一个 继承(代码的复用和精简)

继承就是指 一个大类中逐渐分化出特点功能的方法(这类方法的调用得 person.say 这样的形式进行调用)

成员方法也是有继承的

复制代码
        //获取继承的Method 类
        Method[] idea=aclass.getMethods();
        for (Method m:idea){
            System.out.println(m);
        }
复制代码
        //获取非继承的Method 类
        Method[] idea=aclass.getDeclaredMethods();
        for (Method m:idea){
            System.out.println(m);
        }

        //获取单个
        Method m=aclass.getMethod("userinfo", String.class, int.class, String.class, String.class);
        System.out.println(m);

//        //第三方   调用运行方法
        User u=new User();
        Method fangfa2=aclass.getMethod("userinfo", String.class, int.class, String.class, String.class);
        fangfa2.invoke(u,"xiaodigay",18,"xx","xx");

安全问题

指应用程序使用具有反射功能的外部输入来选择要使用的类或代码,

可能被攻击者利用而输入或选择不正确的类。绕过身份验证或访问控制检查

参考分析:https://zhuanlan.zhihu.com/p/165273855

利用结合:https://xz.aliyun.com/t/7031(反序列化利用链)

小案例 :

利用反射实现RCE(这个RCE的功能是 我们要调用的aip的一个子接口)

我们ctrl + 鼠标左键 直接追踪

getRuntime是一个 public类的一个成员方法

exec也是

但是上边这个get他的返回值是一个实例化对象 我们知道要想让方法被调用就得使用实例化的对象进行调用

这个的思路我们就想到获取 getRuntime的方法 然后我们直接把他当做对象 来实例化第三方调用这个api exec

思路有了开造

复制代码
        //第三方的调用
        //先获取类名
        Class aaa=Runtime.class;
//        System.out.println(aaa);
// 获取所以的方法接口
        Method[] methods=aaa.getMethods();
        for (Method method:methods) {
            System.out.println(method);
        }

获取这个干鸡毛啊 : 为了更方便的获取单个的方法

复制代码
        Class aaa=Runtime.class;
//        System.out.println(aaa);

        Method[] methods=aaa.getMethods();
        for (Method method:methods) {
            System.out.println(method);
        }
        Method m=aaa.getMethod("getRuntime");
        Method exec=aaa.getMethod("exec", String.class);
        Object o=m.invoke(aaa);
        exec.invoke(o,"calc");  //exec 表示方法  
        // invoke 的执行是需要对象的

直接执行 就可以弹计算机了

相关推荐
BillKu13 分钟前
Java + Spring Boot + Mybatis 插入数据后,获取自增 id 的方法
java·tomcat·mybatis
全栈凯哥14 分钟前
Java详解LeetCode 热题 100(26):LeetCode 142. 环形链表 II(Linked List Cycle II)详解
java·算法·leetcode·链表
chxii15 分钟前
12.7Swing控件6 JList
java
全栈凯哥16 分钟前
Java详解LeetCode 热题 100(27):LeetCode 21. 合并两个有序链表(Merge Two Sorted Lists)详解
java·算法·leetcode·链表
YuTaoShao17 分钟前
Java八股文——集合「List篇」
java·开发语言·list
PypYCCcccCc22 分钟前
支付系统架构图
java·网络·金融·系统架构
华科云商xiao徐43 分钟前
Java HttpClient实现简单网络爬虫
java·爬虫
扎瓦1 小时前
ThreadLocal 线程变量
java·后端
BillKu1 小时前
Java后端检查空条件查询
java·开发语言
jackson凌1 小时前
【Java学习笔记】String类(重点)
java·笔记·学习