安全开发 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 的执行是需要对象的

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

相关推荐
万琛4 分钟前
【Java-图片存储方案】
java·开发语言
Mr_sun.4 分钟前
Maven下载&配置
java·maven
工业互联网专业1 小时前
基于springboot+vue的城市公交查询系统
java·vue.js·spring boot·毕业设计·源码·课程设计
G3G41 小时前
Maven项目中没有.iml文件
java·maven·intellij-idea
落霞与孤鹭齐飞。。2 小时前
SSM宠物医院信息管理系统
java·开发语言·mysql·毕业设计·课程设计
上海拔俗网络3 小时前
“AI 大模型内容安全审核软件系统:守护网络世界的卫士
java·团队开发
m0_748251083 小时前
PHP For 循环
android·java·php
m0_748254473 小时前
记录一下在Win上搭建RustDesk
java
我要学编程(ಥ_ಥ)4 小时前
初始JavaEE篇 —— 快速上手 SpringBoot
java·spring boot·spring·java-ee